首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将多个事件侦听器添加到一个元素

将多个事件侦听器添加到一个元素
EN

Stack Overflow用户
提问于 2012-08-07 20:11:06
回答 15查看 161.9K关注 0票数 76

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

以下是原始代码:

代码语言:javascript
运行
复制
document.getElementById('first').addEventListener('touchstart', function(event) {
    do_something();
    });

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

我如何压缩它?必须有一种更简单的方法!

EN

回答 15

Stack Overflow用户

回答已采纳

发布于 2012-08-07 20:43:32

也许你可以像这样使用一个辅助函数:

代码语言:javascript
运行
复制
// 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);

编辑11月2020这个答案已经很古老了。现在我解决这个问题的方法是使用一个actions对象,其中为每个事件类型指定了处理程序,一个元素的data-attribute指示应该在它上执行哪个操作,以及一个通用的文档范围处理程序方法(所以是event delegation)。

代码语言:javascript
运行
复制
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;
}
代码语言:javascript
运行
复制
[data-action]:hover {
  cursor: pointer;
}
代码语言:javascript
运行
复制
<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>

票数 29
EN

Stack Overflow用户

发布于 2017-03-26 04:00:28

我知道这是一个古老的问题,但我认为有些人可能会发现这种方法很有用;它可以应用于任何类似的重复代码:

ES6

代码语言:javascript
运行
复制
['click','ontouchstart'].forEach( evt => 
    element.addEventListener(evt, dosomething, false)
);

ES5

代码语言:javascript
运行
复制
['click','ontouchstart'].forEach( function(evt) {
    element.addEventListener(evt, dosomething, false);
});
票数 165
EN

Stack Overflow用户

发布于 2012-08-07 20:13:03

您可以只定义一个函数并传递它。匿名函数没有任何特殊之处,所有函数都可以作为值传递。

代码语言:javascript
运行
复制
var elem = document.getElementById('first');

elem.addEventListener('touchstart', handler, false);
elem.addEventListener('click', handler, false);

function handler(event) {
    do_something();
}
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11845678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档