美文网首页
封装库-事件绑定

封装库-事件绑定

作者: angryyan | 来源:发表于2017-06-13 19:33 被阅读0次

问题所在:

1 支持同一个元素的同一个事件句柄上可以绑定多个坚挺函数;
2 如果在同一个元素的同一个事件句柄上多次注册同一个函数,那么除第一次注册的函数,其余都将被忽略;
3 函数体内的this指向的应当是正在处理事件的节点(IE指向window);
4 监听函数的执行顺序应当是按照绑定的顺序执行;
5 在函数体内不用使用 event = event || window.event,来标准化Event对象。

var btn = document.getElementById("btn"); btn.onclick = function () { alert('我是传统事件绑定'); }
以上代码展示的传统的事件绑定。现代绑定中W3C使用的是:addEventListener和removeEventListener.IE使用的是attachEvent和detachEvent.

    // 跨浏览器添加事件
     function addEvent(obj, type, fn) {
          if (typeof addEventListener != 'undefined')
               {
                 obj.addEventListener(type, fn, false);
                } else if (typeof attachEvent != 'undefined') 
                {
                   obj.attachEvent('on' + type, fn);
                }
           }```
  //跨浏览器删除事件
  function removeEvent(obj, type, fn) {
      if (typeof removeEventListener != 'undefined')
          {
             obj.removeEventListener(type, fn);
          } else if (typeof detachEvent != 'undefined') 
            {
                obj.detachEvent('on' + type, fn);
            }
      }
以上的两个函数解决了:***同时绑定多个函数以及标准化event的问题***。但是*IE多次注册同一函数*,第一个除外的其他函数并未被忽略;IE中监听函数的执行并不是按照绑定的顺序进行执行,而是*倒序执行*。还有一个问题就是IE中*this传递过来的是window*,而不是当前正在运行事件句柄的节点。
为了解决this传递问题,我们需要使用匿名函数+传递参数的方式来解决:
`  obj.addEvent('on' + type,function(){
    fn.call(obj,window.event);
  });`
使用call第一个参数就是获取this,从第二个参数开始,可以通过函数参数获取。故以上代码解决了IE中this指向window的问题,同时可以获取到event对象。
但是这又引入了新的问题:***无法删除事件  无法顺序执行  IE的现代绑定存在内从泄露的问题。***

从上述问题我们可以看到主要问题是在IE的attachEvent上,存在着无法避免地内佛那个泄露问题。所以我们考虑使用传统事件绑定对IE进行封装。
//跨浏览器添加事件绑定
function addEvent(obj, type, fn) {
    if (typeof obj.addEventListener != 'undefined') {
        obj.addEventListener(type, fn, false);
    } else {
          //创建一个可以保存事件的哈希表(散列表)
           if (!obj.events) obj.events = {};
           if (!obj.events[type]) {
                //创建一个可以保存事件处理函数的数组
              obj.events[type] = [];
              //存储第一个事件处理函数
              if (obj['on' + type])  obj.events[type][0] = fn;
            }
            //通过事件计数器来从第二个事件处理函数开始
            obj.events[type][addEvent.ID++] = fn;
             //执行所有事件处理函数
            obj['on' + type] = function () {
            for (var i in obj.events[type]) {
                obj.events[type][i]();
              }
          }
      }
  }

 //每个事件分配一个ID 计数器
 addEvent.ID = 1;
//事件处理函数调用
addEvent.exec = function (event) {
    var e = event || addEvent.fixEvent(window.event);
    var es = this.events[e.type];
    for (var i in es) {
        es[i].call(this, e);
    }
 };

//获取IE 的event,兼容W3C 的调用
addEvent.fixEvent = function (event) {
    event.preventDefault = addEvent.fixEvent.preventDefault;
    event.stopPropagation = addEvent.fixEvent.stopPropagation;
    return event;
};

//兼容IE 和W3C 阻止默认行为
addEvent.fixEvent.preventDefault = function () {
    this.returnValue = false;
};

//兼容IE 和W3C 取消冒泡
addEvent.fixEvent.stopPropagation = function () {
    this.cancelBubble = true;
};

//跨浏览器删除事件
function removeEvent(obj, type, fn) {
    if (typeof obj.removeEventListener != 'undefined') {
        obj.removeEventListener(type, fn, false);
    } else {
        var es = obj.events[type];
        for (var i in es) {
            if (es[i] == fn) {
            delete obj.events[type][i];
            }
        }
     }
  }
以上就是基于原声JS自己封装的事件绑定库。后续的话需要研究下jQuery的源码,看看关于事件绑定这部分的代码。

相关文章

  • 封装库-事件绑定

    问题所在: 1 支持同一个元素的同一个事件句柄上可以绑定多个坚挺函数;2 如果在同一个元素的同一个事件句柄上多次注...

  • 第十一周第一天笔记

    1 事件库的复习及最终版封装 依赖的库:不依赖任何库; 使用方法:为全局函数调用;系统行为事件绑定:on(ele,...

  • jQuery事件机制

    jQuery的事件机制,指的是:jQuery对JavaScript操作DOM事件的封装,包括了:事件绑定、事件解绑...

  • jQuery知识整理

    jQuery jQuery和DOM关系 jquery框架对象分析 加载事件 事件绑定 动画效果 jquery封装的...

  • JS示例35-事件绑定方式二

    一、知识要点 可以重复绑定相同事件,避免事件被覆盖 二、源码参考 封装

  • 6-2 事件-代码演示

    绑定点击事件和取消默认行为 自定义一个绑定事件,封装 点击激活,先显示激活,后显示取消。点击取消,正常显示。事件的...

  • jQuery事件

    jQuery事件是DOM事件的封装,同时支持自定义的扩展。绑定事件:bind、on、live、delegate、k...

  • 封装一个自己的js库

    仿照jQuery封装一个自己的js库 接下来,我讲封装一个仿jQuery的库,主要包含jQuery中绑定,css,...

  • js-day16

    A.我今天学了什么 1.this指向 2.绑定事件封装 3.select

  • 学习笔记:DOM事件中的IE兼容性处理办法

    事件绑定兼容处理封装,由于.attrachEvent()方法中,this指向window,需要作如下处理: 解除事...

网友评论

      本文标题:封装库-事件绑定

      本文链接:https://www.haomeiwen.com/subject/ctqdqxtx.html