添加第二个addEventListener()会破坏第一个

时间:2019-11-09 11:17:09

标签: javascript

我正在隐藏加载中的p,然后单击按钮应显示它,然后单击其他位置将其隐藏。

我可以隐藏它,然后在单击按钮时显示它,但是当我添加另一个addEventListener使其在任何地方单击时都隐藏它时,它将破坏它。

html:

<button id="btn">click me</button>

<p id="p">text here</p>

JS:

var btn = document.getElementById('btn')
var p = document.getElementById('p')

p.style.display = "none"

btn.addEventListener('click', function() {
  p.style.display = "block"

    document.addEventListener('click', function() {
    p.style.display = "none" 
  })

})

https://jsfiddle.net/v65qh4o1/

2 个答案:

答案 0 :(得分:1)

当您在文档上添加事件监听器时,每当单击按钮时,它仍会触发,因为该按钮也是文档的一部分,并且当您单击按钮时,会间接单击该文档。

尝试以这种方式进行。

var btn = document.getElementById('btn')
var p = document.getElementById('p')

p.style.display = "none"

btn.addEventListener('click', function() {
  p.style.display = "block"
})
document.addEventListener('click', function(event) {
  if(event.target !== btn){
    p.style.display = "none"    
  }

});

查看有效的fiddle here


更新

为防止在单击<p>时隐藏文本,请在if语句中添加另一个条件。

document.addEventListener('click', function(event) {
  if(event.target !== btn && event.target !== p){
    p.style.display = "none"    
  }
});

答案 1 :(得分:0)

那是因为事件监听器冒泡了,所以如果您单击按钮,整个文档也会被单击。因此,当您第一次单击该按钮时,侦听器将附加到该文档,然后无论何时单击它,都会触发两个侦听器以撤消彼此的更改。

您可以让内部处理程序仅触发一次,而不污染事件处理程序列表:

 btn.addEventListener('click', function() {
  p.style.display = "block"

  document.addEventListener('click', function() {
    p.style.display = "none" 
  }, { once: true });
});

如果您不想再次单击按钮以再次隐藏该段落,可以使用以下方法阻止事件冒泡:

 btn.addEventListener(function (event) {
   event.stopPropagation();
   //...
 });
相关问题