美文网首页JavaScript 进阶营前端开发笔记
JavaScript库——swiper.js的内部区域滑动问题

JavaScript库——swiper.js的内部区域滑动问题

作者: 振礼硕晨 | 来源:发表于2018-10-08 22:54 被阅读2次

    一、问题描述

    今天在做移动端项目的时候,遇到这么一个需求:手指滑动屏幕可以切换页面,即实现swiper-slide之间的切换。如下图所示:

    这个需求是很简单的,但是在这个需求之上还要实现:使用手指滑动第二页中的图片的时候,图片上下滑动,swiper不能切换页面。即最终要做到如下效果:

    二、解决问题

    使用swiper来是现在这个需求,肯定是需要使用swiper的嵌套,即在外层的父swiper中嵌套一个子swiper,将图片放在子swiper中。这样,我们就可以实现手指滑动子swiper中的图片,同时父swiper不进行切换页面。

    但是如果你按照swiper的标准做法来嵌套swiper的话,是不能实现这个需求的。当你正确的完成swiper嵌套,去滑动子swiper中的图片的时候,你会看到下图的情况:

    这个情况是swiper的一个小bug,直到现在swiper官方也没有给出合理的解决办法。但是高手在民间,一些大神给出了解决这个问题的代码。

    如果你已经实现了swiper的嵌套,那么你肯定已经在js代码中初始化了两个swiper,比如这是我初始化两个swiper的js代码:

    // 定义父swiper
    var parent_swiper = new Swiper('.parent-swiper', {
        direction: 'vertical',
    });
    
    // 定义子swiper
    var child_swiper = new Swiper('.child-swiper', {
        direction: 'vertical',
    });
    

    想要实现这个需求,首先在自己的CSS中加上以下代码:

    .swiper-slide {
        overflow: auto;
        -webkit-overflow-scrolling: touch;
    }
    

    然后在js脚本中加上以下代码,用来设置子swiper。需要注意的是,我这里的给子swiper命名为child_swiper,所以代码中是child_swiper.slides.on,如果你的swiper是其他命名,对应的修改一下即可。

    var startScroll, touchStart, touchCurrent;
    
    child_swiper.slides.on('touchstart', function (e) {
        startScroll = this.scrollTop;
        touchStart = e.targetTouches[0].pageY;
    }, true);
    
    child_swiper.slides.on('touchmove', function (e) {
        touchCurrent = e.targetTouches[0].pageY;
        var touchesDiff = touchCurrent - touchStart;
        var slide = this;
        var onlyScrolling =
            ( slide.scrollHeight > slide.offsetHeight ) && //allow only when slide is scrollable
            (
                ( touchesDiff < 0 && startScroll === 0 ) || //start from top edge to scroll bottom
                ( touchesDiff > 0 && startScroll === ( slide.scrollHeight - slide.offsetHeight ) ) || //start from bottom edge to scroll top
                ( startScroll > 0 && startScroll < ( slide.scrollHeight - slide.offsetHeight ) ) //start from the middle
            );
        if (onlyScrolling) {
            e.stopPropagation();
        }
    }, true);
    

    这样我们就完美的解决了问题,实现了需求,如果你要实现水平方向的内部区域滑动,将上方的js代码换成下面的即可:

    var startScroll, touchStart, touchCurrent;
    
    child_swiper.slides.on('touchstart', function (e) {
        startScroll = this.scrollLeft;
        touchStart = e.targetTouches[0].pageX;
    }, true);
    
    child_swiper.slides.on('touchmove', function (e) {
        touchCurrent = e.targetTouches[0].pageX;
        var touchesDiff = touchCurrent - touchStart;
        var slide = this;
        var onlyScrolling =
            ( slide.scrollWidth > slide.offsetWidth ) && //allow only when slide is scrollable
            (
                ( touchesDiff < 0 && startScroll === 0 ) || //start from left edge to scroll right
                ( touchesDiff > 0 && startScroll === ( slide.scrollWidth - slide.offsetWidth ) ) || //start from right edge to scroll left
                ( startScroll > 0 && startScroll < ( slide.scrollWidth - slide.offsetWidth ) ) //start from the middle
            );
        if (onlyScrolling) {
            e.stopPropagation();
        }
    }, true);
    

    最终的实现效果如下:

    相关文章

      网友评论

        本文标题:JavaScript库——swiper.js的内部区域滑动问题

        本文链接:https://www.haomeiwen.com/subject/uussaftx.html