有没有办法听多个事件?

时间:2015-12-25 03:50:36

标签: javascript node.js events

例如,我想在所有事件发生时触发回调:

on(['aEvent', 'bEvent', 'cEvent'], callback)

其中回调函数从aEventbEventcEvent获取参数的数组(或可能是对象)。

更新:关于我想要实施的内容。

我正在构建一个向我的用户公开API的警报系统,因此当某些事件发生时,用户可以响应它们。有时用户只有在aEventbEvent都发生时才会回复。这个要求就成了问题。

3 个答案:

答案 0 :(得分:1)

使用ES2015和RxJs.zip

function multiSubscribe(elem, events) {
    return Rx.Observable.zip(...events.map(
        event => Rx.Observable.fromEvent(elem, event)
    )).subscribe(arrayOfEvents => {
        // do whatever
    });
}

答案 1 :(得分:0)

我很难理解这实际上会在现实世界中使用哪些让我不确定我理解你真正想要做什么,但是你可以编写自己的函数来跟踪每个系列的时间事件发生了:

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">

答案 2 :(得分:0)

你可以尝试这个

listAction: 'Home/LocalList'

所有事件都绑定到一个处理程序。这就是处理程序的方式

document.getElementById('mouseenter',master_handler,false)
document.getElementById('mouseout',master_handler,false)
document.getElementById('mouseclick',master_handler,false)