利用原生 Javascript 实现 Delegated Event

想要实现类似于 jQuery 中类似于 .on() 中的 Delegated Event,却又不想用 jQuery 怎么破?

先看问题

举个例子说明一下,有一组按钮,每当点击其中一个按钮,就把这个按钮的状态变为 "active",再点一下就取消 "active" 状态,代码如下:

<ul class="toolbar">
  <li><button class="btn">Pencil</button></li>
  <li><button class="btn">Pen</button></li>
  <li><button class="btn">Eraser</button></li>
</ul>

用最普通的 js 可以这样处理:

var buttons = document.querySelectorAll(".toolbar .btn");

for(var i = 0; i < buttons.length; i++) {
  var button = buttons[i];
  button.addEventListener("click", function() {
    if(!button.classList.contains("active"))
      button.classList.add("active");
    else
      button.classList.remove("active");
  });
}

不过并没有达到预期的效果。

闭包惹的祸

有经验的读者可能已经看出不对劲的地方了。那是因为处理点击事件的 handler 函数形成独立的作用域,是其中的 button 会尝试去更上级的作用域去寻找。
不过真正当你去点击按钮的时候,循环已经完成,button 就会一直指向最后一个按钮,所以效果就是不管点击哪个按钮都是最后一个按钮的状态在变化。

把代码改善一下:

var buttons = document.querySelectorAll(".toolbar button");
var createToolbarButtonHandler = function(button) {
  return function() {
    if(!button.classList.contains("active"))
      button.classList.add("active");
    else
      button.classList.remove("active");
  };
};

for(var i = 0; i < buttons.length; i++) {
  button.addEventListener("click", createToolBarButtonHandler(buttons[i]));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值