事件流
![picture 1](data:image/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+)
事件捕获
捕获阶段,事件依次传递的顺序是:window –> document –> html–> body –> 父元素、子元素、目标元素
事件冒泡
以下事件不冒泡:blur、focus、load、unload、onmouseenter、onmouseleave,可以通过event.bubbles
检查。
阻止冒泡:
1 2 3 4 5 6 7 8 9 10 11
| element.onclick = function (event) { event = event || window.event;
if (event && event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } };
|
事件委托
事件委托,是把一个元素响应事件(click、keydown……)的函数委托到另一个元素,如在父元素的响应函数中处理子元素的事件,事件委托利用了冒泡机制,减少了事件绑定的次数,减少内存消耗,提高性能。
focus、blur 之类的事件本身没有事件冒泡机制,所以无法委托。
mousemove、mouseout 这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的。
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| function eventDelegate(parentSelector, targetSelector, events, foo) { function triFunction(e) { var event = e || window.event;
var target = event.target || event.srcElement;
var currentTarget = event.currentTarget;
if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function (s) { var matches = (this.document || this.ownerDocument).querySelectorAll( s ), i = matches.length; while (--i >= 0 && matches.item(i) !== this) {} return i > -1; }; }
while (target !== currentTarget) { if (target.matches(targetSelector)) { var sTarget = target; foo.call(sTarget, Array.prototype.slice.call(arguments)); }
target = target.parentNode; } }
events.split(".").forEach(function (evt) { Array.prototype.slice .call(document.querySelectorAll(parentSelector)) .forEach(function ($p) { $p.addEventListener(evt, triFunction); }); }); }
eventDelegate("#list", "li", "click", function () { console.log(this); });
|
DOM2 的写法:addEventListener
addEventListener(type, listener, ?option)
- 参数 3:true 表示捕获阶段触发,false 表示冒泡阶段触发(默认)。如果不写,则默认为 false。
- 可以绑定多个响应函数,执行顺序是:事件被触发时,响应函数会按照函数的绑定顺序执行。
addEventListener()
中的 this
,是绑定事件的对象