javascript实现简单的on事件绑定


Posted in Javascript onAugust 23, 2016

实现一个简单的on和off方法

介绍:

Event对象:

   funcList: {}, //保存delegate所绑定的方法  
   ieFuncList :{} //保存ie下的绑定方法

Event 对象中的 on, off 方法,主要调用
Event.addEvent, Event.delegateHandle这两个方法

   Event.addEvent: 调用底层的addEventListener添加监听事件
   Event.delegateHandle: 当发生事件之后,随着事件的冒泡上升,判断存在事件委托的元素,并执行对应的回调函数

addEvent / offEvent:

    obj.addEventListener(type, fn, false);
    obj.removeEventListener(type, fn, false);

代码-Event.js

/**
 * addEvent
 * author laynezhou@tencent.com
 */
window.Event = {};
var Event = {

  funcList: {}, //保存delegate所绑定的方法  
  ieFuncList: {}, //由于保存在ie下绑定的方法


  on: function(obj, selector, type, fn) {
    if (!obj || !selector) return false;
    var fnNew = Event.delegateHandle(obj, selector, fn);
    Event.addEvent(obj, type, fnNew);
    /* 将绑定的方法存入Event.funcList,以便之后解绑操作 */
    if (!Event.funcList[selector]) {
      Event.funcList[selector] = {};
    }
    if (!Event.funcList[selector][type]) {
      Event.funcList[selector][type] = {};
    }

    Event.funcList[selector][type][fn] = fnNew;
  },

  off: function(obj, selector, type, fn) {
    if (!obj || !selector || !Event.funcList[selector]) {
      return false;
    }
    var fnNew = Event.funcList[selector][type][fn];
    if (!fnNew) {
      return;
    }

    Event.offEvent(obj, type, fnNew);
    Event.funcList[selector][type][fn] = null;
  },

  delegateHandle: function(obj, selector, fn) {
    /* 实现delegate 的转换方法,事件冒泡上升时, 符合条件时才会执行回调函数 */
    var func = function(event) {
      var event = event || window.event;
      var target = event.srcElement || event.target;
      var parent = target;

      function contain(item, elmName) {
        if (elmName.split('#')[1]) { //by id
          if (item.id && item.id === elmName.split('#')[1]) {
            return true;
          }
        }
        if (elmName.split('.')[1]) { //by class
          if (hasClass(item, elmName.split('.')[1])) {
            return true;
          }
        }
        if (item.tagName == elmName.toUpperCase()) {
          return true; //by tagname
        }
        return false;
      }
      while (parent) {
        /* 如果触发的元素,属于(selector)元素的子级。 */
        if (obj == parent) {
          return false; //触发元素是自己
        }
        if (contain(parent, selector)) {

          fn.call(obj, event);
          return;
        }
        parent = parent.parentNode;
      }
    };
    return func;
  },
  addEvent: function(target, type, fn) {
    if (!target) return false;
    var add = function(obj) {
      if (obj.addEventListener) {

        obj.addEventListener(type, fn, false);

      } else {
        // for ie
        if (!Event.ieFuncList[obj]) Event.ieFuncList[obj] = {};
        if (!Event.ieFuncList[obj][type]) Event.ieFuncList[obj][type] = {};
        Event.ieFuncList[obj][type][fn] = function() {
          fn.apply(obj, arguments);
        };
        obj.attachEvent("on" + type, Event.ieFuncList[obj][type][fn]);
      }
    }
    if (target.length >= 0 && target !== window && !target.tagName) {
      for (var i = 0, l = target.length; i < l; i++) {
        add(target[i])
      }
    } else {
      add(target);
    }
  },


  offEvent: function(target, type, fn) {
    if (!target) return false;
    var remove = function(obj) {
      if (obj.addEventListener) {
        obj.removeEventListener(type, fn, false);

      } else {
        //for ie
        if (!Event.ieFuncList[obj] || !Event.ieFuncList[obj][type] || !Event.ieFuncList[obj][type][fn]) {
          return;
        }
        obj.detachEvent("on" + type, Event.ieFuncList[obj][type][fn], false);
        Event.ieFuncList[obj][type][fn] = {};
      }
    }
    if (target.length >= 0 && target !== window && !target.tagName) {
      for (var i = 0, l = target.length; i < l; i++) {
        remove(target[i])
      }
    } else {
      remove(target);
    }
  },

};

代码-DEMO.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<p>测试 Event </p>
<div id=content>
  <ul>
    <li><button id="btn1">1</button></li>
    <li><button id="btn2">2</button></li>
    <li><button id="btn3">3</button></li>
    <li><button id="btn4">4</button></li>
    <li><button id="btn5">5</button></li>
  </ul>

<button id="unbind">取消绑定</button>
</div>
<p id="text"></p>

