场景当页面出现浮层时,滑动浮层内容。一般情况下,应该预料到浮层下面的内容不会滚动;然而,这种情况并非如此。如图所示,浮层下的内容并没有像预期的那样不受影响。解决,先在github上搜索,发现有开源包可以解决这个问题。简单粗暴的选择其中最高的一颗星(body-scroll-lock)进行操作!使用后发现一些问题:Android端偶尔无法锁定,ios端偶尔无法锁定。查看源码发现,该包在iOS端是通过禁止touchmove单独处理的,而在另一端则是简单的通过在body中添加overflow:hidden来处理。.所以我决定写一个多终端的通用包来处理类似的问题。探索一:overflow:hidden看到下面的滚动,你肯定马上想到整个视口的滚动,所以如果给body设置overflow:hidden,此时body的内容将只有一屏,它绝对不会滚动;身体{溢出:隐藏;}这个方案完美的解决了我们PC端的问题,但是事情并没有那么简单;再次尝试移动端:移动端并没有出现预期的效果。..既然PC端已经有了完美的解决方案,那我们就继续探索移动端的解决方案吧。探索二:body定位我想到了在移动端给body设置overflow:hidden。是不是因为没有设置body的高度?设置html和body的高度为100%;为body设置绝对定位(固定);同时使用这两个操作似乎可以完美满足我们的需求;但是如图所示,页面每次都会被拉到顶部位置,看起来不太完美;既然用到了定位,那么给一个top值并没有定位到我们想要的位置(聪明如我)。Tips:如果body设置为相对定位,页面本身会被拉起,底部留空。多次实验发现,该方案在android端完美的达到了我们想要的效果,但在ios端却不理想;每次定位都会出现闪动的问题;事情需要时间,然后在ios端探索解决方案。探索三:如果页面禁止touchmove,是否可以禁止touchmove?不说话就做!当浮层弹出时,禁用页面元素的touchmovedocument.addEventListener('touchmove',function(event){event.preventDefault()})测试,发现没有达到预期的效果。我觉得这个结果是不能接受的。禁止文档touchmove不能禁止滚动吗?进一步探究,发现原因是传入了属性passiveaddEventListener的第三个参数,原来是浏览器做了一些优化。chromepassive-event-listenersPassiveEventListeners是Chrome:WebDeveloper提出的浏览器新特性passive的一个新属性,用于告诉浏览器当前页面注册的事件监听器是否会在内部调用preventDefault函数来阻止默认行为的事件,以便浏览器可以根据这些信息做出更好的决策,以优化页面性能。当属性passive的值为true时,表示不会在监听器内部调用preventDefault函数来阻止默认的滑动行为。Chrome浏览器将这种类型的监听器称为被动监听器。知道问题好说,把第三个参数document.addEventListener('touchmove',function(event){event.preventDefault()},{passive:false})传给addEventListener就大功告成了!突然想到,如果浮层还需要滚动,那就没有GG了!那么,可不可以选择性地禁止滚动(浮层中的元素滚动到顶部或底部后禁止滚动)。单独处理浮层中需要滚动的元素;targetElement.ontouchmove=function(event){constclientY=event.targetTouches[0].clientY-initialClientYif(targetElement&&targetElement.scrollTop===0&&clientY>0){returnpreventDefault(event)}if(targetElement&&(targetElement.scrollHeight-1-targetElement.scrollTop<=targetElement.clientHeight)&&clientY<0){returnpreventDefault(event)}event.stopPropagation()returntrue}这个方案在ios中是完美实现的,但是还是有一个android中的问题;当浮层内容被拉到顶部或底部时,仍会带动页面内容进行一定程度的移动。tua-body-scroll-lock终极解法来了!tua-body-scroll-lock在ios,android,pc各端分别处理,确保各端都能达到完美效果!demo安装$npmi-Stua-body-scroll-lock#OR$yarnaddtua-body-scroll-lock使用移动端import{lock,unlock}from'tua-body-scroll-lock'//禁止后滑动,需要在Element里面滚动(移动ios处理)consttargetElement=document.querySelector("#someElementId");lock(targetElement)unlock(targetElement)PCtips:PC不需要targetElement,如果你不想要传递targetElement并且不想要控制台提示,您可以传递它nullimport{lock,unlock}from'tua-body-scroll-lock'lock()unlock()
