JS 事件监听兼容处理示例

感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编来看看吧。
在事件监听处理方面,IE提供了attachEvent和detachEvent两个接口,而Firefox提供的是addEventListener和removeEventListener。最简单的兼容性处理就是封装这两套接口: JS代码如下:

/**
 * 事件监听兼容处理
 *
 * @param 
 * @arrange (编程之家) jb51.cc
 **/
function addEvent(elem,eventName,handler) {
  if (elem.attachEvent) {
    elem.attachEvent(on + eventName,handler);
  } else if (elem.addEventListener) {
    elem.addEventListener(eventName,handler,false);
  }
}

function removeEvent(elem,handler) {
  if (elem.detachEvent) {
    elem.detachEvent(on + eventName,handler);
  } else if (elem.removeEventListener) {
    elem.removeEventListener(eventName,false);
  }
}
然而,上面两个函数还没把问题完全解决。Firefox下,事件处理函数中的this指向被监听元素本身,而在IE下则不然。要解决这个问题,我首先想到的是prototype框架中的function.prototype.bind(下面简称bind): JS代码如下:

/**
 * 事件监听兼容处理
 *
 * @param 
 * @arrange (编程之家) jb51.cc
 **/
function addEvent(elem,handler.bind(elem));
  } else if (elem.addEventListener) {
    elem.addEventListener(eventName,false);
  }
}
这样做的结果是,再也无法移除事件处理函数。原因在于,移除事件处理函数时需要传入该函数的引用,而bind方法返回的是一个新函数而不是handler本身,且这个新函数的引用并没有保存下来。既然如此,只要把bind返回的引用给保存下来就好了。而存储结构就是个关键点。

首先,一个页面中有任意个元素,所以每个元素都要有一个集合,每个元素所有事件处理函数的引用就存放在这个集合中。
element.events = { };
其次,一个元素有多种事件(click、mouseover、mouseout等),同一个函数可以添加为多种事件的处理函数,所以每种事件的存储也必须是独立的。
element.events.click = {};
element.events.mouseover = {};
...
最后,为每个事件处理函数添加一个唯一标识,以便在集合找到它。最简单的标识方法是数据库中常用的自动编号(递增)。

结合以上三点,编写一个生成事件代理的函数: JS代码如下:

/**
 * 事件监听兼容处理
 *
 * @param 
 * @arrange (编程之家) jb51.cc
 **/
var eventId = 0;
function delegate(elem,handler) {
  var events = elem.events = elem.events || {},// 创建事件集合
    id = handler.eventId = handler.eventId || ++eventId; // 生成事件标识
  events[eventName] = events[eventName] || {}; // 创建某种事件的集合

  var trueHandler = function(e) { // 真正被添加的事件处理函数
    handler.call(elem,e);
  };

  events[eventName][id] = trueHandler; // 记下函数的引用
}
相对应地,还要写一个获取事件代理的函数: JS代码如下:

/**
 * 事件监听兼容处理
 *
 * @param 
 * @arrange (编程之家) jb51.cc
 **/
function getDelegate(elem,handler) {
  try { return elem.events[eventName][handler.eventId]; } catch (e) {}
}
这里用try...catch的原因是,避免elem.events和elem.events[eventName]未创建时出错。

最后addEvent和removeEvent改进如下: JS代码如下:

/**
 * 事件监听兼容处理
 *
 * @param 
 * @arrange (编程之家) jb51.cc
 **/
function addEvent(elem,handler) {
  handler = delegate(elem,handler);
  if (elem.attachEvent) {
    elem.attachEvent(on + eventName,handler) {
  handler = getDelegate(elem,handler);
  if (elem.detachEvent) {
    elem.detachEvent(on + eventName,false);
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)