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 相关文章推荐
为radio类型的INPUT添加客户端脚本(附加实现JS来禁用onClick事件思路代码)
Nov 11 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
Nov 19 Javascript
js取得html iframe中的元素和变量值
Jun 30 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
Jul 04 Javascript
jQuery实现仿美橙互联两级导航菜单的方法
Mar 09 Javascript
javascript中返回顶部按钮的实现
May 05 Javascript
jQuery网页选项卡插件rTabs用法实例分析
Aug 26 Javascript
AngularJS实践之使用ng-repeat中$index的注意点
Dec 22 Javascript
js addDqmForPP给标签内属性值加上双引号的函数
Dec 24 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
Mar 14 Javascript
Vue指令的钩子函数使用方法
Mar 20 Javascript
JavaScript嵌入百度地图API的最详细方法
Apr 16 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 创建标签云函数代码
2010/05/26 PHP
PHP开发需要注意的安全问题
2010/09/01 PHP
浅谈PHP中的面向对象OOP中的魔术方法
2017/06/12 PHP
使用YII2框架实现微信公众号中表单提交功能
2017/09/04 PHP
10个基于浏览器的JavaScript调试工具分享
2013/02/07 Javascript
jQuery中对未来的元素绑定事件用bind、live or on
2014/04/17 Javascript
js动态添加表格数据使用insertRow和insertCell实现
2014/05/22 Javascript
Javascript中的默认参数详解
2014/10/22 Javascript
详解jquery中$.ajax方法提交表单
2014/11/03 Javascript
node.js中的fs.symlinkSync方法使用说明
2014/12/15 Javascript
jquery移动点击的项目到列表最顶端的方法
2015/06/24 Javascript
jquery合并表格中相同文本的相邻单元格
2015/07/17 Javascript
JavaScript iframe数据共享接口实现方法
2016/01/06 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
如何判断Javascript对象是否存在的简单实例
2016/05/18 Javascript
微信小程序(应用号)简单实例应用及实例详解
2016/09/26 Javascript
JavaScript中的工厂函数(推荐)
2017/03/08 Javascript
Vue.js学习记录之在元素与template中使用v-if指令实例
2017/06/27 Javascript
老生常谈js数据类型
2017/08/03 Javascript
详解为Bootstrap Modal添加拖拽的方法
2018/01/05 Javascript
JavaScript实现shuffle数组洗牌操作示例
2019/01/03 Javascript
python计数排序和基数排序算法实例
2014/04/25 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
Python配置虚拟环境图文步骤
2019/05/20 Python
Pycharm 2020最新永久激活码(附最新激活码和插件)
2020/09/17 Python
spyder 在控制台(console)执行python文件,debug python程序方式
2020/04/20 Python
CSS实现进度条和订单进度条的示例
2020/11/05 HTML / CSS
卡西欧B级产品官方网站:Casio Outlet
2018/05/22 全球购物
CheapTickets香港机票预订网站:CheapTickets.hk
2019/06/26 全球购物
Muziker英国:中欧最大的音乐家商店
2020/02/05 全球购物
外贸业务员工作职责
2014/01/06 职场文书
护士思想汇报
2014/01/12 职场文书
2014年入党积极分子党课学习心得体会模板
2014/04/03 职场文书
大型会议策划方案
2014/05/17 职场文书
八年级作文之友谊
2019/12/02 职场文书
Go语言读取txt文档的操作方法
2022/01/22 Golang