如何在使用pointer-events:none;的情况下允许JS onclick事件?

8

我在整个页面上放了一个

,当点击大的
时关闭下拉菜单。问题是我需要使用pointer-events: none;,因为如果我不使用它,整个页面会被阻塞。

如果我使用pointer-events:none;,JS的onclick无法工作。所以,我真的不知道该如何解决这个问题。

 function test() {
            if (document.getElementById('div1').style.display == 'block') {
               document.getElementById('div1').style.display = 'none';
           }
           else{

           }

            }

#big_div{
    width: 100%;
    height: 100%;
    display: block;
    pointer-events:none;
}

 <div id="big_div" onclick="test()"></div>

你的 big_div 是为了关闭菜单而存在的吗?如果是,那么有一个比用 div 覆盖整个视口更简单的解决方案。 - Patrick Evans
我认为您不能使用“pointer-events:none;”允许JS onclick。实际上,这正是该属性的作用,即使无法单击它。 - Mark E
@PatrickEvans 是的,它只是用于关闭菜单。有什么解决方案吗? - anonym
我不知道你的下拉菜单是如何制作的,但也许你可以尝试使用 focusout 或在打开下拉菜单时将 onclick 事件附加到 body 上。 - Mark E
2
所以...你正在用一个元素覆盖页面,而这个元素是无法点击的,但你想要能够读取它的点击事件?我认为答案可能只是“不要那样做”。 - Daniel Beck
我做了<body onclick="test()">,但它没有被关闭。 - anonym
3个回答

7

不要使用覆盖整个页面的div,而是在文档上添加一个点击监听器,检查被点击的元素是否为菜单或菜单的子元素,如果不是,则隐藏菜单。

document.addEventListener("click",function(e){
    var menu = document.getElementById("myMenu");   
    var target = e.target;
    if(target !== menu && !menu.contains(target)){
       menu.style.display = "none";
    }
});

演示

document.addEventListener("click",function(e){
    var menu = document.getElementById("myMenu");   
    var target = e.target;
    var openBtn = document.querySelector("button");
  
    if(target !== menu && !menu.contains(target) && target !== openBtn){
       menu.style.display = "none";
    }
});

document.querySelector("button").addEventListener("click",function(){
  document.getElementById("myMenu").style.display = "block";
});
menu {
  width:120px;
  height:300px;
  background:#88DDFF;
  display:none;
}
<menu id="myMenu"><span>some item</span></menu>

<button>Open menu</button>


谢谢,我更进一步地将事件添加为捕获(更多信息请参见https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) - Coding Edgar

1

pointer-events: none 表示没有事件会穿过该元素。相反,您应该监听整个文档上的点击/鼠标按下事件来关闭菜单(并删除设置为 pointer-events: none 的 div 元素)。

document.addEventListener('mousedown', function(e) {
  // You may need a better check involving e.target because
  // you won't want to close the menu when clicking inside the menu
  // or on the button (if the menu is not open)
  if (!e.target.contains(menuNode)) {
       document.getElementById('div1').style.display = 'none';
  }  
});

1
抱歉,我没有认真阅读你的问题,因此我的错误答案被投了反对票。
但是,根据你的问题,你想用那个div覆盖整个页面以阻止点击事件,但仍然希望接收点击事件,实际上可以这样做:
1)从该div中删除pointer-events:none;并添加cursor:
#big_div {
    width: 100%;
    height: 100%;
    display: block;
    cursor: none;
}

2) 如我之前所述,将监听器添加到您的div中,并从那里防止点击:

document.getElementById("big_div").addEventListener("click", function(e) {
     e.preventDefault();
     // Do whatever you want to do
     if (document.getElementById('div1').style.display == 'block') {
         document.getElementById('div1').style.display = 'none';
     }
});

OP在菜单弹出时无法直接点击背景元素,这是OP提出的主要问题。 - Ruan Mendes
哦!这个问题有点令人困惑。 - Shashank Agrawal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接