document.addEventListener('touchstart', function (e) {
e.preventDefault();
});
不要使用
ontouchmove
属性注册事件处理程序,因为存在覆盖现有事件处理程序的风险。请改用
addEventListener(请参阅MDN页面上关于IE的注意事项)。
请注意,防止在
window
或
document
上的
touchstart
事件的默认行为将禁用下层区域的滚动。
为了防止文档滚动但保留所有其他事件,请防止第一个
touchmove
事件跟随
touchstart
:
var firstMove;
window.addEventListener('touchstart', function (e) {
firstMove = true;
});
window.addEventListener('touchmove', function (e) {
if (firstMove) {
e.preventDefault();
firstMove = false;
}
});
这种方法有效的原因是移动版Safari使用第一次移动来确定是否正在滚动文档主体。在设计更复杂的解决方案时,我意识到了这一点。
如果这种方法以后不再有效,更复杂的解决方案是检查touchTarget
元素及其父元素,并创建一个可以滚动到的方向映射。然后使用第一个touchmove
事件来检测滚动方向,并查看它是要滚动文档还是目标元素(或目标元素的任何一个父元素):
var touchTarget,
touchScreenX,
touchScreenY,
conditionParentUntilTrue,
disableScroll,
scrollMap;
conditionParentUntilTrue = function (element, condition) {
var outcome;
if (element === document.body) {
return false;
}
outcome = condition(element);
if (outcome) {
return true;
} else {
return conditionParentUntilTrue(element.parentNode, condition);
}
};
window.addEventListener('touchstart', function (e) {
touchTarget = e.targetTouches[0].target;
scrollMap = {}
scrollMap.left = conditionParentUntilTrue(touchTarget, function (element) {
return element.scrollLeft > 0;
});
scrollMap.top = conditionParentUntilTrue(touchTarget, function (element) {
return element.scrollTop > 0;
});
scrollMap.right = conditionParentUntilTrue(touchTarget, function (element) {
return element.scrollWidth > element.clientWidth &&
element.scrollWidth - element.clientWidth > element.scrollLeft;
});
scrollMap.bottom =conditionParentUntilTrue(touchTarget, function (element) {
return element.scrollHeight > element.clientHeight &&
element.scrollHeight - element.clientHeight > element.scrollTop;
});
touchScreenX = e.targetTouches[0].screenX;
touchScreenY = e.targetTouches[0].screenY;
disableScroll = false;
});
window.addEventListener('touchmove', function (e) {
var moveScreenX,
moveScreenY;
if (disableScroll) {
e.preventDefault();
return;
}
moveScreenX = e.targetTouches[0].screenX;
moveScreenY = e.targetTouches[0].screenY;
if (
moveScreenX > touchScreenX && scrollMap.left ||
moveScreenY < touchScreenY && scrollMap.bottom ||
moveScreenX < touchScreenX && scrollMap.right ||
moveScreenY > touchScreenY && scrollMap.top
) {
} else {
e.preventDefault();
disableScroll = true;
}
});
这个方法有效的原因是移动Safari使用第一个触摸移动事件来确定文档主体是否正在滚动,或者元素(或目标元素的任一父级)是否正在滚动,并坚持此决定。
document.ontouchmove = function(e){ e.preventDefault(); }
- Andrew Samuelsen