本质:不同的库或者工具中总是封装了不同的事件绑定形式,但是究其根源,还是IE事件模型和W3C事件模型不同的处理方式

1)W3C事件模型:支持事件捕捉和冒泡 addEventListener('type',function(){},bool) removeEventListener ('type',function(){},bool)

2)IE事件模型:仅支持事件冒泡 attachEvent('type',function(){}); detachEvent('type',fucntion(){});

*如何统一:设置W3C事件绑定函数的第三个参数为false,那么就不支持事件捕捉了。

*原生的绑定形式:

obj.addEventListener('type',function(){},false);

obj.attachEvent('type',function(){});

*是否有注意的:

当然有,IE对同一个事件绑定2次会重复绑定2次,但是W3C只会绑定一次,会忽略后面的一个事件。这个要特别注意,特别是在开发的时候

我记得我在使用百度tangram的处理问题的时候,还碰到了,后面我们来分析tangram的事件绑定形式。

*是否有解决方案:

当然有,对对象绑定以class的形式就可以解决。不会重复绑定事件了。实现方式也是多种多样。

现在来看看一些框架中的事件绑定处理:

1)tangram:

 
baidu.event.on = function (element, type, listener) {
    type = type.replace(/^on/i, '');
    element = baidu.dom._g(element);
 
    var realListener = function (ev) {
            // 1. 这里不支持EventArgument,  原因是跨frame的事件挂载
            // 2. element是为了修正this
            listener.call(element, ev);
        },
        lis = baidu.event._listeners,
        filter = baidu.event._eventFilter,
        afterFilter,
        realType = type;
    type = type.toLowerCase();
    // filter过滤
    if(filter && filter[type]){
        afterFilter = filter[type](element, type, realListener);
        realType = afterFilter.type;
        realListener = afterFilter.listener;
    }
    
    // 事件监听器挂载
    if (element.addEventListener) {
        element.addEventListener(realType, realListener, false);
    } else if (element.attachEvent) {
        element.attachEvent('on' + realType, realListener);
    }
  
    // 将监听器存储到数组中
    lis[lis.length] = [element, type, listener, realListener, realType];
    return element;
};
 
baidu.event.un = function (element, type, listener) {
    element = baidu.dom._g(element);
    type = type.replace(/^on/i, '').toLowerCase();
    
    var lis = baidu.event._listeners, 
        len = lis.length,
        isRemoveAll = !listener,
        item,
        realType, realListener;
    
    //如果将listener的结构改成json
    //可以节省掉这个循环,优化性能
    //但是由于un的使用频率并不高,同时在listener不多的时候
    //遍历数组的性能消耗不会对代码产生影响
    //暂不考虑此优化
    while (len--) {
        item = lis[len];
        
        // listener存在时,移除element的所有以listener监听的type类型事件
        // listener不存在时,移除element的所有type类型事件
        if (item[1] === type
            && item[0] === element
            && (isRemoveAll || item[2] === listener)) {
            realType = item[4];
            realListener = item[3];
            if (element.removeEventListener) {
                element.removeEventListener(realType, realListener, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + realType, realListener);
            }
            lis.splice(len, 1);
        }
    }
    
    return element;

};

可以看出tangram不过是变了一个绑定的方式,其本质还是一样的。

2)jquery

// Only use addEventListener/attachEvent if the special events handler returns false

if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
// Bind the global event handler to the element
  if ( elem.addEventListener ) {
  elem.addEventListener( type, eventHandle, false );
  } else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, eventHandle );
  }

  }

可以看出也是对是否支持 addEventListener和attachEvent  按后进行绑定处理的。

3) prototype

function observe(element, eventName, handler) {

    element = $(element);
 
    var responder = _createResponder(element, eventName, handler);
 
    if (!responder) return element;
 
    if (eventName.include(':')) {
      if (element.addEventListener)
        element.addEventListener("dataavailable", responder, false);
      else {
        element.attachEvent("ondataavailable", responder);
        element.attachEvent("onlosecapture", responder);
      }
    } else {
      var actualEventName = _getDOMEventName(eventName);
 
      if (element.addEventListener)
        element.addEventListener(actualEventName, responder, false);
      else
        element.attachEvent("on" + actualEventName, responder);
    }
 
    return element;
  }
 

可以看出也是对IE和W3C支持的事件模型进行处理的。不过是处理的函数,方式不同而已。

