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 相关文章推荐
JQuery 常用操作代码
Mar 14 Javascript
js Date概念详细介绍
Nov 22 Javascript
jquery live()重复绑定的解决方法介绍
Jan 03 Javascript
javascript setinterval 的正确语法如何书写
Jun 17 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
Jan 22 Javascript
jQuery中extend()和fn.extend()方法详解
Jun 03 Javascript
js鼠标点击图片切换效果代码分享
Aug 26 Javascript
JS检测移动端横竖屏的代码
May 30 Javascript
基于Node.js的WebSocket通信实现
Mar 11 Javascript
基于vue组件实现猜数字游戏
May 28 Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
May 29 Javascript
JavaScript ES6中的简写语法总结与使用技巧
Dec 30 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脚本数据库功能详解(上)
2006/10/09 PHP
yii2控制器Controller Ajax操作示例
2016/07/23 PHP
php获取微信共享收货地址的方法
2017/12/21 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
微信公众平台开发教程⑥ 微信开发集成类的使用图文详解
2019/04/10 PHP
jquery中push()的用法(数组添加元素)
2014/11/25 Javascript
Javascript实现禁止输入中文或英文的例子
2014/12/09 Javascript
jQuery的text()方法用法分析
2014/12/20 Javascript
js实现获取当前时间是本月第几周的方法
2015/08/11 Javascript
jquery 遍历数组 each 方法详解
2016/05/25 Javascript
javascript事件模型介绍
2016/05/31 Javascript
原生js实现返回顶部缓冲效果
2017/01/18 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
2017/03/19 Javascript
Angularjs使用指令做表单校验的方法
2017/03/31 Javascript
jQuery中的deferred对象和extend方法详解
2017/05/08 jQuery
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
jQuery扇形定时器插件pietimer使用方法详解
2017/07/18 jQuery
3种vue组件的书写形式
2017/11/29 Javascript
单线程JavaScript实现异步过程详解
2020/05/19 Javascript
在vs code 中如何创建一个自己的 Vue 模板代码
2020/11/10 Javascript
python求众数问题实例
2014/09/26 Python
Python函数参数操作详解
2018/08/03 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
Pytorch训练过程出现nan的解决方式
2020/01/02 Python
Pandas读取csv时如何设置列名
2020/06/02 Python
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
健康监测猫砂:Pretty Litter
2017/05/25 全球购物
香港连卡佛百货官网:Lane Crawford
2019/09/04 全球购物
运动会致辞稿50字
2014/02/04 职场文书
读书月活动方案
2014/05/22 职场文书
司机个人年终总结
2015/03/03 职场文书
健康教育主题班会
2015/08/14 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android
python 标准库原理与用法详解之os.path篇
2021/10/24 Python
Spring Boot接口定义和全局异常统一处理
2022/04/20 Java/Android