Closed fubai closed 6 years ago
这个问题不是vux的bug,也不是vux scroller组件所依赖的xscroll的bug,这是iOS的bug。
把issue发在这里,是因为我是在使用vux的scroller组件时碰到的这个iOS bug,而且解决方式也是vux(vue)的方式。
解决方法如下:
1.在main.js
中,通过store
维护当前正在pulldown
的scroller
let store = new Vuex.Store({
state: {
scrollerEl: null // 正在下拉的scroller pulldown的el元素
},
mutations: {
scrollerEl (state, v) {
state.scrollerEl = v;
}
}
});
2.在main.js
中,监听touchmove
事件,
if (!!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {//iOS
function triggerTouchend(e) {
if (!e || !store.state.scrollerEl) {
return;
}
// 手动分发一个touchend事件
store.state.scrollerEl.dispatchEvent(new TouchEvent('touchend', {
touches: e.touches,
targetTouches: e.targetTouches,
changedTouches: e.changedTouches,
ctrlKey: e.ctrlKey,
shiftKey: e.shiftKey,
altKey: e.altKey,
metaKey: e.metaKey,
detail: e.detail,
view: e.view,
sourceCapabilities: e.sourceCapabilities,
bubbles: e.bubbles,
cancelable: e.cancelable,
composed: e.composed
}));
}
let started = false,
timeoutId,
diffX = 39;//tabbar的高度
document.addEventListener('touchstart', function(e) { started = true; }, false);
document.addEventListener('touchend', function(e) { started = false; }, false);
document.addEventListener('touchcancel', function(e) { started = false; }, false);
document.addEventListener('touchmove', function(e) {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
if (e.changedTouches[0].pageY >= (document.body.clientHeight + diffX)) {//这种情况是,用户下拉滑动,滑过了webview和tabbar,滑倒了物理屏幕之外
e.preventDefault();
e.stopPropagation();// 结束事件的传播,保证scroller不再处理
triggerTouchend(e);
} else if (e.changedTouches[0].pageY >= document.body.clientHeight) {//这种情况是,用户下拉滑动,停留在了tabbar之上
if (started) {//在tabbar上停止不动,超过40ms则手动结束滑动
timeoutId = setTimeout(function() {
triggerTouchend(e);
}, 40);
} else {//在tabbar上停止不动,超过40ms被手动结束滑动后,又继续滑动
e.preventDefault();
e.stopPropagation();// 结束事件的传播,保证scroller不再处理
}
}
}, {
capture: true, // 在捕获阶段处理事件,保证在scroller之前处理事件
passive: false // 保证e.preventDefault()生效
});
}
pulldown
的状态。保证当前正在pulldown
的scroller,存储在store
中,反之,保证store
中没有当前scroller
data () {
return {
status: {
pulldownStatus: 'default'
}
};
},
watch: {
'status.pulldownStatus' (to, from) {
this.$store.commit('scrollerEl', to === 'default' ? null : this.$refs.scroller._xscroll.renderTo);
}
}
另外,scroller代码大致如下:
<scroller v-model="status" lock-x :scrollbar-x=false :scrollbar-y=false height="100%" style="width:100%;" ref="scroller" :use-pulldown="true" @on-pulldown-loading="onPullDown" :pulldown-config="{height:60,autoRefresh:false,downContent:'↓ 下拉刷新',upContent:'↑ 松开立即刷新',loadingContent:'加载中...'}">
我知道这个issue提在这里不合适,还请原谅,只希望给遇到相同bug的童鞋一个帮助。
thx,现在已经不建议使用Scroller组建了,可以使用第三方组件替代,例如better-scroll