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 相关文章推荐
document.all还是document.getElementsByName?
Jul 21 Javascript
JS中处理与当前时间间隔的函数代码
May 23 Javascript
Jquery UI震动效果实现原理及步骤
Feb 04 Javascript
JS修改iframe页面背景颜色的方法
Apr 01 Javascript
jquery对dom节点的操作【推荐】
Apr 15 Javascript
Javascript将数字转化成为货币格式字符串
Jun 22 Javascript
javascript动画之磁性吸附效果篇
Dec 09 Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
Feb 11 Javascript
angular+bootstrap的双向数据绑定实例
Mar 03 Javascript
gulp教程_从入门到项目中快速上手使用方法
Sep 14 Javascript
jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法分析
Mar 06 jQuery
Vue路由切换页面不更新问题解决方案
Jul 10 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面向对象——访问修饰符介绍
2012/11/08 PHP
php上传大文件设置方法
2016/04/14 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
PHP实现发送微博消息功能完整示例
2019/12/04 PHP
Laravel服务容器绑定的几种方法总结
2020/06/14 PHP
PHP实现页面静态化深入讲解
2021/03/04 PHP
Extjs在exlipse中设置自动提示的方法
2010/04/07 Javascript
jquery 使用简明教程
2014/03/05 Javascript
Javascript基础知识(一)核心基础语法与事件模型
2014/09/29 Javascript
node.js中的console.assert方法使用说明
2014/12/10 Javascript
jquery移动点击的项目到列表最顶端的方法
2015/06/24 Javascript
jQuery实现悬浮在右上角的网页客服效果代码
2015/10/24 Javascript
轻量级jQuery插件slideBox实现带底栏轮播(焦点图)代码
2016/03/28 Javascript
bootstrap监听滚动实现头部跟随滚动
2016/11/08 Javascript
jquery实现点击页面回到顶部
2016/11/23 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
jquery ajax异步提交表单数据的方法
2017/10/27 jQuery
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
2018/05/09 jQuery
15分钟深入了解JS继承分类、原理与用法
2019/01/19 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
javascript中call,apply,callee,caller用法实例分析
2019/07/24 Javascript
微信小程序模板消息限制实现无限制主动推送的示例代码
2019/08/27 Javascript
使用Karma做vue组件单元测试的实现
2020/01/16 Javascript
写给新手同学的vuex快速上手指北小结
2020/04/14 Javascript
[01:46]TI4西雅图DOTA2前线报道 中国选手抱团调时差
2014/07/08 DOTA
Python最长公共子串算法实例
2015/03/07 Python
使用CodeMirror实现Python3在线编辑器的示例代码
2019/01/14 Python
Python 基于jwt实现认证机制流程解析
2020/06/22 Python
英国设计师泳装、沙滩装和比基尼在线精品店:Beach Cafe
2019/08/28 全球购物
写好求职信第一句话的技巧
2013/10/26 职场文书
记帐员岗位责任制
2014/02/08 职场文书
网站推广策划方案
2014/06/04 职场文书
班训口号大全
2014/06/18 职场文书
爱国教育主题班会
2015/08/14 职场文书
关于使用Redisson订阅数问题
2022/01/18 Redis
关于的python五子棋的算法
2022/05/02 Python