如何为addEventListener创建一个与removeEventListener一起使用的包装器函数?

时间:2015-03-05 19:18:45

标签: javascript javascript-events callback event-handling addeventlistener

我想为addEventListener创建一个包装函数,我可以这样调用:

aEvt('click', document, function (evt, target) {
  //Code here
});

我想这样做是因为它允许我始终将事件目标从一开始就作为参数使用 我试过这样一个函数,但问题是,为了让它与removeEventListener(或我类似的rEvt函数)一起工作,我必须从aEvt函数返回一个回调函数,将其传递给removeEventListener作为回调。

我目前拥有的aEvt功能如下:

function aEvt(evt, elem, fn) {
  'use strict';

  var callback = function (evt) {
    fn(evt, evt && evt.target ? evt.target : window.event.srcElement);
  };

  if (elem.addEventListener) {
    elem.addEventListener(evt, callback);
  } else if (elem.attachEvent) {
    elem.attachEvent('on' + evt, callback);
  } else {
    elem['on' + evt] = callback;
  }

  return callback;
}

我有什么方法可以更改aEvt函数,以便我可以将目标发送到传递给aEvt函数的回调(即fn),但也有我发送给aEvt函数的回调是我发送给我想写的类似rEvt函数的回调吗?
换句话说,我应该如何更改aEvt以进行以下工作?

var callbackFn = function (evt, target) { console.log(target); };
aEvt('click', document, callbackFn);
rEvt('click', document, callbackFn);

谢谢。

1 个答案:

答案 0 :(得分:0)

Felix Kling,非常感谢您在评论中链接的SO帖子中的答案。

我把你做了什么并稍微修改为1)遵循我组织中设置的JS代码标准,2)使它成为我可以将事件目标作为处理程序回调中的参数。 将目标作为参数可用,使我在大多数用例中处理事件变得更加容易,并且极大地减少了所需的重构量。

无论如何,这里是最终代码(请注意each中的remove函数执行一个简单的for循环,函数中的return false实际上打破了循环) :

var evts = (function () {
  'use strict';

  var listeners = [],
    add,
    remove;

  add = function (evt, elem, fn) {
    var callback = function (evt) {
      fn(evt, evt && evt.target ? evt.target : window.event.srcElement);
    };

    listeners.push({
      evt: evt,
      elem: elem,
      fn: fn,
      callback: callback,
      removed: false
    });

    if (elem.addEventListener) {
      elem.addEventListener(evt, callback);
    } else if (elem.attachEvent) {
      elem.attachEvent('on' + evt, callback);
    } else {
      elem['on' + evt] = callback;
    }
  };

  remove = function (evt, elem, fn) {
    var callback;

    each(listeners, function (evtObj) {
      if (evtObj.evt === evt && evtObj.elem === elem && 
          evtObj.fn === fn && !evtObj.removed) {
        evtObj.removed = true;
        callback = evtObj.callback;
        return false;
      }
    });

    if (elem.removeEventListener) {
      elem.removeEventListener(evt, callback);
    } else if (elem.detachEvent) {
      elem.detachEvent('on' + evt, callback);
    } else {
      elem['on' + evt] = null;
    }
  };

  return {
    add: add,
    remove: remove
  };
}());

这是使用这些方法的一个例子:

var callback = function (evt, target) {
  console.log(target);
};
evts.add('click', document, callback);
evts.remove('click', document, callback);