具有不同触发器元素和侦听器元素的自定义事件

时间:2018-01-31 10:22:14

标签: javascript javascript-events



var event = new CustomEvent("custom-event", {bubbles:true, detail:"something"});
var eleA = document.getElementById("A");
var eleB = document.getElementById("B");
eleB.addEventListener("custom-event", function(e) {
    console.log("custom-event caught in element B", e.detail);
});
document.addEventListener("custom-event", function(e) {
    console.log("custom-event caught in document", e.detail);
});
eleA.dispatchEvent(event);

<html>
<body>
<div id="A">A</div>
<div id="B">B</div>
</body>
</html>
&#13;
&#13;
&#13;

我搜索过去的问题,但找不到答案。我有一个触发自定义事件的元素A,并希望另一个元素B接收事件并对其进行操作。例如:

var event = new CustomEvent("new-event");
var eleA = document.querySelector("#A");
eleA.dispatchEvent(event);

//...
// somewhere else
...
var eleB = document.querySelector("#B");
eleB.addEventListener("new-event", function(e) {
   console.log('heard');
});

我发现事件未被触发。我尝试添加:

var event = new CustomEvent("new-event", {bubbles:true});

但没有区别,但是,如果我将侦听器更改为如下所示:

document.addEventListener("new-event", function(e) {
   console.log('heard in document');
});

是否因为某些传播问题?难道我不能用一种或多种特定元素来听它吗?

1 个答案:

答案 0 :(得分:1)

您对使用dispatchEvent功能感到困惑。

.dispatchEvent()

  

在指定的EventTarget上调度Event,以适当的顺序调用受影响的EventListeners。正常的事件处理规则(包括捕获和可选的冒泡阶段)也适用于使用dispatchEvent()手动调度的事件。

  

将自定义事件分派给特定目标对象的侦听器。无论调度事件的哪个对象或正在侦听哪个对象,都不会向该事件的所有侦听器调度它?它基本上就像“点击”事件一样有效。该事件仅分派给特定对象,并且仅将该事件的侦听器附加到该特定对象。 Reference

将使用元素的上下文调度事件,并且侦听该特定事件的每个元素都将收到通知。所以,你没有附上

通知将通过addEventListener()函数中使用的回调来接收。

此代码段显示了elementA,elementB和文档如何监听相同的new-event事件:

var event = new CustomEvent("new-event");
var eleA = document.querySelector("#A");

eleA.addEventListener("new-event", function(e) {
  console.log('new-event from Element A');
});

eleA.dispatchEvent(event);

var eleB = document.querySelector("#B");
eleB.addEventListener("new-event", function(e) {
  console.log('new-event from Element B');
});

eleB.dispatchEvent(event);

document.addEventListener("new-event", function(e) {
  console.log('heard in document');
});

document.dispatchEvent(event);
<span id='A'></span>
<span id='B'></span>

此代码段显示了元素如何监听自己的事件:

var event = new CustomEvent("new-event");
var eleA = document.querySelector("#A");

eleA.addEventListener("new-event", function(e) {
  console.log('new-event from Element A');
});

var eventB = new CustomEvent("new-eventB");
var eleB = document.querySelector("#B");
eleB.addEventListener("new-eventB", function(e) {
  console.log('new-event from Element B');
});

var eventDoc = new CustomEvent("new-eventDoc");
document.addEventListener("new-eventDoc", function(e) {
  console.log('heard in document');
});

eleA.dispatchEvent(event);
eleB.dispatchEvent(eventB);
document.dispatchEvent(eventDoc);
<span id='A'></span>
<span id='B'></span>

您可以创建一个SharedResource对象,以便将事件通知给特定的接收者。

此代码段显示了如何:

  • eleA通知eleBdocument
  • eleC通知eleB

//This Object represents a shared result among receivers.
var SharedResource = function(event) {
  this.event = event;
  this.receivers = [];

  this.addReceiver = function(receiver) {
    this.receivers.push(receiver);
  }

  this.addReceivers = function(receivers) {
    this.receivers.push.apply(this.receivers, receivers);
  }

  //This function will loop over receivers array to call the current event.
  this.notify = function() {
    var $self = this;
    this.receivers.forEach(function(receiver) {
      receiver.dispatchEvent(new CustomEvent($self.event));
    });
  }
};

//Element A will send a "broadcast" message to eleB and Document.
var eleA = document.querySelector("#A");
eleA.addEventListener("click", function(e) {
  ABDocSharedResource.notify();
});

var eleB = document.querySelector("#B");
eleB.addEventListener("new-event", function(e) {
  console.log('new-event from Element B');
});

document.addEventListener("new-event", function(e) {
  console.log('new-event from Document');
});

var ABDocSharedResource = new SharedResource('new-event');
ABDocSharedResource.addReceivers([eleB, document]);

//Element C will send a "broadcast" message to eleB.
var CBSharedResource = new SharedResource('new-event');
CBSharedResource.addReceiver(eleB);

var eleC = document.querySelector("#C");
eleC.addEventListener("click", function(e) {
  CBSharedResource.notify();
});
<a href="#" id='A'>Click me! (A) - Broadcast to B and Document</a>
<br>
<a href="#" id='C'>Click me! (C) - Broadcast to B</a>


<span id='B'></span>