zoukankan      html  css  js  c++  java
  • javascript绑定事件

    本质:不同的库或者工具中总是封装了不同的事件绑定形式,但是究其根源,还是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支持的事件模型进行处理的。不过是处理的函数,方式不同而已。

  • 相关阅读:
    14 微服务电商【黑马乐优商城】:day02-springcloud(理论篇一:HttpClient的简单使用)
    14 微服务电商【黑马乐优商城】:day01-springboot(Thymeleaf快速入门)
    14 微服务电商【黑马乐优商城】:day01-springboot(理论篇)
    1.1 行列式:二阶三阶n阶行列式
    ubuntu:make工程管理器大致了解
    ubuntu:VIM使用
    机器学习:朴素贝叶斯邮件分类(python实现)
    ubuntu 添加快速启动
    ubuntu:软件包
    Ubuntu:远程管理ubuntu文件系统
  • 原文地址:https://www.cnblogs.com/SmallNiu/p/4189288.html
Copyright © 2011-2022 走看看