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

一、问题描述

今天在做移动端项目的时候,遇到这么一个需求:手指滑动屏幕可以切换页面,即实现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);

最终的实现效果如下:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值