我是靠谱客的博主 感动大碗,最近开发中收集的这篇文章主要介绍html手机蒙层穿透,通过 JavaScript 脚本解决移动端弹出层滚动穿透的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前端开发中经常会遇到一个麻烦的问题:在通过fixed或者absolute定位的弹出层上进行滚动操作的时候,滚动事件会穿透到底部导致body跟着滚动,及其影响交互体验。常规做法是在弹出层时候禁止body的滚动,将其设置为overflow: hidden,但是会导致滚动高度丢失从而造成视觉上一次弹动,所以我决定从弹出层本身考虑这个问题。

Body content.

const canScrollEl = ($el, up) => {

const overflow = up

? Math.abs($el.scrollTop) > Number.EPSILON

: $el.scrollHeight - $el.scrollTop - $el.clientHeight > Number.EPSILON;

if (!overflow) {

return false;

}

const styles = getComputedStyle($el);

if (styles['overflow-y'] !== 'auto' && styles['overflow-y'] !== 'scroll') {

return false;

}

return true;

};

const canScrollEls = ($child, $root, up) => {

let $el = $child;

while ($el) {

if (canScrollEl($el, up)) {

return true;

}

if ($el === $root) {

break;

}

$el = $el.parentNode;

}

return false;

};

const preventEvent = (e) => {

e.preventDefault();

e.stopPropagation();

e.returnValue = false;

return false;

};

const eventData = {

touchesPos: {},

moving: false,

canScroll: false,

};

const el = document.getElementById('popup');

el.addEventListener('mousewheel', (e) => {

if (canScrollEls(e.target, el, e.wheelDelta > 0)) {

return void 0;

}

return preventEvent(e);

}, { capture: true, passive: false, once: false });

el.addEventListener('touchstart', (e) => {

// record touch start pos

Object.keys(e.changedTouches).forEach((i) => {

const touch = e.changedTouches[i];

eventData.touchesPos[touch.identifier] = {

startY: touch.clientY,

currentY: touch.clientY,

};

});

eventData.moving = false;

eventData.canScroll = false;

}, { capture: true, passive: false, once: false });

el.addEventListener('touchmove', (e) => {

// update current touch pos and calc touches sum delta distance

let touchDeltaY = 0;

Object.keys(e.changedTouches).forEach((i) => {

const touch = e.changedTouches[i];

const cache = eventData.touchesPos[touch.identifier];

if (cache) {

touchDeltaY += touch.clientY - cache.currentY;

cache.currentY = touch.clientY;

}

});

const canScroll = canScrollEls(e.target, el, touchDeltaY > 0);

if (!eventData.moving) { // if first move cannot scroll this layer, all move after will not scroll this layer

eventData.moving = true;

eventData.canScroll = canScroll;

}

if (canScroll && eventData.canScroll) {

return void 0;

}

return preventEvent(e);

}, { capture: true, passive: false, once: false });

el.addEventListener('touchend', (e) => {

if (e && e.touches && e.touches.length !== 0) {

return;

}

eventData.touchesPos = {};

}, { capture: true, passive: false, once: false });

如果直接禁止touchmove事件,那么子元素有滚动区域时将也无法滚动,所以我们用上面一段代码来判断,动态判断是否要禁止事件。

最后

以上就是感动大碗为你收集整理的html手机蒙层穿透,通过 JavaScript 脚本解决移动端弹出层滚动穿透的问题的全部内容,希望文章能够帮你解决html手机蒙层穿透,通过 JavaScript 脚本解决移动端弹出层滚动穿透的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部