首页 > 技术文章 > 事件兼容及对内存的影响

webliu 2015-04-19 10:57 原文

 1 var EventUtil={
 2        addHandler:function(element,type,handler){    //为元素添加事件处理程序
 3            if(typeof element.addEventListener=="function"){
 4                element.addEventListener(type,handler,false);   //DOM2
 5            }else if(typeof element.attachEvent=="function"){
 6                element.attachEvent("on"+type,handler);   //IE
 7            }else{
 8               element["on"+type]=handler;    //所有的浏览器都支持
 9            }
10        },
11 
12        getEvent:function(event){    //获取包含事件信息的event对象
13            return event?event:window.event;
14        },
15 
16        getTarget:function(event){       //获取事件的目标target
17            return event.target||event.srcElement;
18        },
19        getRelatedTarget:function(event){   //获取相关元素,针对mouseover与mouseout事件
20            if(event.relatedTarget){
21                return event.relatedTarget;
22            }else if(event.fromElement){
23                return event.fromElement;
24            }else if(event.toElement){
25                return event.toElement;
26            }else{
27                return null;
28            }
29        },    
30        getButton:function(event){    //获取鼠标的按钮,针对mousedown和mouseup事件
31            if(document.implementation.hasFeature("MouseEvents","2.0")){
32                return event.button;
33            }else{
34                switch(event.button){
35                    case 0:
36                    case 1:
37                    case 3:
38                    case 5:
39                    case 7:
40                        return 0; //主鼠标
41                    case 4:
42                        return 1; //中间鼠标
43                    case 2:
44                    case 6:
45                         return 2;  //次鼠标
46                }
47            }
48        },
49         getWheelDelta:function(event){  //鼠标滚动事件
50            if(event.wheelDelta){
51                return event.wheelDelta;
52            }else{
53                return -40*event.detail;
54            }
55        },
56        getCharCode:function(event){   //获取字符编码,针对keypress事件
57            if(typeof event.charCode=="Number"){
58                return event.charCode;
59            }else{
60                return event.keyCode;
61            }
62        },
63        preventDefault:function(event){  //阻止事件的默认行为
64            if(event.preventDefault){
65                event.preventDefault();
66            }else{
67                event.returnValue=false;
68            }
69        },
70        stopPropagation:function(event){  //阻止事件流
71            if(event.stopPropagation){
72                event.stopPropagation();
73            }else{
74                event.cancelBubble=true;
75            }
76        },
77        removeHandler:function(element,type,handler){  //删除事件
78            if(typeof element.removeEventListener=="function"){
79                element.removeEventListener(type,handler,false);
80            }else if(typeof element.detachEvent=="function"){
81                element.detachElement("on"+type,handler);
82            }else{
83                element["on"+type]=null;
84            }
85        }
86    };

创建了一个关于事件的EventUtil对象,通过这个对象调用方法。

内存性能:添加到页面中的事件处理程序的数量直接关系到页面整体的运行性能。一方面是由于函数是对象,对象占用内存,内存中的对象越多,性能就越差。另一方面是由于事先指定事件处理程序会导致对DOM的访问次数增多,会延迟整个页面的交互就绪的时间。下面是提升性能的方法:

  • 事件委托:利用事件冒泡的原理,将事件处理程序添加到DOM中尽可能高的元素节点,从而管理某一类型的所有事件。当触发某一具体元素的事件时,事件会冒泡到添加事件处理程序的元素上,对事件进行处理。这里需要用到事件的target属性来判断事件的真正目标。可以的话,可以考虑为document添加一个事件处理程序,用于处理网页上发生的某一类型的事件:这样对document很快能够访问,只要事件元素出现在页面上就具备交互能力;在页面设置事件处理程序的事件变短;整个页面占用的内存更少,性能进一步提升。
  • 移除事件处理程序:每当将事件处理程序制定给某个元素时,运行在浏览器中的代码就就会与支持JavaScript交互的代码创建一个连接。这种连接越多,页面的运行速度就越慢。(1)通过innerHTML移除带有事件处理程序的元素,由于移除的元素带有事件处理程序,它们保持着引用的关系,所以无法被当作垃圾回收。一方面可以事先手动移除事件,然后再用innerHTML移除元素,另一方面,如果事先知道将来将通过innerHTML移除元素,那就把事件别直接添加到元素上,可添加到委托元素上。(2)卸载页面之前没有清理干净事件处理程序,它们就会滞留在内存中。可在页面卸载前利用onunload事件处理程序移除所用的事件处理程序,利用事件委托添加的事件处理程序越少,越容易移除。

推荐阅读