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 相关文章推荐
js几个不错的函数 $$()
Oct 09 Javascript
js常用排序实现代码
Dec 28 Javascript
jquery通过ajax加载一段文本内容的方法
Jan 15 Javascript
浅谈angularJS 作用域
Jul 05 Javascript
《JavaScript函数式编程》读后感
Aug 07 Javascript
jquery实现初次打开有动画效果的网页TAB切换代码
Sep 06 Javascript
js查看一个函数的执行时间实例代码
Sep 12 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
Jul 18 Javascript
10个在JavaScript开发中常遇到的BUG
Dec 18 Javascript
vue中的$emit 与$on父子组件与兄弟组件的之间通信方式
May 13 Javascript
基于vue-router 多级路由redirect 重定向的问题
Sep 03 Javascript
vue-cli4使用全局less文件中的变量配置操作
Oct 21 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 字符截取 解决中文的截取问题,不用mb系列
2009/09/29 PHP
PHP中$this和$that指针使用实例
2015/01/06 PHP
Codeigniter中集成smarty和adodb的方法
2016/03/04 PHP
javascript中利用数组实现的循环队列代码
2010/01/24 Javascript
两种简单实现菜单高亮显示的JS类代码
2010/06/27 Javascript
js导出table数据到excel即导出为EXCEL文档的方法
2013/10/10 Javascript
不同Jquery版本引发的问题解决
2013/10/14 Javascript
JS实现仿Windows经典风格的选项卡Tab切换代码
2015/10/20 Javascript
jQuery实现带有动画效果的回到顶部和底部代码
2015/11/04 Javascript
bootstrap制作jsp页面(根据值让table显示选中)
2017/01/05 Javascript
详解Angular.js中$http拦截器的介绍及使用
2017/07/04 Javascript
JavaScript canvas实现围绕旋转动画
2017/11/18 Javascript
jQuery图片查看插件Magnify开发详解
2017/12/25 jQuery
seajs下require书写约定实例分析
2018/05/16 Javascript
vue组件实现可搜索下拉框扩展
2020/10/23 Javascript
JavaScript插入排序算法原理与实现方法示例
2018/08/06 Javascript
js实现3D旋转效果
2020/08/18 Javascript
python获取当前运行函数名称的方法实例代码
2017/04/06 Python
python实现图片处理和特征提取详解
2017/11/13 Python
浅谈python中字典append 到list 后值的改变问题
2018/05/04 Python
pandas.dataframe中根据条件获取元素所在的位置方法(索引)
2018/06/07 Python
使用 Django Highcharts 实现数据可视化过程解析
2019/07/31 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
python 检查数据中是否有缺失值,删除缺失值的方式
2019/12/02 Python
Python OrderedDict字典排序方法详解
2020/05/21 Python
整理HTML5的一些新特性与Canvas的常用属性
2016/01/29 HTML / CSS
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
德国珠宝和手表在线商店:VALMANO
2019/03/24 全球购物
输入N,打印N*N矩阵
2012/02/20 面试题
求职信模版
2013/11/30 职场文书
个人求职信范文
2014/05/24 职场文书
商业街策划方案
2014/05/31 职场文书
专项法律服务方案
2014/06/11 职场文书
《自己去吧》教学反思
2016/02/16 职场文书
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android
如何用H5实现好玩的2048小游戏
2022/07/23 HTML / CSS