锁定正文滚动,阻止目标元素滚动
Posted
技术标签:
【中文标题】锁定正文滚动,阻止目标元素滚动【英文标题】:Locking the body scroll, blocks target element scrolling 【发布时间】:2021-04-09 00:51:45 【问题描述】:我正在使用以下库来锁定页面主体的滚动,并且只允许在我的模式打开时滚动。
https://www.npmjs.com/package/body-scroll-lock
我的模态AddItemModal
是一个门户,所以在index.html
文件中我有这个。
<body>
<div id="root"></div>
<div id="add-item-modal"></div>
</body>
NavigationIcons 组件(打开模式的地方)
const NavigationIcons = (props) =>
let targetElement = document.getElementById("add-item-modal");
useEffect(() =>
...
return () => clearAllBodyScrollLocks();
, []);
const renderAddItemModal = () =>
if (props.addItem)
disableBodyScroll(targetElement);
return <AddItemModal />;
;
return (
<div className="main-4" onClick=() => props.openAddItemModal()>
renderAddItemModal()
</div>
);
AddItemModalHeader 组件(模态关闭的地方)
const AddItemModalHeader = (props) =>
let targetElement = document.getElementById("add-item-modal");
return (
<div className="modal-header">
add item
<div className="close" onClick=(e) =>
props.handleModalClose(e);
enableBodyScroll(targetElement);
>
close
</div>
</div>
)
在文档中写道targetElement
必须是我要显示的模式。但是由于应用程序是在root
div 中呈现的,并且模态显示在add-item-modal
中,所以它不应该是root
,而是将提供的函数应用于它,例如enableBodyScroll
、disableBodyScroll
、clearAllBodyScrollLocks
。我确实尝试了root
和add-item-modal
,在这两种情况下,当我从我的 ios 设备进行测试时,滚动都无法在模式上工作。
那里提供的示例并没有让我清楚这一点。有人可以解释我在这里做错了什么吗?
更新
其他可能在 iOS 设备上遇到此问题的人请参阅以下来自 Github 线程的解释清楚的答案 https://github.com/ionic-team/ionic-v1/issues/155#issuecomment-411110252
【问题讨论】:
【参考方案1】:body-scroll-lock
的一些已知问题是
输入tua-body-scroll-lock
请知道我与
tua-body-scroll-lock
没有任何联系。
tua-body-scroll-lock
与body-scroll-lock
提供的功能相同。喜欢
disableBodyScroll
lock
的别名
enableBodyScroll
unlock
的别名
clearAllBodyScrollLocks
clearBodyLocks
的别名
我使用tua-body-scroll-lock
制作了一个example 的小提琴
你的代码应该是这样的
import lock, unlock, clearBodyLocks from 'tua-body-scroll-lock';
const NavigationIcons = (props) =>
...
useEffect(() =>
...
return () => clearBodyLocks();
, []);
const renderAddItemModal = () =>
if (props.addItem)
lock(targetElement);
return <AddItemModal />;
;
...
const AddItemModalHeader = (props) =>
return (
<div className="modal-header">
add item
<div className="close" onClick=(e) =>
props.handleModalClose(e);
unlock(targetElement);
>
close
</div>
</div>
)
【讨论】:
我正在查看您的示例,想知道您从哪里获取clearBodyLocks
变量。我认为我的问题是我没有针对正确的节点元素,我想更好地了解您做了什么来了解如何使其工作。
clearBodyLocks
函数和你的clearAllBodyScrollLocks
有相同的用途,我将它与lock
和unlock
函数一起导入了代码的顶部
对不起,我的意思是 bodyScrollLock
来自示例
哦。我在 HTML 中导入了带有script
标记的tua-body-scroll-lock
。所以bodyScrollLock
就像拥有lock
、unlock
和clearBodyLocks
函数的对象
我编辑了 jsFiddle
以注销 bodyScrollLock
从我编辑的答案中查看新链接【参考方案2】:
如果您查看他们的源代码,disableBodyScroll 在内部所做的唯一事情就是在设备为 IOS 的情况下附加 ontouchstart
和 ontouchmove
事件并阻止该事件(通过调用e.preventDefault()
) 有条件地如果 targetElement 接近可滚动边界。
所以如果我理解正确的话,targetElement
必须是一个可滚动的元素,否则它永远不会绕过那些边界检查,它会阻止滚动。
在您的情况下,我认为 add-item-modal
不是可滚动元素,因此它不起作用。尝试在模式中使用targetElement
的任何可滚动元素。
【讨论】:
以上是关于锁定正文滚动,阻止目标元素滚动的主要内容,如果未能解决你的问题,请参考以下文章
由于目标被视为被动,无法在被动事件侦听器中阻止默认值?为啥滚动时出现此错误?
js 弹出框 里面元素touchmove时候阻止其他元素滚动,背景遮罩层还无法阻止冒泡,怎么禁用遮罩层touchmove