我正在开发一个导航栏,其中有多个下拉菜单实例。我们正在尝试在下拉菜单打开时禁用页面滚动,并在启用下拉菜单时再次启用它。
目前我们有以下脚本,可以完美运行:
<script>
const resourcesElem = document.getElementById("resources");
const locationElem = document.getElementById("location");
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.attributeName === "class") {
if (resourcesElem.classList.contains("w--open") || locationElem.classList.contains("w--open")) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "visible";
}
}
});
});
const config = { attributes: true, attributeFilter: ["class"] };
observer.observe(resourcesElem, config);
observer.observe(locationElem, config);
</script>
基本上这个脚本的作用是使用 MutationObserver 检查两个下拉菜单中的更改,如果它们具有“w--open”类,则意味着下拉菜单已打开,然后禁用页面滚动。每当关闭下拉菜单时,“w--open”类就会被删除,因此页面滚动将再次启用。
但是,我们希望使其更加动态,因为我们希望将来增加导航栏中的下拉列表数量,并且我们希望避免手动更新脚本来检查所有元素。
就我而言,MutationObserver 在同时检查同一元素的多个实例时存在问题。我尝试让它检查父元素(div)的子元素(下拉列表)中的更改,但没有成功。
我还尝试过使用事件监听器在单击任何下拉列表时触发,但这种方法似乎不起作用,就像您单击任何下拉列表一样,页面滚动将被禁用,但如果您单击另一个下拉列表,则下拉列表将被禁用。仍然会打开,但页面滚动已启用。发生这种情况似乎是因为 MutationObserver 单独检查两个元素,其中一个元素禁用页面滚动,而另一个元素启用页面滚动。
问题是:有没有一种方法可以使脚本正常工作,同时又易于扩展?例如,我们可以检查属性,而不是检查 ID,如果添加新的下拉列表,这将使事情变得更容易。然而,这种方法似乎破坏了 MutationObserver,因为它只检查一个实例。
也许还有其他方法可以解决这个问题吗?
谢谢,
听起来您可以通过监听包含下拉列表的父元素的点击来实现这一点。您应该能够仅使用
if(parent.querySelector('w--open'))
来确定父级中是否存在打开的下拉列表的任何实例,而不是检查每个下拉列表以查看它是否具有该类 - 如果返回一个元素,您将禁用页面滚动。