文章目录
  1. 1. 事件流
  2. 2. 事件处理程序
  3. 3. 事件对象
  4. 4. 内存与性能
  5. 5. 总结

    JS中原生的事件需要关注的主要是事件的处理程序、事件对象以及跨浏览器的解决方案。我主要使用的DOM2级方法,并且为了浏览器的兼容性基本上都设置在冒泡阶段捕获。这里主要是原生事件的基本知识,具体属性问题在实际使用时一查就知道了,所以也不全哈~~~

事件流

事件流是页面中接收事件的顺序:冒泡(IE)与捕捉(网景)。 现在高版本的浏览器这两种都会支持,在”DOM2级事件”中将事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

事件处理程序

  1. DOM0 级事件处理程序每个元素都有自己的事件处理程序属性(onclick等属性),这些属性通常小写,将这种属性值设置成一个函数,就可以指定事件处理程序。这时候的事件处理程序是在元素的作用域中运行, 即程序中的this 指向当前元素。(onclick)(这是肯定的啊,这个事件处理程序是这个元素对象的一个属性方法,this自然指向自己…),注意:这种方法添加的事件处理程序会在事件流的冒泡阶段被处理。
    删除事件处理程序: btn.onclick = null;
  2. DOM2 级事件处理程序DOM2级事件定义了两个方法,用于指定和删除事件处理程序的操作,addEventListener()和removeEventListener()。所有DOM节点都包含着两个方法,并且有3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。true:表示在捕获阶段调用事件处理程序。false:在冒泡阶段调用事件处理程序(建议用false).

    DOM2 好处是可以添加多个事件处理程序。 用addEventListener()添加的事件处理函数必须用removeEventListener()才能移除。对于匿名函数无法处理。这时候的事件处理程序是在元素的作用域中运行, 即程序中的this 指向当前元素。 (click)

  3. IE事件处理程序IE 实现了两个方法,attachEvent()与detachEvent()。参数为事件处理程序名称与事件处理程序参数。 attachEvent添加的事件处理程序都会被添加到冒泡阶段。但此事件处理程序的作用域是全局。可以用来为一个元素添加多个事件处理程序。detachEvent用来移除事件。(onclick).
    与DOM0级方法与DOM2级方法不一样的是 :这个attachEvent()中的事件处理程序是在全局作用域中运行。

    1
    2
    3
    btn.attachEvent('onclick',function(){
    alert(this == window);// true !!! 很重要
    })

    另外: 添加多个事件处理程序时 这些事件处理程序不是以添加他们的顺序执行,而是以相反的顺序触发!!!!!!!!

  4. 跨浏览器的事件处理程序创建一个属于EventUtil对象的方法addHandler 与 removeHandler()。职责是根据情况分别使用DOM0级方法、DOM2级方法或IE方法来添加事件。3个参数:要操作的元素、事件名称和事件处理函数。  

    事件对象

    所有浏览器都支持event对象。在触发DOM上的某个事件时,都会产生一个事件对象event.这个对象上面包含着所有与事件有关的信息。

  1. DOM中的事件对象 event对象包含与创建他的特定事件有关的属性与方法。触发事件类型不一样,可用的属性与方法也不一样。this始终等于currentTarget的值,而target则只包含的事件(作用的)实际对象。要阻止事件的默认行为,可以使用preventDefault()方法,如阻止链接的默认行为(单击时会导航到其href指定的url)。stopPropagation()方法用于立即停止事件在DOM层次的传播,取消进一步的事件捕捉或冒泡。

  2. IE中的事件对象IE中的事件对象根据方法不同而不同。若采用的是DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。若是用attachEvent()添加的,则event会作为参数传入事件处理程序函数。event对象也会因为事件类型的不同而不同。 returnValue属性相当于prevaentDefault(),cancelBubble属性相当于stopPropagation().

  3. 跨浏览器的事件对象

内存与性能

在JS中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,导致这一问题的原因:首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能就越差。 其次,必须事先指定所有事件处理程序而导致的DOM访问次数增加,会延迟整个页面的交互就绪事件。

  1. 事件委托:可以解决 “事件处理程序过多”。事件委托利用冒泡,只在DOM树中尽量最高的层次上添加一个事件处理程序,就可以管理某一类型的所有事件。
  2. 空事件处理程序: 当从文档中移除待有时间处理程序的元素时,若通过纯粹的DOM操作,如removeChild() 、 replaceChild()、innerHTML替换页面某一部分时,那么原来添加到元素中的事件处理程序极有可能无法被当做垃圾回收。另一种情况是当卸载页面时会使得空事件处理程序增加。
  3. 移除事件处理程序: 每当将事件处理程序指定元素时,运行中的浏览器代码与支持页面交互的js代码之间就会建立一个连接,这种连接越多,页面执行起来就会越慢。 为减少这种情况,一可以使用事件委托,二是可以使用移除事件处理程序
    移除事件处理程序就是在使用removeChild() 、 replaceChild()、innerHTML替换页面某一部分之前,手动的移除事件处理程序
    1
    btn.onclick = null;

更好的解决办法是 在页面卸载之前,先通过onunload事件处理程序移除所有事件处理程序。

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//事件处理程序
var EventUtil = {
addHandler: function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
elemenr["on" + type] = handler;
}
},
//跨浏览器的事件对象
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
}
}

其实说了那么多,不过是在解释这几行代码,用时直接粘贴啊。。。这就是城市人的套路啊……
我还不知道在重用的库中事件的实现机制是什么,,,还有在AngularJS 中的实现机制是什么,等—-JS中的事件(二) 吧…..

文章目录
  1. 1. 事件流
  2. 2. 事件处理程序
  3. 3. 事件对象
  4. 4. 内存与性能
  5. 5. 总结