dispatchEvent到所有侦听器

时间:2015-09-05 22:59:58

标签: javascript javascript-events event-handling event-listener

也许这是对我的误解,但我认为当你创建一个自定义事件,然后创建“带有事件监听器的元素”(监听该事件)时,事件(本身)会跟踪所有的监听器等待事件发生的人以及事件发生时所有听众都会自动得到通知。

然而,在我看过的所有例子中,看起来通知过程非常明确(不是很自动);您必须通过以下方式手动编码将事件调度到每个侦听元素:

elementName.dispatchEvent(eventName);

例如,我刚刚将此测试代码编写为:

  • 创建基本自定义事件
  • 使用自定义事件的侦听器生成100个div元素
  • 使事件中每个div的背景颜色变为红色 发生

var myEvent = new CustomEvent("redTime", {});
var div;
for(var i=1, iL=101; i < iL; i++)
{
	div = document.createElement('div');
	document.body.appendChild(div);
	div.innerHTML = i;
    div.style.border = "solid 1px #333333";
    div.style.display = "inline-block";
    div.style.margin = "1px";
    div.style.padding = "1px";
	div.addEventListener("redTime", function(e)
	{
		this.style.backgroundColor = "red";
	});
    document.body.appendChild(div);
}
div.dispatchEvent(myEvent);

显然,我预计上面代码的最后一行只会使最后一个div的背景颜色变红,但是我不知道一个方法(没有创建一个循环)来分派给所有的监听器。

但是,在尝试此实验之前,我假设会有一些事件对象的方法将事件分派给所有订阅的侦听器(并使所有DIV变为红色)。我认为这是addEventListener方法的主要目的:创建事件发生时要通知的所有元素的某种类型的“幕后列表”。

你真的必须手动调度到正在收听的每个元素吗?

1 个答案:

答案 0 :(得分:2)

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

如果您想要一个全局事件和您似乎想要的全局侦听器,那么您可以创建一个已知对象,让每个人都听取该对象上的事件,然后将事件分派给该对象。然后,每个人都会收到有关该事件的通知。

您可能会发现使用像this这样的eventEmitter对象更容易。

但是,如果您要做的只是更改一堆div个对象的某些属性,那么我建议您只在其上添加一个公共类名并使用document.querySelectorAll()检索所有目标元素,然后在它们上运行一些代码。我没有在这里看到任何特定的理由让自定义事件听众,因为他们并没有真正做你正在做的事情。

您可以使用以下内容:

function iterateTargets(selector, fn, data) {
    var items = document.querySelectorAll(selector);
    for (var i = 0; i < items.length; i++) {
        fn(items[i], data);
    }
}

iterateTargets(".specials", function(item){
    item.style.backgroundColor = "red;
});

或者适用于没有回调函数的样式设置的版本:

function iterateTargets(selector, fn, data) {
    var items = document.querySelectorAll(selector);
    for (var i = 0; i < items.length; i++) {
        fn(items[i], data);
    }
}

function setStyles(selector, styleName, value) {
    iterateTargets(selector, function(item) {
        item.style[styleName] = value;
    });
}

setStyles(".specials", "backgroundColor", "red");