zoukankan      html  css  js  c++  java
  • w3c与微软(IE)事件注册区别 -Tom

    严格来说,有2中不同的模型:W3C模型和微软模型,除IE之外W3C模型支持所有的现代浏览器,而微软模型只支持IE,使用W3C模型的代码如下:

    // 格式:target.addEventListener( type, function, useCapture );  
    // 例子:
    var myIntro = document.getElementById('intro');
    myIntro.addEventListener('click', introClick, false);

    使用IE模型的代码如下:

    // 格式: target.attachEvent ( 'on' + type, function );  
    // 例子:
    var myIntro = document.getElementById('intro');
    myIntro.attachEvent('onclick', introClick);

    introClick的代码如下:

    function introClick() {  
    alert('You clicked the paragraph!');
    }

    事实上,要做出通用的话,我们可以自定义一个函数以支持跨浏览器:

    function addEvent(elem, type, fn) {
    if (elem.attachEvent) {
    elem.attachEvent('on' + type, fn);
    return;
    }
    if (elem.addEventListener) {
    elem.addEventListener(type, fn, false);
    }
    }

    该函数首先检查attachEvent和addEventListener属性,谁可以就用谁,这两种类型的模型都支持删除句柄功能,参考下面的removeEvent函数。

    function removeEvent(elem, type, fn) {
    if (elem.detachEvent) {
    elem.detachEvent('on' + type, fn);
    return;
    }
    if (elem.removeEventListener) {
    elem.removeEventListener(type, fn, false);
    }
    }

    你可以这样使用:

    var myIntro = document.getElementById('intro');
    addEvent(myIntro, 'click', function () {
    alert('YOU CLICKED ME!!!');
    });

    注意到我们传入了一个匿名函数作为第三个参数,JavaScript运行我们定义和执行匿名函数,这种匿名函数特别适合作为参数传递,实际上我们也可以传递有名的函数(代码如下),但是你们函数更容易做。

    如果你只想在第一次click的时候触发一个函数,你可以这么做:

    // 注意:前提是我们已经定于好了addEvent/removeEvent函数
    // (定义好了才能使用哦)

    var myIntro = document.getElementById('intro');
    addEvent(myIntro, 'click', oneClickOnly);

    function oneClickOnly() {
    alert('WOW!');
    removeEvent(myIntro, 'click', oneClickOnly);
    }

    当第一次触发以后,我们就立即删除该句柄,但是有匿名函数的话却很难将自身的引用删除,不过实际上可以通过如下的形式来做(只不过有点麻烦):

    addEvent(myIntro, 'click', function () {
    alert('WOW!');
    removeEvent(myIntro, 'click', arguments.callee);
    });

    这里我们是有了arguments对象的callee属性,arguments对象包含了所有传递进来的参数以及该函数自身(callee),这样我们就可以放心地删除自身的引用了。

    Event对象

    另外一个非常重要的内容是Event对象,当事件发生的时候出发某个函数,该Event对象将自动在函数内可用,该对象包含了很多事件触发时候的信 息,但IE却没有这么实现,而是自己实现的,IE浏览器是通过全局对象window下的event属性来包含这些信息,虽然不是大问题,但我们也需要注意 一下,下面的代码是兼容性的:

    function myEventHandler(e) {

    // 注意参数e
    // 该函数调用的时候e是event对象(W3C实现)

    // 兼容IE的代码
    e = e || window.event;

    // 现在e就可以兼容各种浏览器了

    }

    // 这里可以自由地绑定事件了

    这里判断e对象(Event对象)是否存在我们使用了OR操作符:如果e不存在(为null, undefined,0等)的时候,将window.event赋值给e,否则的话继续使用e。通过这方式很快就能在多浏览器里得到真正的Event对象,如果你不喜欢这种方式的话,你可以使用if语句来处理:

    if (!e) {
    e = window.event;
    } // 没有else语句,因为e在其它浏览器已经定义了

    另外Event对象下的命令和属性都很有用,遗憾的是不不能全兼容浏览器,例如当你想取消默认的行为的时候你可以使用Event对象里的preventDefault()方法,但IE里不得不使用对象的returnValue属性值来控制,兼容代码如下:

    function myEventHandler(e) {
    e = e || window.event;
    // 防止默认行为
    if (e.preventDefault) {
    e.preventDefault();
    } else {
    e.returnValue = false;
    }
    }

    例如,当你点击一个连接的时候,默认行为是导航到href里定义的地址,但有时候你想禁用这个默认行为,通过returnValue和preventDefault就可以实现,Event对象里的很多属性在浏览器里都不兼容,所以很多时候需要处理这些兼容性代码。

    注意:现在很多JS类库都已经封装好了e.preventDefault代码,也就是说在IE里可用了,但是原理上依然是使用returnValue来实现的。

  • 相关阅读:
    P1309 瑞士轮 (吸氧了)
    P1158 导弹拦截
    腾讯笔试题 构造回文(LCS问题)
    蓝桥杯之大臣的旅费(两次dfs)
    蓝桥杯之买不到的数目(数学公式或缩小范围+暴力)
    蓝桥杯之翻硬币(思维,找规律,贪心)
    蓝桥杯之 连号区间数(巧妙遍历)
    蓝桥杯之剪格子(经典dfs)
    蓝桥杯之带分数(全排列+暴力)
    面试题之O(n)内旋转字符串
  • 原文地址:https://www.cnblogs.com/weilantiankong/p/4538839.html
Copyright © 2011-2022 走看看