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 克隆数组最简单的方法
Feb 12 Javascript
面向对象的编程思想在javascript中的运用上部
Nov 20 Javascript
js网页中的(运行代码)功能实现思路
Feb 04 Javascript
js判断FCKeditor内容是否为空的两种形式
May 14 Javascript
ext中store.load跟store.reload的区别示例介绍
Jun 17 Javascript
利用原生JS自动生成文章标题树的实例
Aug 22 Javascript
webpack+vue.js实现组件化详解
Oct 12 Javascript
JS实现全屏的四种写法
Dec 30 Javascript
video.js使用改变ui过程
Mar 05 Javascript
基于zepto.js实现登录界面
Oct 09 Javascript
ligerUI---ListBox(列表框可移动的实例)
Nov 28 Javascript
JavaScript实现前端网页版倒计时
Mar 24 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
php笔记之:数据类型与常量的使用分析
2013/05/14 PHP
ThinkPHP模版引擎之变量输出详解
2014/12/05 PHP
jQuery formValidator表单验证插件开源了 含API帮助、源码、示例
2008/08/14 Javascript
javascript在事件监听方面的兼容性小结
2010/04/07 Javascript
基于JavaScript 数据类型之Boolean类型分析介绍
2013/04/19 Javascript
jquery $.fn $.fx是什么意思有什么用
2013/11/04 Javascript
超实用的JavaScript表单代码段
2016/02/26 Javascript
详解JavaScript中的自定义事件编写
2016/05/10 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
jQuery编写设置和获取颜色的插件
2017/01/09 Javascript
原生js实现焦点轮播图效果
2017/01/12 Javascript
Angularjs为ng-click事件传递参数
2017/06/15 Javascript
Angularjs cookie 操作实例详解
2017/09/27 Javascript
jQuery实现动态加载select下拉列表项功能示例
2018/05/31 jQuery
js实现图片推拉门效果代码实例
2019/05/18 Javascript
vue限制输入框只能输入8位整数和2位小数的代码
2019/11/06 Javascript
js实现选项卡效果
2020/03/07 Javascript
Javascript摸拟自由落体与上抛运动原理与实现方法详解
2020/04/08 Javascript
[06:30]DOTA2英雄梦之声_第15期_死亡先知
2014/06/21 DOTA
使用Python的Tornado框架实现一个简单的WebQQ机器人
2015/04/24 Python
Python设置在shell脚本中自动补全功能的方法
2018/06/25 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
Python使用type关键字创建类步骤详解
2019/07/23 Python
拿来就用!Python批量合并PDF的示例代码
2020/08/10 Python
Boda Skins皮衣官网:奢侈皮夹克,全球配送
2016/12/15 全球购物
意大利和国际奢侈品牌购物网站:Suitnegozi.com
2021/01/15 全球购物
PHP面试题集
2016/12/18 面试题
标准毕业生自荐信范文
2013/11/04 职场文书
班长演讲稿范文
2014/04/24 职场文书
十周年庆典策划方案
2014/06/03 职场文书
信息与计算机科学职业规划范文:成为一艘有方向的船
2014/09/11 职场文书
交通事故委托书范本(2篇)
2014/09/21 职场文书
2015年公路路政个人工作总结
2015/07/24 职场文书
红灯733-1型14管5波段半导体收音机
2021/04/22 无线电
MySQL学习之基础操作总结
2022/03/19 MySQL
Li list-style-image 图片垂直居中实现方法
2023/05/21 HTML / CSS