javascript 交叉侦听多个事件并触发回调

lc8prwob  于 2023-02-21  发布在  Java
关注(0)|答案(3)|浏览(168)

我有一个需要监听的事件名称列表,存储在一个数组中,如下所示:

var events = ['A', 'B'];

现在,我不确定哪一个事件会先被触发,而且可能会非常不一致(取决于它们等待的HTTP请求),所以我永远不可能只安全地监听其中一个事件。所以,我需要以某种方式“交叉监听”所有事件才能触发我最初的回调。
所以我的想法是这样做:
1.为A创建一个侦听器,这将为B创建一个侦听器。B的侦听器触发回调。
1.为B创建侦听器,这将为A创建侦听器。A的侦听器触发回调。
因此,这将产生4个列表器,如下所示(伪代码):

var callback = function() { console.log('The callback'); };

Event.on('A', function () {
    Event.on('B', callback);
});

Event.on('B', function () {
    Event.on('A', callback);
});

因此,我相信这将解决我的问题(可能还有另一个问题,我没有看到这里虽然)。
问题是,当我只需要监听2个事件时,我可以做到这一点。但是当我有3-4个事件要“交叉监听”时,情况会怎样呢?假设我们有['A', 'B', 'C', 'D']。这显然需要循环遍历这些事件。这部分让我感到困惑,我不确定如何继续。这需要注册一个很好的事件组合。
这需要在JavaScript中完成。
在这种情况下,我的想象力和逻辑是有限的。

kyxcudwk

kyxcudwk1#

我是这么想的:

var callback = function() { console.log('The callback'); };
var events = {
  'click': false,
  'mouseover': false,
  'mouseout': false
};

for(prop in events) {
  $('.evt-button').on(prop, function(evt) {
    if(events[evt.type] === false) {
      console.log('First ' + evt.type + ' event');
      events[evt.type] = true;
      checkAll();
    }
  });
}

function checkAll() {
  var anyFalse = false;
  for(prop in events) {
    if(events.hasOwnProperty(prop)) {
      if(events[prop] === false) {
        anyFalse = true;
        break;
      }
    }
  }
  if(!anyFalse) {
    callback();
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button class="evt-button">The button</button>
zf9nrax1

zf9nrax12#

有很多方法可以完成你的任务,但是为了保持简单,你可以有一个事件名称数组,就像你已经做的那样,只要在它们发生时删除它们,每次都检查数组是否为空。

var events = ['A', 'B'];

var callback = function() { console.log('The callback'); };

var eventOccured = function(eventName) {
    // if the event name is in the array, remove it...
    var idx = events.indexOf(eventName);
    if (idx !== -1) {
        events.splice(events.indexOf(idx), 1);
    }

    // if the event array is empty then we've handled everything...
    calback();
};

Event.on('A', function () {
    // do whatever you need in the event handler
    eventOccured("A");
});

Event.on('B', function () {
    // do whatever you need in the event handler
    eventOccured("B");
});
j7dteeu8

j7dteeu83#

有点晚了,但是你可以做一个函数来 Package 你的回调,并重用它来附加多个eventlistener和计数,直到所有事件都发生为止。这样你也可以添加事件来抵消其他事件,比如keyup取消keydown。

const K = a => _b => a

const makeEventTrigger = (fn) => {
  let lastTarget,
    required = 0,
    active = 0;

  return (enable, qualifier = K(true)) => {
    required = enable ? required + 1 : required;

    return (event) => {
      if(!qualifier(event)) {
        return
      }

      const isLastTarget =
        lastTarget && lastTarget.isEqualNode(event.currentTarget);

      if (!enable) {
        lastTarget = isLastTarget ? null : lastTarget;
        active = Math.max(0, active - 1);
        return;
      }

      if (!isLastTarget) {
        lastTarget = event.currentTarget;
        active = Math.min(required, active + 1);
        return active === required && fn();
      }
    };
  };
};

let changeTitleCol = () =>
  (document.querySelector("h1").style.color =
    "#" + Math.random().toString(16).slice(-6));
let addTriggerForColorChange = makeEventTrigger(changeTitleCol);

let isSpace = e => e.key === " " || e.code === "Space"

document
  .querySelector("button")
  .addEventListener("mousedown", addTriggerForColorChange(true));
document
  .querySelector("button")
  .addEventListener("mouseup", addTriggerForColorChange(false));
document.addEventListener("keydown", addTriggerForColorChange(true, isSpace));
document.addEventListener("keyup", addTriggerForColorChange(false));
<h1>Multiple Event sources!</h1>
<div>
  <button id="trigger-A">klik me and press space</button>
</div>

相关问题