document.addEventListener('touchstart', function (e) {
e.preventDefault();
});
不要使用ontouchmove 属性来注册事件处理程序,因为您有覆盖现有事件处理程序的风险。请改用addEventListener(请参阅MDN 页面上有关IE 的说明)。
请注意,阻止 window 或 document 上的 touchstart 事件的默认设置将禁用下降区域的滚动。
为了防止滚动文档但保持所有其他事件不变,防止touchstart 之后的第一个touchmove 事件默认:
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;
// a boolean map indicating if the element (or either of element parents, excluding the document.body) can be scrolled to the X direction.
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
) {
// You are scrolling either the element or its parent.
// This will not affect document.body scroll.
} else {
// This will affect document.body scroll.
e.preventDefault();
disableScroll = true;
}
});
这样做的原因是移动版 Safari 使用第一次触摸移动来确定是滚动文档正文还是滚动元素(或目标元素父元素)并坚持这一决定。