JavaScript 写一个通用的事件侦听器函数

🌙
手机阅读
本文目录结构

问题

写一个通用的事件侦听器函数

答案

/*on:是负责往数组里安排一个队列的,程序池*/
function on (ele, type, fn) {
  if (ele.addEventListener) {
    ele.addEventListener(type, fn);
  } else {
    if (!ele["aEvent" + type]) {
      ele["aEvent" + type] = [];//用了自定义属性,这里不能用全局(污染),不能用局部(off失效)
      //bind3(ele,type,run);//只会执行一次,防止重复绑定;上一次封装的事件库是用bind解决的
      ele.attachEvent("on" + type, function () { run.call(ele) })//放在这里,因为是在if里,所以是有条件执行的,而且这里是只执行一次;防止重复绑定;
    }
    var aryEvent = ele["aEvent" + type];
    for (var i = 0; i < aryEvent.length; i++) {//防止同一个方法被同事件绑定;
      if (aryEvent[i] == fn) return;
    }
    aryEvent.push(fn);
  }
}

/*run:负责具体的执行,在这里把IE兼容性全部解决掉;run方法是由系统的事件来触发的,真正绑定的是run方法;run在on里执行的*/
function run () {//run方法只用在IE678;
  var e = window.event;
  e.target = e.srcElement;
  e.pageX = (document.documentElement.scrollLeft || document.body.scrollLeft) + e.clientX;
  e.pageY = (document.documentElement.scrollTop || document.body.scrollTop) + e.clientY;
  e.stopPropagation = function () { e.cancelBubble = true; }//阻止事件传播;
  e.preventDefault = function () { e.returnValue = false; }//阻止事件默认行为;
  var a = this["aEvent" + e.type];
  for (var i = 0; i < a.length;) {
    /*下面是防止数组塌陷的*/
    if (typeof a[i] == "function") {//这个是和off呼应的,off里有为null的值;
      a[i].call(this, e);//以后给元素写的方法,约定好都要写一个e的参数,这样就不需要再解决IE兼容性了;
      i++;
    } else {
      a.splice(i, 1);
    }
  }
}

function off (ele, type, fn) {
  if (ele.removeEventListener) {
    ele.removeEventListener(type, fn);
  } else {
    var aryEvent = ele["aEvent" + type];
    if (aryEvent && aryEvent.length) {
      for (var i = 0; i < aryEvent.length; i++) {
        if (aryEvent[i] == fn) {
          aryEvent[i] = null;
          return;
        }
      }
    }
  }
}

function bindThis (obj, fn) {
  return function (e) { fn.call(obj, e) }
}

更多面试题

如果你想了解更多的前端面试题,可以查看本站的WEB前端面试题 ,这里基本包涵了市场上的所有前端方面的面试题,也有一些大公司的面试图,可以让你面试更加顺利。

面试题
HTML CSS JavaScript
jQuery Vue.js React
算法 HTTP Babel
BootStrap Electron Gulp
Node.js 前端经验相关 前端综合
Webpack 微信小程序 -

这些题库还在更新中,如果你有不错的面试题库欢迎分享给我,我整理后放上来;人人为我,我为人人,互帮互助,共同提高,祝大家都拿到心仪的Offer!


AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

目前重心已经放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>