2012-08-07 148 views
21

所以我的两难是我不想两次写同一个代码。一次用于点击事件,另一次用于事件touchstart将多个事件侦听器添加到一个元素

这里是原代码:

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

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

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

回答

14

也许你可以使用一个辅助功能是这样的:

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

好吧,帮助:)谢谢! – coiso 2012-08-07 12:45:39

+0

警告:该事件在句柄函数中不可用。我修复了这个bug https://pastebin.com/raw/Lrcdv1ws – higimo 2017-06-07 10:58:28

5

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

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

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

function handler(event) { 
    do_something(); 
} 
7

除非你do_something功能实际上不会与任何给定的参数的东西,你可以把它作为事件处理程序。

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

我只是想有可能是一个更快的方法..像: ( 'touchstart,点击' ,do_something,false) – coiso 2012-08-07 12:27:59

+1

@PedroEsperança没有。我同意,能够传递像'['touchstart','click']这样的字符串数组会很好,但是没有这样的事情。 – 2012-08-07 21:45:08

4

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

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

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

如果要处理大量的事件,并且每个听者不同的要求,你也可以pass an object其中大多数人往往忘记。

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

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

ES6

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

ES5

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

但是如何定位特定的选择器? – 2018-02-12 17:25:16

+1

你可以使用类似于: document.querySelectorAll(选择器).forEach((element)=> {...}); – 2018-02-13 18:51:14

相关问题