better-scroll项目中遇到的问题

官网: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>

 

posted @ 2018-12-28 21:34  zhaobao1830  阅读(1801)  评论(0编辑  收藏  举报