为什么addEventListener通过内联onclick fire引用函数立即添加?

时间:2016-05-09 00:15:27

标签: javascript

在最近的一个项目中,我继承了一些代码,为我提出了一些问题。

有人可以解释为什么从内联onclick函数添加一个事件监听器会立即触发addEventListner()中引用的函数吗?

function refFunction() {
  console.log("Test Function");

  if (document.removeEventListener) {
    document.removeEventListener('click', refFunction, false);
  } else if (document.detachEvent) {
    document.detachEvent('onclick', refFunction);
  }
}

function addEvtLstnr() {
  if (document.addEventListener) {
    document.addEventListener('click', refFunction, false);
  } else if (document.attachEvent) {
    document.attachEvent('onclick', refFunction);
  }
}
<input type="button" value="Add Evt listener" onClick="addEvtLstnr();">

请在此处查看JSfiddle:Example JSFiddle

我想要的效果是使用按钮的内联onclick添加事件处理程序,但是不要立即触发引用的函数。

感谢任何帮助, 学家

2 个答案:

答案 0 :(得分:3)

单击按钮时,侦听器将添加到文档中。然后,click事件会冒泡到文档,触发侦听器。

为避免这种情况,请使用超时添加侦听器,以便事件在添加之前完成冒泡。

或者,停止传播事件,使其不会冒泡。

&#13;
&#13;
function refFunction() {
  console.log("Test Function");

  if (document.removeEventListener) {
    document.removeEventListener('click', refFunction, false);
  } else if (document.detachEvent) {
    document.detachEvent('onclick', refFunction);
  }
}

function addEvtLstnr() {
  if (document.addEventListener) {
    document.addEventListener('click', refFunction, false);
  } else if (document.attachEvent) {
    document.attachEvent('onclick', refFunction);
  }
}
&#13;
// Call addEvtLstnr after a pause so event finishes bubbling before listener added
<input type="button" value="Add Evt listener" onclick="setTimeout(addEvtLstnr, 0);">

// Stop propagation of the event so that it doesn't reach the listener
<input type="button" value="Add Evt listener 2" onclick="addEvtLstnr();event.stopPropagation();">
&#13;
&#13;
&#13;

BTW,函数声明不以分号结束。 ; - )

答案 1 :(得分:0)

引用:“有人可以解释为什么从内联onclick函数添加一个事件监听器会立即触发addEventListner()中引用的函数吗?”

这不完全正确,事件必须 传播 通过相当多的元素才能最终到达并触发根元素< / em>您实际添加了事件监听器。

在为元素分配了一个click事件监听器之后,root元素将在input元素上接收click事件,因此需要按规定触发它。