document.addEventListener('touchstart', function (e) {
e.preventDefault();
});
Verwenden Sie nicht das ontouchmove
-Eigenschaft, um den Ereignishandler zu registrieren, da Sie das Risiko eingehen, einen vorhandenen Ereignishandler zu überschreiben. Verwenden Sie stattdessen addEventListener (siehe die Anmerkung zu IE auf der MDN-Seite).
Beachten Sie, dass das Verhindern des Standardverhaltens für das touchstart
-Ereignis auf dem window
oder document
das Scrollen der untergeordneten Bereiche deaktiviert.
Um das Scrollen des Dokuments zu verhindern, aber alle anderen Ereignisse intakt zu lassen, verhindern Sie das Standardverhalten für das erste touchmove
-Ereignis nach touchstart
:
var firstMove;
window.addEventListener('touchstart', function (e) {
firstMove = true;
});
window.addEventListener('touchmove', function (e) {
if (firstMove) {
e.preventDefault();
firstMove = false;
}
});
Der Grund, warum dies funktioniert, ist, dass Mobile Safari die erste Bewegung verwendet, um festzustellen, ob der Inhalt des Dokuments gescrollt wird. Dies ist mir aufgefallen, als ich eine ausgefeiltere Lösung entwickelt habe.
Falls dies irgendwann aufhören sollte zu funktionieren, ist die ausgefeiltere Lösung, das touchTarget
-Element und dessen Eltern zu inspizieren und eine Karte der Scrollrichtungen zu erstellen, die gescrollt werden können. Verwenden Sie dann das erste touchmove
-Ereignis, um die Scrollrichtung zu erkennen und festzustellen, ob es das Dokument oder das Ziellement scrollen wird (oder eines der Ziellement-Elternelemente):
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;
// eine boolesche Karte, die anzeigt, ob das Element (oder eines der Element-Elternelemente, ausgenommen document.body) in Richtung X gescrollt werden kann.
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
) {
// Sie scrollen entweder das Element oder eines seiner Elternelemente.
// Dies wird das Scrollen des document.body nicht beeinflussen.
} else {
// Dies wird das Scrollen des document.body beeinflussen.
e.preventDefault();
disableScroll = true;
}
});
Der Grund, warum dies funktioniert, ist, dass Mobile Safari die erste Berührungsbewegung verwendet, um festzustellen, ob das Dokument gescrollt wird oder das Element (oder eines der Ziellement-Elternelemente) und hält sich an diese Entscheidung.