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

coi*_*iso 39 html javascript dom-events

所以我的困境是我不想两次编写相同的代码.一次为click事件,另一次为touchstart事件.

这是原始代码:

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

document.getElementById('first').addEventListener('click', function(event) {
    do_something(); 
    });
Run Code Online (Sandbox Code Playgroud)

我该怎么压缩这个?有一个更简单的方法!

All*_*uis 80

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

ES6

['click','ontouchstart'].forEach( evt => 
    element.addEventListener(evt, dosomething, false)
);
Run Code Online (Sandbox Code Playgroud)

ES5

['click','ontouchstart'].forEach( function(evt) {
    element.addEventListener(evt, dosomething, false);
});
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用类似以下内容:document.querySelectorAll(selectors).forEach((element)=> {...}); (3认同)
  • 您正在执行alertFunction(),并将其返回值(未定义)分配给事件处理程序。不执行该函数(使用 () ),只需将函数名称/引用传递给 eventListener 函数。请注意,在我的示例中,dosomething 后面没有 ()。 (2认同)

Koo*_*Inc 17

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

// 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);
Run Code Online (Sandbox Code Playgroud)

  • 警告:该事件在句柄函数中不可用。我修复了这个错误 https://pastebin.com/raw/Lrcdv1ws (2认同)

Esa*_*ija 10

您可以定义一个函数并传递它.匿名函数在任何方面都不是特殊的,所有函数都可以作为值传递.

var elem = document.getElementById('first');

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

function handler(event) {
    do_something();
}
Run Code Online (Sandbox Code Playgroud)


Tor*_*ter 10

对于大量事件,这可能会有所帮助:

var element = document.getElementById("myId");
var myEvents = "click touchstart touchend".split(" ");
var handler = function (e) {
    do something
};

for (var i=0, len = myEvents.length; i < len; i++) {
    element.addEventListener(myEvents[i], handler, false);
}
Run Code Online (Sandbox Code Playgroud)

更新06/2017:

现在新的语言功能可以更广泛地使用,您可以简化添加共享一个侦听器的有限事件列表.

const element = document.querySelector("#myId");

function handleEvent(e) {
    // do something
}
// I prefer string.split because it makes editing the event list slightly easier

"click touchstart touchend touchmove".split(" ")
    .map(name => element.addEventListener(name, handleEvent, false));
Run Code Online (Sandbox Code Playgroud)

如果你想处理很多事件并且每个监听器有不同的要求,你也可以传递一个大多数人都会忘记的对象.

const el = document.querySelector("#myId");

const eventHandler = {
    // called for each event on this element
    handleEvent(evt) {
        switch (evt.type) {
            case "click":
            case "touchstart":
                // click and touchstart share click handler
                this.handleClick(e);
                break;
            case "touchend":
                this.handleTouchend(e);
                break;
            default:
                this.handleDefault(e);
        }
    },
    handleClick(e) {
        // do something
    },
    handleTouchend(e) {
        // do something different
    },
    handleDefault(e) {
        console.log("unhandled event: %s", e.type);
    }
}

el.addEventListener(eventHandler);
Run Code Online (Sandbox Code Playgroud)


Mat*_*ens 7

除非您的do_something函数实际上对任何给定的参数执行某些操作,否则您可以将其作为事件处理程序传递.

var first = document.getElementById('first');
first.addEventListener('touchstart', do_something, false);
first.addEventListener('click', do_something, false);
Run Code Online (Sandbox Code Playgroud)

  • 我只是认为可能会有一种更快的方法..类似:(“ touchstart,click”,do_something,false) (2认同)