委派点击事件仅在第二次点击前进行

时间:2016-11-15 16:17:31

标签: javascript events delegation

我正在尝试构建和学习原生javascript event delegation(不确定),就像这样

function clicked(d) {
  d.innerText = "clicked";
}
document.addEventListener('click', function() {
  var foos = Array.from(document.getElementsByClassName('foo'));
  foos.forEach(function(elm, i) {
    elm.addEventListener('click', function() {
      clicked(elm);
    });
  });
})

document.body.innerHTML = `<div class="foo"></div><div class="foo"></div><div class="foo"></div><div class="foo"></div>`;
.foo {
  height: 100px;
  width: 100px;
  float: left;
  border: 1px solid green;
}

为什么它只在第二次点击后才能工作?

我可以使用jQuery on方法更改上面的addEventListener代码块以使其工作,但我只想知道如何使我的代码在上面行为相似。

2 个答案:

答案 0 :(得分:1)

事件委托使用事件冒泡和event.target属性来处理多个子元素的事件,其中一个事件处理程序附加到其父元素(请参阅{Tttlaw的this explanation和{{3中的其他示例)大卫沃尔什)。

在您的情况下,您不需要为每个foo div添加事件处理程序,因为click事件是在文档级别处理的。您只需检查click事件的目标是否具有foo类,并将该目标元素传递给clicked函数。

&#13;
&#13;
function clicked(d) {
  d.innerText = "clicked";
}

document.addEventListener('click', function(e) {
  if (e.target.className === "foo") {
    clicked(e.target);
  }
});

document.body.innerHTML = '<div class="foo"></div><div class="foo"></div><div class="foo"></div><div class="foo"></div>';
&#13;
.foo {
  height: 100px;
  width: 100px;
  float: left;
  border: 1px solid green;
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这是因为你没有设置div上的点击处理程序,直到你点击了document一次。

  • 删除document上的点击处理程序。
  • 在尝试选择课程
  • 之前写入dom

function clicked(d) {
  d.innerText = "clicked";
}

document.body.innerHTML = `<div class="foo"></div><div class="foo"></div><div class="foo"></div><div class="foo"></div>`;

var foos = Array.from(document.getElementsByClassName('foo'));
foos.forEach(function(elm, i) {
  elm.addEventListener('click', function() {
    clicked(elm);
  });
});
.foo {
  height: 100px;
  width: 100px;
  float: left;
  border: 1px solid green;
}