文章结构
事件绑定
普通的事件绑定方式如下:
1 2 3 4 5 6 7
| var div1 = document.getElementById('div1');
div1.addEventListener('click', function(e) { console.log('clicked'); });
|
可以对上述事件绑定编写一个更通用的方法:
1 2 3
| function bindEvent(el, event, fn) { el.addEventListener(event, fn); }
|
调用该方法:
1 2 3 4 5
| var div1 = document.getElementById('div1');
bindEvent(div1, 'click', function(e) { console.log('clicked'); });
|
事件冒泡
在 DOM 树上绑定的事件,会沿着 DOM 结构冒泡,从下到上挨个(直到 body)执行。使用 e.stopProgapation()可以阻止事件冒泡。
事件代理(事件委托)
应该添加到子元素上的事件,添加到了父元素上。例如:
1 2 3 4 5 6 7
| <div id="div1"> <a href="#">a1</a> <a href="#">a2</a> <a href="#">a3</a> <a href="#">a4</a> </div> <button>点击增加一个 a 标签</butto
|
这里,一个<div>
中包含很多个<a>
,并且将来还有可能继续添加<a>
。那么怎么快速方便地给<a>
添加事件呢?
这里我们就可以采用事件代理的方式,监听<a>
上的事件,但把具体的事件绑定到<div>
上。代码如下:
1 2 3 4 5 6 7 8
| var div1 = document.getElementById('div1');
div1.addEventListener('click', function(e) { var target = e.target; if (e.nodeName === 'A') { console.log(target.innerHtml); } });
|
再完善一下之前封装得方法,让它支持事件代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function bindEvent(el, event, selector, fn) { if (fn == null) { fn = selector; selector = null; }
el.addEventListener(event, function(e) { var target; if (selector) { target = e.target; if (target.match(selector)) { fn.call(target, e); } } else { fn(e); } }); }
|
改进之前的绑定代码:
1 2 3 4 5 6 7 8 9 10
| var div1 = document.getElementById('div1'); var a1 = document.getElementById('a1');
bindEvent(div1, 'click', function(e) { console.log(a1.innerHTML); });
bindEvent(div1, 'click', 'a', function(e) { console.log(this.innerHTML); });
|
使用事件代理的优点: