Vue中使用swiper的过程中,使用的是swiper卡片化轮播,由于要做成网站 所以项目在浏览器中使用 使用过程中鼠标可以对卡片化轮播进行滑动切换,但是使用触摸屏的话却不能对卡片化轮播进行滑动切换,左右滑动的时候会导致路由变化,请问各位有什么方式可以解决嘛(需要触摸屏滑动切换不能禁用掉触摸滑动切换)
你好,可以通过swiper的参数touchMoveStopPropagation
来解决该问题。该参数默认值为false,即当触摸跟随滑动时也会触发touchmove事件,会影响到浏览器的默认行为(即滚动页面),从而导致路由变化等问题。将该参数设置为true时,可以阻止这种行为,从而实现触摸屏下的卡片化轮播。
具体实现方式为,在swiper的初始化参数中添加touchMoveStopPropagation: true
参数即可,例如:
new Swiper('.swiper-container', {
touchMoveStopPropagation: true,
...
});
另外,还可以通过preventDefault
的方式禁止浏览器的默认行为,避免路由变化等问题,例如:
document.querySelector('.swiper-container').addEventListener('touchmove', function (e) {
e.preventDefault();
});
希望能够帮助你解决问题。创作不易,如果有用记得给个采纳哈 <<<<<<<<<<撒花>>>>>>>>
// 使用指令安装
npm i swiper@3.4.2 -S
根据参考资料中的代码以及描述,可以得出以下解决方案:
var swiper = new Swiper('.swiper-container', {
on: {
slideChangeTransitionEnd: function(){
Vue.$router.replace({path: '/xxx/' + this.activeIndex});
}
}
})
var swiperContainer = document.querySelector('.swiper-container');
var startTouchY;
var endTouchY;
swiperContainer.addEventListener('touchstart', function(evt) {
// 记录当前触摸位置的Y坐标
startTouchY = evt.touches[0].pageY;
// 当前滚动容器的scrollTop值
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// 该元素的scrollTop值
var elementScrollTop = this.scrollTop;
// 判断是否允许滚动冒泡的条件
// 1. 容器有滚动条
// 2. 触摸坐标在容器顶部,且往上滑动
// 3. 触摸坐标在容器底部,且往下滑动
var allowScrollBubble =
elementScrollTop === 0 && scrollTop < 5 ||
elementScrollTop + this.offsetHeight >= this.scrollHeight && scrollTop > startTouchY;
if (!allowScrollBubble) {
evt.stopPropagation();
}
});
swiperContainer.addEventListener('touchmove', function(evt) {
// 判断是否允许滚动冒泡的条件
// 1. 允许Y轴滑动
// 2. 容器有滚动条
var allowScrollBubble =
Math.abs(evt.touches[0].screenY - startTouchY) > Math.abs(evt.touches[0].screenX - startX) &&
this.offsetHeight < this.scrollHeight;
if (!allowScrollBubble) {
evt.stopPropagation();
evt.preventDefault();
}
// 记录滑动结束位置的Y坐标
endTouchY = evt.touches[0].pageY;
});
上面的代码会判断当前的触摸事件是否在Swiper容器的顶部或底部区域产生,只有这两个区域在滚动或往上下滑动时才会进行冒泡。要注意的是,在处理touchmove事件时,需要调用preventDefault方法以防止默认的滑动行为。
swiperContainer.addEventListener('touchstart', function(evt) {
var node = evt.target;
while (node !== swiperContainer) {
if (node.classList.contains('swiper-slide')) {
isAllowScroll = true;
break;
}
node = node.parentNode;
}
});
swiperContainer.addEventListener('touchmove', function(evt) {
// 判断是否允许滚动冒泡的条件
var allowScrollBubble =
Math.abs(evt.touches[0].screenY - startTouchY) > Math.abs(evt.touches[0].screenX - startX) &&
this.offsetHeight < this.scrollHeight &&
isAllowScroll;
if (!allowScrollBubble) {
evt.stopPropagation();
evt.preventDefault();
}
// 记录滑动结束位置的Y坐标
endTouchY = evt.touches[0].pageY;
});
swiperContainer.addEventListener('touchstart', function(evt) {
Vue.$emit('swiper:start', {});
});
然后在Vue组件中,可以在created方法中监听该事件:
export default {
props: {
index: Number
},
created() {
Vue.$on('swiper:start', () => {
this.$nextTick(() => {
this.$refs.innerSwiper.swiper.slideTo(this.index, 0);
});
});
}
};
这里我们在子组件内监听swiper:start事件,并利用refs属性获取到内部的Swiper实例,然后通过该实例的slideTo方法来跳转到指定的slide。
应该注意的是,这种方式在Swiper组件处于隐藏状态时是不起作用的,因为所有子组件在父元素隐藏时都是不会挂载的。