javascript绑定事件的更多相关文章

  1. JavaScript绑定事件的方法[3种]

    在JavaScript中,有三种常用的绑定事件的方法: 在DOM元素中直接绑定: 在JavaScript代码中绑定: 绑定事件监听函数. 一. 在DOM元素中直接绑定 这里的DOM元素,可以理解为HT ...

  2. Javascript绑定事件的两种方式的区别

    命名函数 <input type="button" onclick="check()" id="btn"/> <scrip ...

  3. day51—JavaScript绑定事件

    转换学开发,代码100天——2018-05-06 今天学习JavaScript的绑定事件.因为浏览器的原因绑定事件需要考虑兼容性问题. attachEvent     IE浏览器 ,ie9以上事件执行 ...

  4. javascript绑定事件addEventListener与attachEvent

    1.eleObj.addEventListener(eventName,handle,useCapture); eleObj:DOM元素: eventName:事件名称.注意,这里的事件名称没有“ o ...

  5. JavaScript 绑定事件时传递数据

    var data = { name: 'Ruchee', email: 'my@ruchee.com' }; data.handleEvent = function (e) { console.log ...

  6. javaScript绑定事件委托 demo

    事件绑定通常发生在 onload 或 DOMContentReady , 事件绑定占用 处理时间 占用内存, 而且不是每个事件都会被 点击执行. 由此 事件委托 可以优化事件绑定行为.. 事件逐层冒泡 ...

  7. JavaScript中事件绑定的方法总结

    最近收集了一些关于JavaScript绑定事件的方法,汇总了一下,不全面,但是,希望便于以后自己查看. JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScr ...

  8. JavaScript中绑定事件监听函数的通用方法addEvent() 和 事件绑定之bindEvent()与 unBindEvent()函数

    下面绑定事件的代码,进行了兼容性处理,能够被所有浏览器支持: function addEvent(obj,type,handle){ try{ // Chrome.FireFox.Opera.Safa ...

  9. javascript对象事件绑定方法

    javascript对象事件绑定方法 今天在做对象事件绑定的过程中出现了一点异外情况,由于事件方法是由参数传过来的,需要将当前对象call过去,方便方法体里直接调用this 错误写法 obj.oncl ...

随机推荐

  1. MYSQL 错误日志

    背景知识 : 就算我们不配置mysql的错误文件,它也会有一个默认的,在data文件夹下保存(.err文件) 还好这个文件保存在哪我们还是可以配置的 配置方法: log-err=E:\DB\mysql ...

  2. 在 Windows Azure 虚拟机中使用 Microsoft SQL Server 安全功能

    编辑人员注释:本文章由 SQL Server 团队高级项目经理 Sung Hsueh 撰写. SQL Server 的最新用法之一是利用 Microsoft 的 Windows Azure 基础结构服 ...

  3. MyEclipse修改

    MyEclipse设置编码方式 http://www.cnblogs.com/susuyu/archive/2012/06/27/2566062.html Eclipse添加Spket插件实现ExtJ ...

  4. Java 覆盖测试工具 :EclEmma

    http://www.eclemma.org/installation.html#manual EclEmma 2.2.1 Java Code Coverage for Eclipse Overvie ...

  5. javascript抽象工厂模式

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

  6. zyUpload界面绝佳、体验超棒的HTML5上传插件

    一.为毛线开发它 经过了两个星期做出了两个基于HTML5的多文件上传插件,之前在做网站的时候用到文件上传这一个功能,但是大多说都是基于Flash的,正好最近HTML5很火,而且渐渐壮大起来,感觉搞前端 ...

  7. Mac 域名解析

    1. 域名解析 如,解析 www.baidu.com 在终端输入, host www.baidu.com 题外话: 转载自:http://hoarn.blog.51cto.com/1642678/14 ...

  8. Node.cloneNode()方法

    概述 返回调用该方法的节点的一个副本. 语法 var dupNode = node.cloneNode(deep);node将要被克隆的节点dupNode克隆生成的副本节点deep 可选是否采用深度克 ...

  9. 链表的实现 -- 数据结构与算法的javascript描述 第六章

    链表 链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链 结构示意图 : 链表头需要我们标识 head { element:head,next:obj1 ...

  10. Matlab中边缘提取方法简析

    1.Matlab简述 Matlab是国际上最流行的科学与工程计算的软件工具,它起源于矩阵运算,已经发展成一种高度集成的计算机语言.有人称它为“第四代”计算机语言,它提供了强大的科学运算.灵活的程序设计 ...