关于JavaScript与HTML的交互事件(3)

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

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

了解了这四点区别后我们可以尝试写一个浏览器兼容性比较好的添加事件处理程序方法

复制代码 代码如下:


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, handler, );
                return true;
            }
            return false;
        }


这样,首先我们解决了第一个问题参数个数不同,现在三个参数,采用事件冒泡阶段触发,第二个问题也得以解决,如果是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;
        }


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

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdgsgj.html