npm install better-scroll --save
<template> <div class="box"> <div class="person-wrap" ref="personWrap"> <ul class="person-list" ref="li1"> <li class="person-item" :class="{'current':currentIndex===index}" v-for="(item,index) in 7" :key="index" @click="select(index,$event)" >第{{item}}塊</li> </ul> </div> <div class="wrapper" ref="wrapper"> <div class="content" ref="li2"> <div v-for="(item,index) in 7" :key="index">第{{item}}塊</div> </div> </div> </div> </template>
<style scoped lang="scss"> * { margin: 0; padding: 0; box-sizing: border-box; } .box { width: 100%; height: 100%; } .person-wrap { overflow: hidden; height: 38px; .person-list { list-style-type: none; .person-item { float: left; line-height: 36px; margin: 0 16px; white-space: nowrap; } .current { color: #004299; border-bottom: 2px solid #004299; } } } .wrapper { height: 600px; background: pink; overflow: hidden; .content { display: block; div { height: 200px; border-bottom: 1px solid red; text-align: center; line-height: 200px; &:last-of-type { height: 600px; } } } } </style>
<script> import BScroll from "better-scroll"; export default { name: "better_scroll", data() { return { currentIndex: 0, //當前顯示的下標 listHeight: [], scrollY: 0, menuIndexChange: true }; }, created() { this.$nextTick(() => { this._initScroll(); this.personScroll(); this.height(); }); }, mounted() {}, methods: { // 橫軸初始化 personScroll() { // 動態設置寬度 let width = this.width(); this.$refs.li1.style.width = width + "px"; this.$nextTick(() => { if (!this.scroll) { this.scroll = new BScroll(this.$refs.personWrap, { startX: 0, click: true, scrollX: true, scrollY: false, eventPassthrough: "vertical", bounce: false }); } else { this.scroll.refresh(); } }); }, //新建滾動實例 並監聽豎軸滾動的高度 _initScroll() { this.wrapperScroll = new BScroll(this.$refs.wrapper, { click: true, //better-scroll 默認會阻止瀏覽器的原生 click 事件。當設置為 true,better-scroll 會派發一個 click 事件,我們會給派發的 event 參數加一個私有屬性 _constructed,值為 true。 probeType: 3, //這個屬性設置之后可以監聽得到了 bounce: false }); //監聽滾動事件 this.wrapperScroll.on("scroll", pos => { // 當允許滾動並滾動的y軸小於0 if (this.menuIndexChange && pos.y <= 0) { this.scrollY = Math.abs(Math.round(pos.y)); //滾動距離 // console.log(this.scrollY); // 循環每一個模塊距離頂部的高度 for (let i = 0; i < this.listHeight.length; i++) { let height1 = this.listHeight[i]; let height2 = this.listHeight[i + 1]; if ( !height2 || (this.scrollY >= height1 && this.scrollY < height2) ) { // console.log(i); this._followScroll(i); //橫軸動畫移動 this.currentIndex = i; return; } } } }); }, //獲取橫軸寬度 width() { let wrap1 = this.$refs.li1.children; let sum = 0; for (var i = 0; i < wrap1.length; i++) { sum += wrap1[i].offsetWidth; } return sum + wrap1.length * 16 * 2; }, //獲取豎軸每個模塊的高度 height() { let wrap2 = this.$refs.li2.children; let height = 0; this.listHeight.push(height); for (let i = 0; i < wrap2.length; i++) { let item = wrap2[i]; height += item.clientHeight; this.listHeight.push(height); } }, // 點擊橫軸滾動 select(index, event) { // PC頁面時,點擊不會被 better-scroll阻止事件,初始化,給 better-scroll派發事件,使移動端擁有點擊事件,因此切換到PC端時,點擊事件會被執行兩次, if (!event._constructed) { return; } this.currentIndex = index; //改變點擊的當前樣式 this.menuIndexChange = false; //禁用豎軸滾動 防止橫豎軸都改變index 解決運動時listenScroll依然監聽的bug //橫縱向右偏移16 this._followScroll(index); //橫軸動畫移動 //豎軸滾到響應位置 let wrap2 = this.$refs.li2.children; let el = wrap2[index]; this.wrapperScroll.scrollToElement(el, 300); //豎軸滾動結束后在允許動畫 this.wrapperScroll.on("scrollEnd", () => { this.menuIndexChange = true; }); }, // 橫軸滾動到當前元素並向右移動16px _followScroll(index) { let wrap1 = this.$refs.li1.children; let el = wrap1[index]; if (index < wrap1.length / 2) { this.scroll.scrollToElement(el, 300, -16, 0); } } } }; </script>