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 分号引起的一段调试问题
Jun 18 Javascript
JavaScript字符串String和Array操作的有趣方法
Dec 18 Javascript
JavaScript对数组进行随机重排的方法
Jul 22 Javascript
改变checkbox默认选中状态及取值的实现代码
May 26 Javascript
React中ES5与ES6写法的区别总结
Apr 21 Javascript
require.js中的define函数详解
Jul 10 Javascript
详解如何让Express支持async/await
Oct 09 Javascript
jQuery 获取除某指定对象外的其他对象 ( :not() 与.not())
Oct 10 jQuery
JavaScript如何处理移动端拍摄图片旋转问题
Nov 16 Javascript
vue.js 解决v-model让select默认选中不生效的问题
Jul 28 Javascript
使用jQuery实现购物车
Oct 29 jQuery
解决vant框架做H5时踩过的坑(下拉刷新、上拉加载等)
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
set_include_path在win和linux下的区别
2008/01/10 PHP
PHP gbk环境下json_dencode传送来的汉字
2012/11/13 PHP
php对数组排序代码分享
2014/02/24 PHP
Yii核心组件AssetManager原理分析
2014/12/02 PHP
Laravel 添加多语言提示信息的方法
2019/09/29 PHP
CSS3画一个阴阳八卦图
2021/03/09 HTML / CSS
js调用flash的效果代码
2008/04/26 Javascript
JavaScript 空位补零实现代码
2010/02/26 Javascript
Javascript下判断是否为闰年的Datetime包
2010/10/26 Javascript
web基于浏览器的本地存储方法应用
2012/11/27 Javascript
js 判断js函数、变量是否存在的简单示例代码
2014/03/04 Javascript
JavaScript中的document.referrer在各种浏览器测试结果
2014/07/18 Javascript
JS选项卡动态替换banner图片路径的方法
2015/05/11 Javascript
jquery实现点击向下展开菜单项(伸缩导航)效果
2015/08/22 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
基于javascript实现随机颜色变化效果
2016/01/14 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
全面解析Bootstrap表单样式的使用
2016/09/09 Javascript
js滚轮事件兼容性问题需要注意哪些
2016/11/15 Javascript
微信小程序开发之录音机 音频播放 动画实例 (真机可用)
2016/12/08 Javascript
Angularjs中三种数据的绑定策略(“@”,“=”,“&amp;”)
2016/12/23 Javascript
基于JavaScript实现带缩略图的轮播效果
2017/01/12 Javascript
bootstrap IE8 兼容性处理
2017/03/22 Javascript
如何在Angular应用中创建包含组件方法示例
2019/03/23 Javascript
npm的lock机制解析
2019/06/20 Javascript
解决vue做详情页跳转的时候使用created方法 数据不会更新问题
2020/07/24 Javascript
python实现unicode转中文及转换默认编码的方法
2017/04/29 Python
python 调试冷知识(小结)
2019/11/11 Python
英国No.1文具和办公用品在线:Euroffice
2016/09/21 全球购物
Nordgreen手表德国官方网站:丹麦极简主义手表
2019/10/31 全球购物
函授生自我鉴定
2014/03/25 职场文书
小学数学课题方案
2014/06/15 职场文书
优秀本科毕业生自荐信
2014/07/04 职场文书
教师党员整改措施
2014/10/24 职场文书
为什么中国式养孩子很累?
2019/08/07 职场文书
基于flask实现五子棋小游戏
2021/05/25 Python