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 trim函数 去空格函数与正则集锦
Nov 20 Javascript
javascript innerText和innerHtml应用
Jan 28 Javascript
从面试题学习Javascript 面向对象(创建对象)
Mar 30 Javascript
浅析offsetLeft,Left,clientLeft之间的区别
Nov 30 Javascript
jquery.form.js实现将form提交转为ajax方式提交的方法
Apr 07 Javascript
jQuery实现的小图列表,大图展示效果幻灯片示例
Oct 25 Javascript
JS基于面向对象实现的拖拽功能示例
Dec 20 Javascript
nuxt.js 缓存实践
Jun 25 Javascript
vue生命周期与钩子函数简单示例
Mar 13 Javascript
js回溯法计算最佳旅行线路代码实例
Sep 11 Javascript
js判断复选框是否选中的方法示例【基于jQuery】
Oct 10 jQuery
用JS实现选项卡
Mar 23 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
example1.php
2006/10/09 PHP
小偷PHP+Html+缓存
2006/11/25 PHP
详解PHP显示MySQL数据的三种方法
2008/06/05 PHP
创建配置文件 用PHP写出自己的BLOG系统 2
2010/04/12 PHP
PHP编程函数安全篇
2013/01/08 PHP
PHP 图片合成、仿微信群头像的方法示例
2019/10/25 PHP
dojo随手记 gird组件引用
2011/02/24 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
JavaScript中对象介绍
2014/12/31 Javascript
jQuery中extend函数详解
2015/07/13 Javascript
JS实现仿QQ面板的手风琴效果折叠菜单代码
2015/09/11 Javascript
jQuery自定义滚动条完整实例
2016/01/08 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
2017/01/20 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
JS获取数组中出现次数最多及第二多元素的方法
2017/10/27 Javascript
vue中axios的封装问题(简易版拦截,get,post)
2018/06/15 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
亲自动手实现vue日历控件
2019/06/26 Javascript
JS实现求字符串中出现最多次数的字符和次数示例
2019/07/05 Javascript
JS控制只能输入数字并且最多允许小数点两位
2019/11/24 Javascript
webpack打包优化的几个方法总结
2020/02/10 Javascript
vue 需求 data中的数据之间的调用操作
2020/08/05 Javascript
Vuex实现购物车小功能
2020/08/17 Javascript
javascript代码实现简易计算器
2021/01/25 Javascript
深入浅析python中的多进程、多线程、协程
2016/06/22 Python
在pycharm中显示python画的图方法
2019/08/31 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
2021/01/06 Python
python爬取微博评论的实例讲解
2021/01/15 Python
阳光体育活动方案
2014/02/16 职场文书
人力管理专业毕业生求职信
2014/02/27 职场文书
会计求职自荐信
2014/06/20 职场文书
2014镇副书记群众路线专题民主生活会思想汇报
2014/09/23 职场文书
小学入学感言
2015/08/01 职场文书
车辆管理制度范本
2015/08/05 职场文书