有没有一种方法可以监听多个事件
Is there a way to listen to multiple events?
例如,我想在所有事件发生时触发回调:
on(['aEvent', 'bEvent', 'cEvent'], callback)
其中回调函数从aEvent
、bEvent
和cEvent
获得参数的数组(或者可能是对象)。
更新:关于我想要实现的内容。
我正在构建一个向用户公开API的警报系统,这样当一些事件发生时,用户就可以对它们做出响应。有时,用户希望仅在aEvent
和bEvent
都发生时才进行响应。这个要求就成了问题。
使用ES2015和RxJs.zip
:
function multiSubscribe(elem, events) {
return Rx.Observable.zip(...events.map(
event => Rx.Observable.fromEvent(elem, event)
)).subscribe(arrayOfEvents => {
// do whatever
});
}
我很难理解这在现实世界中什么时候会被实际使用,这让我不确定我是否理解你真正想做什么,但你可以编写自己的函数来跟踪一系列事件中的每一个发生的时间:
function listenMultiple(elem, events, callback) {
var eventList = events.split(" ");
var cnt = 0;
var results = {};
eventList.forEach(function(event) {
function localHandler(e) {
this.removeEventListener(event, localHandler);
results[event] = e;
++cnt;
if (cnt === eventList.length) {
callback(results);
}
}
elem.addEventListener(event, localHandler);
});
}
用法:
listenMultiple(elem, "aEvent bEvent cEvent", function(results) {
// all three events have happened
});
注意:为了避免对给定事件进行多次计数,这将在事件发生时删除侦听器。
对这种情况进行多次响应是复杂的,因为这取决于你希望它如何工作,因为有很多方法可以配置,而你还没有解释你希望如何工作。我能想到的最简单的方法就是在它启动时让它重新初始化。这将等待所有事件发生,然后当发生时,调用相同的函数来重新设置。这将在最后一个事件发生时重新启动所有计数器,因此它将忽略在系列的最后一个发生之前发生的任何其他事件的任何盈余。
function listenMultiple(elem, events, callback) {
var eventList = events.split(" ");
var cnt = 0;
var results = {};
eventList.forEach(function(event) {
function localHandler(e) {
this.removeEventListener(event, localHandler);
results[event] = e;
++cnt;
if (cnt === eventList.length) {
callback(results);
// configure for next sequence
listenMultiple(elem, events, callback);
}
}
elem.addEventListener(event, localHandler);
});
}
编辑
现在,您已经阐明了当各种事件多次出现在其中时您想要什么,这会变得更加复杂,因为您必须为每个事件保持N个状态级别。这里有一个适用于DOM事件的方案(因为这是我测试它的最简单方法),但它肯定可以适用于任何类型的事件:
// pass a list of ids and a list of events and a callback
function listenMultiple(ids, events, callback) {
var eventList = events.split(" ");
var idList = ids.split(" ");
if (idList.length !== eventList.length) {
throw new Error("Number of ids and events must be the same");
}
var eventCntrs = {};
var results = [];
eventList.forEach(function(event, index) {
var key = event + idList[index];
eventCntrs[key] = 0;
function localHandler(e) {
// get our current cnt for this event
var cnt = eventCntrs[key];
log("click on: ", this.id, ", cnt = ", cnt);
// if we don't yet have any results for this cnt,
// then initialize the results object for this cnt
if (!results[cnt]) {
results[cnt] = {_cntr: 0};
}
// save this event object
// and count it
results[cnt][key] = {time: Date.now()};
++results[cnt]._cntr;
// count this event
++eventCntrs[key];
// if this fills out a result set, then fire the callback
if (results[cnt]._cntr === eventList.length) {
callback(results[cnt]);
// clear item saved in results array so it can be garbage collected
delete results[cnt];
}
}
document.getElementById(idList[index]).addEventListener(event, localHandler);
});
}
listenMultiple("test1 test2 test3", "click click click", function(result) {
log("callback: ", result);
})
// diagnostic function for showing results
function log(args) {
var str = "";
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] === "object") {
str += JSON.stringify(arguments[i]);
} else {
str += arguments[i];
}
}
var div = document.createElement("div");
div.innerHTML = str;
var target = log.id ? document.getElementById(log.id) : document.body;
target.appendChild(div);
}
log.id = "output";
#output {
margin-top: 30px;
}
Click any sequence of the three buttons.<br><br>Each time a combination of each one of the three is completed, a result will be output via the callback.<br><br>
<button id="test1">1</button><button id="test2">2</button><button id="test3">3</button>
<div id="output">
您可以像一样尝试
document.getElementById('mouseenter',master_handler,false)
document.getElementById('mouseout',master_handler,false)
document.getElementById('mouseclick',master_handler,false)
所有事件都绑定到一个处理程序。这就是处理程序的
function master_handler(event){
if(event.type=="mouseenter"){
Some something special
}
if(event.type=="mouseout"){
Some something special
}
if(event.type=="click"){
Some something special
}
}
相关文章:
- 如何在AngularJS中监听点击事件,而不是触摸事件
- 监听touchend有时会触发移动点击事件
- jQuery有没有,或者有没有jQuery插件,内置了监听CSS3动画事件的功能(例如animationEnd)
- 如何让Google Maps API v3监听dragend事件并在投递时填充表单字段
- 如何在angular js中监听dom就绪事件
- React鼠标事件在没有监听它们的组件上触发
- 如何在具体化 CSS 中监听<选择>更改事件
- 如何将誓言令牌推送到本地存储或本地会话并监听存储事件?(SoundCloud Php/JS 错误解决方法)
- 有没有办法在 asp.net MVC 3 中使用 JavaScript、Jquery 监听事件
- 一个“;监听路由器”;(响应视图/模型中的路由器事件)
- Javascript jquery创建和监听事件
- 通过JQuery "on"在Dart中监听事件
- 绑定/监听事件
- angular如何在ng样式触发转换的css转换结束时监听事件?
- React-router:从路由器获取参数,监听事件失败
- 这三种监听事件的方式的作用域有何不同
- 如何停止监听事件,直到ajax请求完成
- 监听事件的指令
- 单元测试angularjs指令监听事件
- 在AngularJS中监听事件和操作DOM(编译、链接)的地方