向一个元素添加多个事件监听器

新手上路,请多包涵

所以我的困境是我不想两次编写相同的代码。一次用于点击事件,另一次用于 touchstart 事件。

这是原始代码:

 document.getElementById('first').addEventListener('touchstart', function(event) {
    do_something();
    });

document.getElementById('first').addEventListener('click', function(event) {
    do_something();
    });

我怎样才能压缩这个?必须有一个更简单的方法!

原文由 coiso 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 603
2 个回答

也许你可以使用这样的辅助函数:

 // events and args should be of type Array
function addMultipleListeners(element,events,handler,useCapture,args){
  if (!(events instanceof Array)){
    throw 'addMultipleListeners: '+
          'please supply an array of eventstrings '+
          '(like ["click","mouseover"])';
  }
  //create a wrapper to be able to use additional arguments
  var handlerFn = function(e){
    handler.apply(this, args && args instanceof Array ? args : []);
  }
  for (var i=0;i<events.length;i+=1){
    element.addEventListener(events[i],handlerFn,useCapture);
  }
}

function handler(e) {
  // do things
};

// usage
addMultipleListeners(
    document.getElementById('first'),
    ['touchstart','click'],
    handler,
    false);

[ 编辑十一月。 2020 ] 这个答案已经很老了。我现在解决这个问题的方法是使用 actions 对象,其中为每个事件类型指定处理程序,一个 data-attribute 用于指示应该对其执行哪个操作的元素和一个通用文档宽处理程序方法(所以 事件委托)。

 const firstElemHandler = (elem, evt) =>
  elem.textContent = `You ${evt.type === "click" ? "clicked" : "touched"}!`;
const actions = {
  click: {
    firstElemHandler,
  },
  touchstart: {
    firstElemHandler,
  },
  mouseover: {
    firstElemHandler: elem => elem.textContent = "Now ... click me!",
    outerHandling: elem => {
      console.clear();
      console.log(`Hi from outerHandling, handle time ${
        new Date().toLocaleTimeString()}`);
    },
  }
};

Object.keys(actions).forEach(key => document.addEventListener(key, handle));

function handle(evt) {
  const origin = evt.target.closest("[data-action]");
  return origin &&
    actions[evt.type] &&
    actions[evt.type][origin.dataset.action] &&
    actions[evt.type][origin.dataset.action](origin, evt) ||
    true;
}
 [data-action]:hover {
  cursor: pointer;
}
 <div data-action="outerHandling">
  <div id="first" data-action="firstElemHandler">
    <b>Hover, click or tap</b>
  </div>
  this is handled too (on mouse over)
</div>

原文由 KooiInc 发布,翻译遵循 CC BY-SA 4.0 许可协议

我认为有些人可能会发现这种方法很有用;它可以应用于任何类似的重复代码:

ES6

 ['click','ontouchstart'].forEach( evt =>
    element.addEventListener(evt, dosomething, false)
);

ES5

 ['click','ontouchstart'].forEach( function(evt) {
    element.addEventListener(evt, dosomething, false);
});

原文由 Allan Nienhuis 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题