dom事件/事件代理杂谈

1、事件流过程

从上向下有一个分发过程,从下到上有一个冒泡过程,在绑定事件时,可以指定处理函数是在capture过程还是bubble过程(addEventListener第三个参数为true的话,是在capture时触发,默认false,在bubble时触发),然而,不是所有版本的浏览器都包含这两个完整的过程,有的没有捕获阶段,有的没有冒泡阶段。
典型例子,有父子两个div,各自addEventListener,如果父div是capture,则父div处理函数会先运行,如果父div是bubble,会后运行。
事件对象会作为参数传入绑定的处理函数,这里有个hack,ie的事件对象是在window上的,所以要写e = e||window.event来兼容。

2、事件代理
就是把事件处理函数注册在父元素上面,统一代理子元素,e.target是被点击的dom元素,e.currentTarget是绑定处理函数的父dom元素,这种代理机制恰恰是事件流捕获、冒泡的体现。下面用一个最简单的例子来说明代理或非代理的事件机制。
考虑一个ul内包含多个li,点击不同的li,显示这个li的index
1)循环绑定,用for循环遍历li标签,分别添加事件处理函数,注意要用到闭包
2)改进循环绑定,仍然用for循环,但是给li的dom元素添加index属性(document.getElementById("the_li").index=i),这样在处理函数中,直接alert(this.index)就可以了(调用处理函数的正是dom元素,所以this指向该dom元素)。
3)事件代理,把处理函数绑定到ul上面去,同时给dom元素上添加index属性,则alert(e.target.index)就可以了。
4)jQuery实现,jQuery实行绑定的时候,可以传递data,把data放在了event事件对象的属性中(?原理不明白?),共有bind、live、delegate、on四种方法,1.7以上版本推荐用on代替前三种方法,前三种方法就是鲜明的代理与非代理的区别,bind是非代理的,绑定到具体的元素上,delegate代理,指定了父元素和委托事件的子元素,冒泡到父元素就会触发事件,所以,对于绑定完成后,新的动态添加到父元素内的匹配元素,对于事件依然是响应的,live的区别就是把父元素直接设定为document了。