场景
当页面涌现浮层的时刻,滑动浮层的内容,一般状况下预期应该是浮层下边的内容不会转动;然则现实并非如此。
如图所示,浮层下边的内容并没有如设想中不受影响。
处置惩罚
先去github上搜刮一番,发明有处置惩罚此题目的开源包,简朴粗犷直接遴选了个中star的最高的(body-scroll-lock)操纵一番!
运用后发明有一些题目:
- 安卓端全挂
- ios端偶然会有锁不住的状况
查源码发明该包在iOS
端运用制止touchmove
的体式格局零丁处置惩罚,然则在其他端只是给body
加overflow: hidden
简朴处置惩罚。
因而决议写一个针对多端通用的包来处置惩罚相似的题目。
探究一:overflow: hidden
看到下边的转动肯定马上就想到了是全部viewport
的转动,那末假如给body设置overflow: hidden
,此时body的内容就只有一屏了,肯定不会转动了;
body { overflow: hidden; }
此计划在pc端圆满处置惩罚了我们的题目,然则事变并没有那末简朴;
再尝尝挪动端:
挪动端中并没有涌现期待的效果。。。
既然pc端已经有了圆满的计划,下边我们继承探究挪动端的处置惩罚计划。
探究二:body定位
上边想到给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
最终计划来啦!
tua-body-scroll-lock等于在ios
、android
和PC
各个端零丁处置惩罚,保证在每一个端都能够完成圆满的效果!
装置
$ 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)
PC端
tips: PC端不须要targetElement, 不传targetElement也不想要控制台提醒能够传
null
import { lock, unlock } from 'tua-body-scroll-lock'
lock()
unlock()