Prevent mobile browsers from pulling down the rubber band effect (drop-down scrolling to reveal the bottom)

foreword

There is a requirement for a recent project: the rubber band effect in the mobile browser is required, but the existence divbox 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: overflowthe 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: falseRegarding 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 :

  1. If a box ( div) needs to be slidable, then the default behavior ( touchmovethe 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
  2. 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 touchthe 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 isChildTargetas 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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324880534&siteId=291194637