一、问题描述
今天在做移动端项目的时候,遇到这么一个需求:手指滑动屏幕可以切换页面,即实现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);
最终的实现效果如下:
网友评论