<script src="addEvent.js"></script>
<script>
(function(){
  /* 演示demo*/
  var $id=function(id)
  {
    return document.getElementById(id) || id;
  }
  var outer = $id("content"),
    btn = $id("text");
  Event.on(outer,'button',"click",add);
  Event.on(outer,'#unbind',"click",remove);

  //动态添加一个按钮,查看是否有事件响应
  var newbtn = document.createElement("button");
  var node = document.createTextNode("new button");
  newbtn.appendChild(node);
  outer.appendChild(newbtn);

  function add(){
    var e = arguments[0] || window.event;
    var target = e.srcElement || e.target;
    console.log("target:",target);
    btn.innerHTML = target.innerHTML + ' ' + e.type;
  }
  function remove(){
    Event.off(outer,'button',"click",add);
    Event.off(outer,'#unbind',"click",remove);
  }
})();
</script>
</body>
</html>
Javascript 相关文章推荐
javascript 年月日联动实现核心代码
Dec 21 Javascript
IE6下focus与blur错乱的解决方案
Jul 31 Javascript
基于jquery中children()与find()的区别介绍
Apr 26 Javascript
jQuery function的正确书写方法
Aug 02 Javascript
学习javascript面向对象 掌握创建对象的9种方式
Jan 04 Javascript
jquery dialog获取焦点的方法
Feb 09 Javascript
vue单页应用在页面刷新时保留状态数据的方法
Sep 21 Javascript
引入外部js脚本加载慢与页面白屏问题的解决
Dec 10 Javascript
小程序日历控件使用方法详解
Dec 29 Javascript
webpack HappyPack实战详解
Oct 08 Javascript
解决iView Table组件宽度只变大不变小的问题
Nov 13 Javascript
ES2020让代码更优美的运算符 (?.) (??)
Jan 04 Javascript
js实现图片淡入淡出切换简易效果
Aug 22 #Javascript
JS对HTML表格进行增删改操作
Aug 22 #Javascript
AngularJS中$http服务常用的应用及参数
Aug 22 #Javascript
详解AngularJS如何实现跨域请求
Aug 22 #Javascript
深入浅析JS Function()构造函数
Aug 22 #Javascript
深入浅析jQuery对象$.html
Aug 22 #Javascript
基于JavaScript实现添加到购物车效果附源码下载
Aug 22 #Javascript
You might like
在win7中搭建Linux+PHP 开发环境
2014/10/08 PHP
Yii2中事务的使用实例代码详解
2016/09/07 PHP
Laravel5.1 框架Middleware中间件基本用法实例分析
2020/01/04 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
JavaScript 变量命名规则
2009/09/23 Javascript
JavaScript代码编写中各种各样的坑和填坑方法
2014/06/06 Javascript
JavaScript中的Truthy和Falsy介绍
2015/01/01 Javascript
js实现页面跳转的几种方法小结
2016/05/16 Javascript
JS防止网页被嵌入iframe框架的方法分析
2016/09/13 Javascript
express文件上传中间件Multer详解
2016/10/24 Javascript
基于JS实现仿百度百家主页的轮播图效果
2017/03/06 Javascript
Node+Express+MongoDB实现登录注册功能实例
2017/04/23 Javascript
浅谈Node模块系统及其模式
2017/11/17 Javascript
vue 项目中使用Loading组件的示例代码
2018/08/31 Javascript
Vue一个案例引发的递归组件的使用详解
2018/11/15 Javascript
微信小程序:数据存储、传值、取值详解
2019/05/07 Javascript
微信打开网址添加在浏览器中打开提示的办法
2019/05/20 Javascript
element-ui 中使用upload多文件上传只请求一次接口
2019/07/19 Javascript
微信小程序scroll-view锚点链接滚动跳转功能
2019/12/12 Javascript
微信小程序利用云函数获取手机号码
2019/12/17 Javascript
JavaScript函数重载操作实例浅析
2020/05/02 Javascript
jQuery开发仿QQ版音乐播放器
2020/07/10 jQuery
Python 如何访问外围作用域中的变量
2016/09/11 Python
django解决跨域请求的问题
2018/11/11 Python
Python如何实现大型数组运算(使用NumPy)
2020/07/24 Python
CSS3 真的会替代 SCSS 吗
2021/03/09 HTML / CSS
华为慧通面试题
2012/09/11 面试题
销售工作人员的自我评价分享
2013/11/10 职场文书
五星级酒店餐饮部总监的标准岗位职责
2014/02/17 职场文书
《夹竹桃》教学反思
2014/04/20 职场文书
公司证明怎么写
2014/09/22 职场文书
2015年七年级班主任工作总结
2015/05/21 职场文书
2019大学生预备党员转正思想汇报
2019/06/21 职场文书
2019年浪漫婚礼证婚词
2019/06/27 职场文书
导游词之丽江普济寺
2019/10/22 职场文书