foreword
There is a requirement for a recent project: the rubber band effect in the mobile browser is required, but the existence div
box inside the page needs to have scrolling. As a result, the problems encountered and the solution process are recorded as follows.
Disclaimer: Only the js control part and the css settings are discussed here (for example: overflow
the settings, etc.)
The first step to stop the rubber band effect
Simple and rude solution to prevent the default behavior of browser sliding
document.body.addEventListener('touchmove', (e) => {
e.preventDefault();
});
It needs to be explained here that this writing method cannot achieve the expected effect under IOS11.3, and the following code is required
document.body.addEventListener('touchmove', (e) => {
e.preventDefault();
}, { passive: false });
passive: false
Regarding the event listener of the reference article passive , about the explanation under IOS11.3, the reference article ios11.3 rubber band effect
So far, the rubber band effect that blocks mobile browsers has been solved
Guarantee the scrolling effect of the inner box
Disclaimer: The main discussion here is vertical sliding
Discussion :
- If a box (
div
) needs to be slidable, then the default behavior (touchmove
the scrolling behavior) of the box and its descendant elements cannot be prevented, so we need to identify the box element and its descendant elements, and do not perform operations that prevent its default behavior - When the scroll element reaches the top and continues to slide up, it also needs to prevent its default event. When scrolling to the bottom, continuing to scroll down may prevent its default behavior.
In summary, first determine whether touch
the event triggering element is a scrolling element and its descendant elements, if so, block the default event, if not, determine whether it is the top and slide up or the bottom and slide down. code above
let startY = 0;
const scrollBox = document.querySelector('.scroll-box');
document.body.addEventListener('touchstart', (e) => {
startY = e.touches[0].pageY;
}, { passive: false });
document.body.addEventListener('touchmove', (e) => {
const moveY = e.touches[0].pageY;
const top = scrollBox.scrollTop;
const ch = scrollBox.clientHeight;
const sh = scrollBox.scrollHeight;
if (!isChildTarget(e.target, scrollBox)) {
e.preventDefault();
} else if ((top === 0 && moveY > startY) || (top + ch === sh && moveY < startY)) {
e.preventDefault();
}
}, { passive: false });
This is almost the end, for the function isChildTarget
as follows :
function isChildOf(child, parent, justChild = flase) {
// justChild为true则只判断是否为子元素,若为false则判断是否为本身或者子元素 默认为false
let parentNode;
if (justChild) {
parentNode = child.parentNode;
} else {
parentNode = child;
}
if (child && parent) {
while (parentNode) {
if (parent === parentNode) {
return true;
}
parentNode = parentNode.parentNode;
}
}
return false;
}
It's really over.
If you have any questions, welcome to exchange and learn.
If you need to reprint, please indicate the source of this article address