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 相关文章推荐
提高网站信任度的技巧
Oct 17 Javascript
javascript xml为数据源的下拉框控件
Jul 07 Javascript
基于jquery的跟随屏幕滚动代码
Jul 24 Javascript
JavaScript的Number对象的toString()方法
Dec 18 Javascript
基于canvas实现的钟摆效果完整实例
Jan 26 Javascript
详解Angular2中的编程对象Observable
Sep 17 Javascript
JS重载实现方法分析
Dec 16 Javascript
微信小程序-小说阅读小程序实例(demo)
Jan 12 Javascript
浅谈webpack组织模块的原理
Mar 10 Javascript
小程序云开发实战小结
Oct 25 Javascript
基于JavaScript判断两个对象内容是否相等
Jan 10 Javascript
Vue2.0搭建脚手架
Mar 13 Vue.js
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 fckeditor 调用的函数
2009/06/21 PHP
yii2高级应用之自定义组件实现全局使用图片上传功能的方法
2016/10/08 PHP
js滚动条多种样式,推荐
2007/02/05 Javascript
jQuery学习2 选择器的使用说明
2010/02/07 Javascript
制作高质量的JQuery Plugin 插件的方法
2010/04/20 Javascript
javascript获取所有同类checkbox选项(实例代码)
2013/11/07 Javascript
基于编写jQuery的无缝滚动插件
2014/08/02 Javascript
jQuery实现的简洁下拉菜单导航效果代码
2015/08/26 Javascript
浅析Bootstrap组件之面板组件
2016/05/04 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
2016/08/24 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
微信小程序之网络请求简单封装实例详解
2017/06/28 Javascript
使用JS和canvas实现gif动图的停止和播放代码
2017/09/01 Javascript
jQuery完成表单验证的实例代码(纯代码)
2017/09/30 jQuery
详解在React里使用&quot;Vuex&quot;
2018/04/02 Javascript
解决webpack多页面内存溢出的方法示例
2019/10/08 Javascript
vue中keep-alive内置组件缓存的实例代码
2020/04/16 Javascript
详解Python 数据库 (sqlite3)应用
2016/12/07 Python
python实时分析日志的一个小脚本分享
2017/05/07 Python
python3使用pyqt5制作一个超简单浏览器的实例
2017/10/19 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
2018/11/10 Python
python烟花效果的代码实例
2020/02/25 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
详细分析Python垃圾回收机制
2020/07/01 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
html5中localStorage本地存储的简单使用
2017/06/16 HTML / CSS
HTML5之SVG 2D入门8—文档结构及相关元素总结
2013/01/30 HTML / CSS
可靠的数据流传输TCP
2016/03/15 面试题
图书室管理制度
2014/01/19 职场文书
安全责任书怎么写
2014/07/28 职场文书
委托函范文
2015/01/29 职场文书
2015年办公室个人工作总结
2015/04/20 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
2019年手机市场的调研报告2篇
2019/10/10 职场文书
Html5调用企业微信的实现
2021/04/16 HTML / CSS