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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11845678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:20:38  来源:igfitidea点击:

adding multiple event listeners to one element

javascripthtmldom-events

提问by coiso

So my dilemma is that I don't want to write the same code twice. Once for the click event and another for the touchstartevent.

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

Here is the original code:

这是原始代码:

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

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

How can I compact this? There HAS to be a simpler way!

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

采纳答案by KooiInc

Maybe you can use a helper function like this:

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

// 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);

回答by Allan Nienhuis

I know this is an old question, but I thought some might find this approach useful; it could be applied to any similarly repetitive code:

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

ES6

ES6

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

ES5

ES5

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

回答by Esailija

You can just define a function and pass it. Anonymous functions are not special in any way, all functions can be passed around as values.

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

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

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

function handler(event) {
    do_something();
}

回答by Torsten Walter

For large numbers of events this might help:

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

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);
}

Update 06/2017:

06/2017 更新:

Now that new language features are more widely available you could simplify adding a limited list of events that share one listener.

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

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));

If you want to handle lots of events and have different requirements per listener you can also pass an objectwhich most people tend to forget.

如果您想处理大量事件并且对每个侦听器有不同的要求,您还可以传递一个大多数人往往会忘记的对象

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);

Update 05/2019:

05/2019 更新:

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

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

Object.keys(eventHandler.handlers)
    .map(eventName => el.addEventListener(eventName, eventHandler))

回答by Mattias Buelens

Unless your do_somethingfunction actually does something with any given arguments, you can just pass it as the event handler.

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

var first = document.getElementById('first');
first.addEventListener('touchstart', do_something, false);
first.addEventListener('click', do_something, false);

回答by Armin

Simplest solution for me was passing the code into a separate function and then calling that function in an event listener, works like a charm.

对我来说最简单的解决方案是将代码传递到一个单独的函数中,然后在事件侦听器中调用该函数,就像一个魅力。

function somefunction() { ..code goes here ..}

variable.addEventListener('keyup', function() {
   somefunction(); // calling function on keyup event
})

variable.addEventListener('keydown', function() {
   somefunction(); //calling function on keydown event
})

回答by Strauss Bornman

I have a small solution that attaches to the prototype

我有一个附加到原型的小解决方案

  EventTarget.prototype.addEventListeners = function(type, listener, options,extra) {
  let arr = type;
  if(typeof type == 'string'){
    let sp = type.split(/[\s,;]+/);
    arr = sp;   
  }
  for(let a of arr){
    this.addEventListener(a,listener,options,extra);
  }
};

Allows you to give it a string or Array. The string can be separated with a space(' '), a comma(',') OR a Semicolon(';')

允许你给它一个字符串或数组。字符串可以用空格(' ')、逗号(',')或分号(';')分隔

回答by Ian Pollak

I just made this function (intentionally minified):

我刚刚做了这个功能(故意缩小):

((i,e,f)=>e.forEach(o=>i.addEventListener(o,f)))(element, events, handler)

Usage:

用法:

((i,e,f)=>e.forEach(o=>i.addEventListener(o,f)))(element, ['click', 'touchstart'], (event) => {
    // function body
});

The difference compared to other approaches is that the handling function is defined only once and then passed to every addEventListener.

与其他方法相比的不同之处在于处理函数只定义一次,然后传递给 every addEventListener

EDIT:

编辑:

Adding a non-minified version to make it more comprehensible. The minified version was meant just to be copy-pasted and used.

添加非缩小版本以使其更易于理解。缩小版本只是为了复制粘贴和使用。

((element, event_names, handler) => {

    event_names.forEach( (event_name) => {
        element.addEventListener(event_name, handler)
    })

})(element, ['click', 'touchstart'], (event) => {

    // function body

});

回答by John Balvin Arias

document.getElementById('first').addEventListener('touchstart',myFunction);

document.getElementById('first').addEventListener('click',myFunction);
    
function myFunction(e){
  e.preventDefault();e.stopPropagation()
  do_something();
}    

You should be using e.stopPropagation()because if not, your function will fired twice on mobile

您应该使用,e.stopPropagation()因为如果没有,您的功能将在移动设备上触发两次

回答by Luis Febro

This is my solution in which I deal with multiple events in my workflow.

这是我在工作流程中处理多个事件的解决方案。

let h2 = document.querySelector("h2");

function addMultipleEvents(eventsArray, targetElem, handler) {
        eventsArray.map(function(event) {
            targetElem.addEventListener(event, handler, false);
        }
    );
}
let counter = 0;
function countP() {
    counter++;
    h2.innerHTML = counter;
}

// magic starts over here...
addMultipleEvents(['click', 'mouseleave', 'mouseenter'], h2, countP);
<h1>MULTI EVENTS DEMO - If you click, move away or enter the mouse on the number, it counts...</h1>

<h2 style="text-align:center; font: bold 3em comic; cursor: pointer">0</h2>