摘要:场景当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动然而事实并非如此。当属性的值为的时候,代表该监听器内部不会调用函数来阻止默认滑动行为,浏览器称这类型的监听器为被动监听器。
场景
当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。
如图所示,浮层下边的内容并没有如想象中不受影响。
先去github上搜索一番,发现有解决此问题的开源包,简单粗暴直接挑选了其中star的最高的(body-scroll-lock)操作一番!
使用后发现有一些问题:
安卓端全挂
ios端偶尔会有锁不住的情况
查源码发现该包在iOS端使用禁止touchmove的方式多带带处理,但是在其他端只是给body加overflow: hidden简单处理。
于是决定写一个针对多端通用的包来处理类似的问题。
看到下边的滚动肯定立刻就想到了是整个viewport的滚动,那么如果给body设置overflow: hidden,此时body的内容就只有一屏了,肯定不会滚动了;
body { overflow: hidden; }
此方案在pc端完美解决了我们的问题,然而事情并没有那么简单;
再试试移动端:
移动端中并没有出现期待的效果。。。
既然pc端已经有了完美的方案,下边我们继续探索移动端的解决方案。
上边想到给body设置overflow: hidden在移动端并不能解决我们的问题,是否在于body的height没有设置
将html、body的高度都设置为100%;
给body设置绝对定位(fixed);
同时使用这两个操作似乎完美满足了我们的需求;
但是如图所示,每次都会将页面拉到最顶上的位置,这样看起来又不完美了;
既然使用了定位,那么给一个top值不就定位到我们想要的位置了(聪明如我)。
tips: body 设置 relative 定位会页面自身拉上去,下边留白
多次实验发现这个方案在android端中完美达到了我们想要的结果,但是在ios端并不理想;每次定位的时候会有闪动的问题;好事多磨,接着探索ios端的方案。
探索三:禁止touchmove如果禁止掉页面的touchmove是否可行呢?话不多说就是干!
当弹出浮层的时候禁掉页面元素的touchmove
document.addEventListener("touchmove", function (event) { event.preventDefault() })
测试发现没有达到想象中的效果,感觉这个结果并不能接受啊,禁止document 的touchmove都不能禁止滚动的吗?
进一步的探索后发现原因竟是这个属性
passive addEventListener第三个参数中传入
原来是浏览器做的一些优化,chrome passive-event-listeners
Passive Event Listeners是Chrome提出的一个新的浏览器特性:Web开发者通过一个新的属性passive来告诉浏览器,当前页面内注册的事件监听器内部是否会调用preventDefault函数来阻止事件的默认行为,以便浏览器根据这个信息更好地做出决策来优化页面性能。当属性passive的值为true的时候,代表该监听器内部不会调用preventDefault函数来阻止默认滑动行为,Chrome浏览器称这类型的监听器为被动(passive)监听器。
知道问题就好说了,给addEventListener传入第三个参数
document.addEventListener("touchmove", function (event) { event.preventDefault() }, { passive: false })
大功告成!
突然想到,如果浮层中还需要滚动那就不GG了!
so,是不是可以有选择性的禁止滚动(在浮层中元素滚动到最顶部或者最底部之后禁止滚动)。
多带带处理浮层中需要滚动的元素;
targetElement.ontouchmove = function (event) { const clientY = event.targetTouches[0].clientY - initialClientY if (targetElement && targetElement.scrollTop === 0 && clientY > 0) { return preventDefault(event) } if (targetElement && (targetElement.scrollHeight - 1 - targetElement.scrollTop <= targetElement.clientHeight) && clientY < 0) { return preventDefault(event) } event.stopPropagation() return true }
这个方案在ios中完美实现,但是在 android中还是有一点问题;浮层内容拉到最顶部或者最底部的时候依然会带动页面的内容有一定程度的移动。
终极方案来啦!
tua-body-scroll-lock即是在ios、android和PC各个端多带带处理,保证在每个端都可以实现完美的效果!
demo
安装$ npm i -S tua-body-scroll-lock # OR $ yarn add tua-body-scroll-lock使用
import { lock, unlock } from "tua-body-scroll-lock" // 禁止滑动后还需要内部可以滚动的元素(针对移动端ios处理) const targetElement = document.querySelector("#someElementId"); lock(targetElement) unlock(targetElement)
tips: PC端不需要targetElement, 不传targetElement也不想要控制台提示可以传null
import { lock, unlock } from "tua-body-scroll-lock" lock() unlock()
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/103754.html
摘要:场景当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动然而事实并非如此。当属性的值为的时候,代表该监听器内部不会调用函数来阻止默认滑动行为,浏览器称这类型的监听器为被动监听器。 场景 当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。showImg(https://user-gold-cdn.xitu.io...
摘要:接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。心想来了突然意识到写弹窗的时候忘记处理滚动穿透的问题了。下期预告前端词典继承必懂知识点传送门前端词典代理的概念及其应用前端词典滚动穿透问题的解决方案 背景 产品有三宝,弹窗,浮层加引导; 设计有三宝,透明,阴影加圆角; 运营有三宝,短信,推送加红包; 程序员有一宝,这个做不了。 随着移动端市场的份额越大,需求就越多...
摘要:接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。心想来了突然意识到写弹窗的时候忘记处理滚动穿透的问题了。下期预告前端词典继承必懂知识点传送门前端词典代理的概念及其应用前端词典滚动穿透问题的解决方案 背景 产品有三宝,弹窗,浮层加引导; 设计有三宝,透明,阴影加圆角; 运营有三宝,短信,推送加红包; 程序员有一宝,这个做不了。 随着移动端市场的份额越大,需求就越多...
摘要:问题众所周知,移动端当有遮罩背景和弹出层时,在屏幕上滑动能够滑动背景下面的内容,这就是著名的滚动穿透问题之前搜索了一圈,找到下面两种方案之页面弹出层上将添加到上,禁用和的滚动条但是这个方案有两个缺点由于和的滚动条都被禁用,弹出层 问题 众所周知,移动端当有 fixed 遮罩背景和弹出层时,在屏幕上滑动能够滑动背景下面的内容,这就是著名的滚动穿透问题 之前搜索了一圈,找到下面两种方案 c...
摘要:所以这种情况下是不符合点击事件的定义的。,关于移动端的点击事件总结完了,可能你都没想到一个简单的点击事件会有那么多坑,如果你在工作中可能会涉及到移动端开发的话,相信这篇文章还是值得你点赞和收藏的,毕竟是踩了那么多坑的经验总结。 看标题的时候你可能会想,点击事件有什么好说的,还写一篇攻略?哈哈,如果你这么想,只能说明你too young to simple. 接触过移动端开发的同学可能都...
阅读 1179·2021-11-24 11:16
阅读 3412·2021-11-15 11:38
阅读 1887·2021-10-20 13:47
阅读 530·2021-09-29 09:35
阅读 2165·2021-09-22 15:17
阅读 991·2021-09-07 09:59
阅读 3352·2019-08-30 13:21
阅读 2885·2019-08-30 12:47