官網:https://better-scroll.github.io/docs/zh-CN/
與better-scroll有關的文檔:https://juejin.im/post/5e40f72df265da5732551bdf#heading-5
1、在項目中發現個問題,用better-scroll實現的輪播圖和頁面滾動條倆個效果一起出現的時候,當鼠標或手指放在輪播圖位置的時候,上下滾動的時候,頁面滾動條不動
發現最新的版本就會出這個問題,就是官網的例子中也一樣,還有cube-ui中的輪播圖
https://ustbhuangyi.github.io/better-scroll/#/examples/slide/en
解決辦法是:
第一種:輪播圖用其他的,不要用better-sacroll,比如可以使用vant里面的輪播圖效果https://youzan.github.io/vant/#/zh-CN/swipe。頁面滾動效果用better-sacroll的
這有個問題:如果我們的輪播圖可以點擊跳轉,那么在滑動的時候,會觸發跳轉效果。這時我們就需要做處理,比如給跳轉加一個時間判斷(感覺這樣挺麻煩的)
第二種:不要用新版本的better-scroll,可以使用0.4.0版本的
第三種: 也是現階段我認為最好的
在於scrollX平級的地方,不要stopPropagation這個屬性,如果還不行,就加一個eventPassthrough: 'vertical'
示例代碼:
<template> <div class="slider" ref="slide"> <div class="slider-group" ref="slideGroup"> <slot> </slot> </div> <div v-if="showDot" class="dots" :class="{dots_center : (dots_position === 0),dots_left : (dots_position === 1),dots_right : (dots_position === 2)}"> <span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots" :key="index"></span> </div> </div> </template> <script type="text/ecmascript-6"> import {addClass} from 'common/js/dom.js' import BScroll from 'better-scroll' import {mapMutations} from 'vuex' export default { name: 'slider', props: { autoPlay: { // 是否開啟自動滾動 type: Boolean, default: true }, loop: { // 是否開啟循環滾動 type: Boolean, default: true }, interval: { // 滾動間隔時間 type: Number, default: 4000 }, showDot: { type: Boolean, default: true }, click: { type: Boolean, default: true }, threshold: { type: Number, default: 0.3 }, speed: { type: Number, default: 400 }, dots_position: { // 焦點的位置 0 中間 1 左邊 2 右邊 type: Number, default: 0 }, showItemIndex: { type: Number, defalut: 0 } }, data() { return { dots: [], currentPageIndex: 0 } }, mounted() { this.update() window.addEventListener('resize', () => { if (!this.slide || !this.slide.enabled) { return } clearTimeout(this.resizeTimer) this.resizeTimer = setTimeout(() => { if (this.slide.isInTransition) { this._onScrollEnd() } else { if (this.autoPlay) { this._play() } } this.refresh() }, 60) }) }, activated() { if (!this.slide) { return } this.slide.enable() let pageIndex = this.slide.getCurrentPage().pageX this.slide.goToPage(pageIndex, 0, 0) this.currentPageIndex = pageIndex if (this.autoPlay) { this._play() } }, deactivated() { this.slide.disable() clearTimeout(this.timer) }, beforeDestroy() { this.slide.disable() clearTimeout(this.timer) }, methods: { update() { if (this.slide) { this.slide.destroy() } this.$nextTick(() => { this.init() }) }, refresh() { this._setSlideWidth(true) this.slide.refresh() }, prev() { this.slide.prev() }, next() { this.slide.next() }, init() { clearTimeout(this.timer) this.currentPageIndex = 0 this._setSlideWidth() if (this.showDot) { this._initDots() } this._initSlide() if (this.autoPlay) { this._play() } }, _setSlideWidth(isResize) { this.children = this.$refs.slideGroup.children let width = 0 let slideWidth = this.$refs.slide.clientWidth for (let i = 0; i < this.children.length; i++) { let child = this.children[i] addClass(child, 'slider-item') child.style.width = slideWidth + 'px' width += slideWidth } if (this.loop && !isResize) { width += 2 * slideWidth } this.$refs.slideGroup.style.width = width + 'px' }, _initSlide() { this.slide = new BScroll(this.$refs.slide, { scrollX: true, scrollY: false, eventPassthrough: 'vertical', momentum: false, snap: { loop: this.loop, threshold: this.threshold, speed: this.speed }, bounce: false, click: this.click, freeScroll: true }) this.slide.on('scrollEnd', this._onScrollEnd) this.slide.on('touchEnd', () => { if (this.autoPlay) { this._play() } }) this.slide.on('beforeScrollStart', () => { if (this.autoPlay) { clearTimeout(this.timer) } }) }, _onScrollEnd() { let pageIndex = this.slide.getCurrentPage().pageX this.currentPageIndex = pageIndex if (this.autoPlay) { this._play() } else { // 觸發回調,將當前index值作為參數返回到store中 this.saveSIndex(this.currentPageIndex + 1) } }, ...mapMutations({ saveSIndex: 'SET_SLIDERINDEX' }), _initDots() { this.dots = new Array(this.children.length) }, _play() { clearTimeout(this.timer) this.timer = setTimeout(() => { this.slide.next() }, this.interval) } }, watch: { loop() { this.update() }, autoPlay() { this.update() }, speed() { this.update() }, threshold() { this.update() }, showItemIndex (index) { this.slide.goToPage(index, 0, 0) } } } </script> <style lang="less" rel="stylesheet/less" type="text/less"> @import "../../common/less/variable"; .slider{ min-height: 1px; } .slider-group{ position: relative; overflow: hidden; white-space: nowrap; } .slider-item{ float: left; box-sizing: border-box; overflow: hidden; text-align: center; } .slider-item a{ display: block; width: 100%; overflow: hidden; text-decoration: none; } .slider-item img{ display: block; width: 100%; } .dots{ position: absolute; bottom: 30px; transform: translateZ(1px); font-size: 0; } .dots_center{ left: 0; right: 0; } .dots_left{ left: 30px; } .dots_right{ right: 30px; } .dot{ display: inline-block; margin: 0 8px; width: 10px; height: 10px; border: 2px solid #f8fafc; border-radius: 50%; background: rgba(255, 255, 255, 0.5); } .dot.active{ background: #398ed1; } </style>
