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 相关文章推荐
javascript中常用编程知识
Apr 08 Javascript
jquery单选框radio绑定click事件实现方法
Jan 14 Javascript
JS模拟实现Select效果代码
Sep 24 Javascript
js操作数据库实现注册和登陆的简单实例
May 26 Javascript
全面解析Bootstrap中transition、affix的使用方法
May 30 Javascript
Angular多选、全选、批量选择操作实例代码
Mar 10 Javascript
jQuery plugin animsition使用小结
Sep 14 jQuery
微信小程序实现下拉菜单切换效果
Mar 30 Javascript
浅谈在Vue.js中如何实现时间转换指令
Jan 06 Javascript
Vue3.0数据响应式原理详解
Oct 09 Javascript
bootstrap-table后端分页功能完整实例
Jun 01 Javascript
移动端JS实现拖拽两种方法解析
Oct 12 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和js如何通过json互相传递数据相关问题探讨
2013/02/26 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
用JavaScript脚本实现Web页面信息交互
2006/12/21 Javascript
JS中动态添加事件(绑定事件)的代码
2011/01/09 Javascript
学习javascript,实现插入排序实现代码
2011/07/31 Javascript
firebug的一个有趣现象介绍
2011/11/30 Javascript
js禁止页面刷新禁止用F5键刷新禁止右键的示例代码
2013/09/23 Javascript
JS常用字符串处理方法应用总结
2014/05/22 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
JavaScript对象数组的排序处理方法
2015/10/21 Javascript
使用Javascript写的2048小游戏
2015/11/25 Javascript
利用jQuery插件imgAreaSelect实现获得选择域的图像信息
2016/12/02 Javascript
详解jQuery中基本的动画方法
2016/12/14 Javascript
JS随机排序数组实现方法分析
2017/10/11 Javascript
详解Vue源码中一些util函数
2019/04/24 Javascript
微信小程序绘制图片发送朋友圈
2019/07/25 Javascript
jQuery+PHP+Ajax实现动态数字统计展示功能
2019/12/25 jQuery
浅谈element中InfiniteScroll按需引入的一点注意事项
2020/06/05 Javascript
JavaScript如何判断对象有某属性
2020/07/03 Javascript
Python实现二维有序数组查找的方法
2016/04/27 Python
Python如何判断数独是否合法
2016/09/08 Python
Python之Scrapy爬虫框架安装及简单使用详解
2017/12/22 Python
Python 多维List创建的问题小结
2019/01/18 Python
Python 解码Base64 得到码流格式文本实例
2020/01/09 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
2020/03/09 Python
Keras模型转成tensorflow的.pb操作
2020/07/06 Python
利用CSS3伪元素实现逐渐发光的方格边框
2017/05/07 HTML / CSS
HTML5图片预览实例分享
2014/06/04 HTML / CSS
瑞士设计师家具和家居饰品网上商店:Bruno Wickart
2019/03/18 全球购物
波兰在线儿童和婴儿用品零售商:pinkorblue
2019/06/29 全球购物
PHP开发工程师面试问题集锦
2012/11/01 面试题
幼儿园教学随笔感言
2014/02/23 职场文书
学校党的群众路线教育实践活动整改措施
2014/10/25 职场文书
民主生活会主持词
2015/07/01 职场文书
国庆放假通知怎么写
2015/07/30 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书