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判断浏览器的比较全的代码
Feb 13 Javascript
jQuery创建平滑的页面滚动(顶部或底部)
Feb 26 Javascript
在js文件中写el表达式取不到值的原因及解决方法
Dec 23 Javascript
JavaScript中Date.toSource()方法的使用教程
Jun 12 Javascript
jQuery简单实现仿京东商城的左侧菜单效果代码
Sep 09 Javascript
Form表单按回车自动提交表单的实现方法
Nov 18 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
Dec 21 Javascript
bootstrap treeview 树形菜单带复选框及级联选择功能
Jun 08 Javascript
Vue组件内部实现一个双向数据绑定的实例代码
Apr 04 Javascript
解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
Oct 11 Javascript
layui清除radio的选中状态实例
Nov 14 Javascript
解决vant的Toast组件时提示not defined的问题
Nov 11 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程序员的技术瓶颈分析
2011/07/17 PHP
PHP定时更新程序设计思路分享
2014/06/10 PHP
php生成二维码时出现中文乱码的解决方法
2014/12/18 PHP
学习php设计模式 php实现模板方法模式
2015/12/08 PHP
详谈PHP程序Laravel 5框架的优化技巧
2016/07/18 PHP
Jquery从头学起第四讲 jquery入门教程
2010/08/01 Javascript
js 触发select onchange事件代码
2014/03/20 Javascript
《JavaScript高级编程》学习笔记之object和array引用类型
2015/11/01 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
2016/02/14 Javascript
XML、HTML、CSS与JS的区别整理
2016/02/18 Javascript
BootStrap实用代码片段之一
2016/03/22 Javascript
详谈jQuery中的一些正则匹配表达式
2017/03/08 Javascript
JS数组搜索之折半搜索实现方法分析
2017/03/27 Javascript
js canvas实现QQ拨打电话特效
2017/05/10 Javascript
Angular2使用Angular CLI快速搭建工程(一)
2017/05/21 Javascript
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
解决angular2 获取到的数据无法实时更新的问题
2018/08/31 Javascript
bootstrap自定义样式之bootstrap实现侧边导航栏功能
2018/09/10 Javascript
微信小程序生成海报分享朋友圈的实现方法
2019/05/06 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
vue实现把接口单独存放在一个文件方式
2020/08/13 Javascript
js实现抽奖功能
2020/11/24 Javascript
[48:52]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第一局
2016/02/25 DOTA
[01:09:23]KG vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python字典get()方法用法分析
2015/04/17 Python
使用html5 canvas绘制圆环动效
2019/06/03 HTML / CSS
同程旅游英文网站:LY.com
2018/11/13 全球购物
高中生毕业自我鉴定范文
2013/12/22 职场文书
销售工作岗位职责
2013/12/24 职场文书
西式婚礼证婚词
2014/01/12 职场文书
社区工作者感言
2014/03/02 职场文书
教师党的群众路线教育实践活动个人整改措施
2014/11/04 职场文书
公务员个人总结
2015/02/12 职场文书
公司员工培训管理制度
2015/08/04 职场文书
2019森林防火宣传标语大全!
2019/07/03 职场文书
2019年教师节活动策划方案
2019/09/09 职场文书