javascript事件

来源:互联网 发布:sonos软件下载 编辑:程序博客网 时间:2024/06/14 10:49


在添加事件处理程序事addEventListener和attachEvent主要有几个区别

1. 参数个数不相同,这个最直观,addEventListener有三个参数,attachEvent只有两个,attachEvent添加的事件处理程序只能发生在冒泡阶段,addEventListener第三个参数可以决定添加的事件处理程序是在捕获阶段还是冒泡阶段处理(我们一般为了浏览器兼容性都设置为冒泡阶段)

2. 第一个参数意义不同,addEventListener第一个参数是事件类型(比如click,load),而attachEvent第一个参数指明的是事件处理函数名称(onclick,onload)

3. 事件处理程序的作用域不相同,addEventListener得作用域是元素本身,this是指的触发元素,而attachEvent事件处理程序会在全局变量内运行,this是window,所以刚才例子才会返回undefined,而不是元素id

4. 为一个事件添加多个事件处理程序时,执行顺序不同,addEventListener添加会按照添加顺序执行,而attachEvent添加多个事件处理程序时顺序无规律(添加的方法少的时候大多是按添加顺序的反顺序执行的,但是添加的多了就无规律了),所以添加多个的时候,不依赖执行顺序的还好,若是依赖于函数执行顺序,最好自己处理,不要指望浏览器



这样,首先我们解决了第一个问题参数个数不同,现在三个参数,采用事件冒泡阶段触发,第二个问题也得以解决,如果是IE,我们给type添加上on,第四个问题目前还没有解决方案,需要用户自己注意,一般情况下,大家也不会添加很多事件处理程序,试试这个方法感觉很不错,但是我们没有解决第三个问题,由于处理程序作用域不同,如果handler内有this之类操作,那么就会出错在IE下,实际上大多数函数都会有this操作。

复制代码
function addEvent(node, type, handler) {            if (!node) return false;            if (node.addEventListener) {                node.addEventListener(type, handler, false);                return true;            }            else if (node.attachEvent) {                node.attachEvent('on' + type, function() { handler.apply(node); });                return true;            }            return false;        }
复制代码

这样处理就可以解决this的问题了,但是新的问题又来了,我们这样等于添加了一个匿名的事件处理程序,无法用detachEvent取消事件处理程序,有很多解决方案,我们可以借鉴大师的处理方式,jQuery创始人John Resig是这样做的

复制代码
function addEvent(node, type, handler) {            if (!node) return false;            if (node.addEventListener) {                node.addEventListener(type, handler, false);                return true;            }            else if (node.attachEvent) {                node['e' + type + handler] = handler;                node[type + handler] = function() {                    node['e' + type + handler](window.event);                };                node.attachEvent('on' + type, node[type + handler]);                return true;            }            return false;        }
复制代码

在取消事件处理程序的时候

复制代码
function removeEvent(node, type, handler) {            if (!node) return false;            if (node.removeEventListener) {                node.removeEventListener(type, handler, false);                return true;            }            else if (node.detachEvent) {                node.detachEvent('on' + type, node[type + handler]);                node[type + handler] = null;            }            return false;        }
复制代码

John Resig很巧妙地利用了闭包,看起来很不错。



虽然DOM和IE的event对象不同,但基于它们的相似性,我们还是可以写出跨浏览器的事件对象方案

复制代码
function getEvent(e) {            return e || window.event;        }        function getTarget(e) {            return e.target || e.scrElement;        }        function preventDefault(e) {            if (e.preventDefault)                e.preventDefault();            else                e.returnValue = false;        }        function stopPropagation(e) {            if (e.stopPropagation)                e.stopPropagation();            else                e.cancelBubble = true;        }






0 0