dispatchEvent发送给所有监听器



也许这是我的一个误解,但我认为,当您创建自定义事件,然后创建"具有事件侦听器的元素"(侦听该事件)时,事件(本身)会跟踪等待事件发生的所有侦听器,并且当事件发生时,所有侦听器都会自动收到通知。

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

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方法的主要目的:创建某种类型的"幕后列表",其中包含在事件发生时要通知的所有元素。

您真的必须手动分派到每个正在侦听的元素吗?

将自定义事件分派给特定目标对象的侦听器。它不会被分派给该事件的所有监听器,无论该事件被分派给哪个对象或哪个对象正在被监听?它的工作原理与"点击"事件的工作原理完全相同。事件只分配给特定对象,并且只有该事件的侦听器附加到该特定对象。

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

你可能会发现像这样使用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");

相关内容

  • 没有找到相关文章