今天从事件流,DOM0级事件绑定,DOM2级事件绑定,低版本IE事件绑定等方面来学习事件。
事件流
当你单击了某个元素,单击事件不仅仅发生在这个元素上,你也单击了它的父元素、父元素的父元素、……它的祖先元素,甚至单击了整个页面。
“事件流”描述的是页面上各个元素接收事件的顺序。
我们为了描述事件的传播顺序,特意人为规定了两个阶段:捕获阶段capture pahse、冒泡阶段bubbling phase。点击页面上的一个元素,事件在哪个阶段触发,这取决于添加事件监听的方法。
DOM0级事件绑定
DOM分为级别,DOM0级、1级、2级、3级,是不同的标准,标准一直在升级。
我们之前学习的 obj.onclick = function () {} 这种注册监听的写法,就是DOM0级的事件绑定方法。就是把onclick当做属性添加给了oDiv元素。
通过实验,我们发现,这种事件添加方法,只能监听冒泡过程。事件的捕获阶段,没有监听成功。
这里需要注意,在IE9、Chrome里面,事件会冒泡到window对象,而IE6、7、8仅仅冒泡到document对象。
另外,用这种方法绑定的监听,this指的是触发这个事件的元素,没有任何的浏览器兼容问题。
DOM0级还有一种写法,直接将监听写在标签里面,工作中不许用:
写在HTML标签里面代码耦合性很强,三层没有完全分离,工作中不用的。这种写法,也是监听冒泡阶段。
用DOM0级添加事件监听,同一个元素不能有两个同样事件监听,比如:
- box.onclick = function () {
- alert(1);
- }
- box.onclick = function () {
- alert(2);
- }
以JS代码后出现的为准,它会覆盖先写的函数。所以点击box弹出2。
DOM2级事件绑定
DOM1级规范中,没有对事件进行改动,所以不再赘述。
DOM2级做了新的规范,不用on来绑定监听了,而是使用一个方法 addEventListener()。它接受三个参数:什么事件、函数、是否监听捕获阶段。
第1个参数:事件名不用写on,比如:click、mouseover 、mouseout
第2个参数:函数可以是匿名函数,也可以是有名函数
第3个参数:布尔值,true表示监听捕获、false表示监听冒泡阶段
比如:
- box.addEventListener("click", funciton () {
- alert(1);
- }, true);
第三个参数是true,表示监听box的捕获阶段的单击事件。
addEventListener可以重复添加相同事件名的事件:我们给box1的绑定了两个事件冒泡阶段的监听,不会覆盖,两个监听的函数都会执行,按照代码执行顺序。
- box.addEventListener("click", funciton () {
- alert(1);
- }, true);
- box.addEventListener("click", funciton () {
- alert(2);
- }, true);
先弹出1,然后弹出2。
低版本IE的事件绑定
现在仍有少量的用户在使用IE8,所以我们把低版本的IE事件绑定说明一下。
IE6、7、8不支持addEventListener()方法,支持 attachEvent() 方法。
- box.attachEvent("onclick", function () {
- alert("click");
- });
attachEvent方法没有第三个参数,也就是说,不能选择监听捕获、冒泡,只能监听冒泡阶段。
第一个参数,必须写on,和addEventListener()不一样;
第二个参数,就是事件处理函数
没有第三个参数,只能监听冒泡。所以和DOM0事件写法一样(比如onclick)。
低版本IE的事件监听attachEvent:事件处理函数里面的this,不是触发事件的这个元素,而是window对象!
并且,同一个事件名的多个监听,会反着执行:
- box.attachEvent("onclick", function () {
- alert(1);
- });
- box.attachEvent("onclick", function () {
- alert(2);
- });
- box.attachEvent("onclick", function () {
- alert(3);
- });
结果会弹出3、2、1。