【问题标题】:dispatchEvent to all listenersdispatchEvent 到所有监听器
【发布时间】:2015-09-05 22:59:58
【问题描述】:

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

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

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 方法的主要目的:为事件发生时要通知的所有元素创建某种类型的“幕后列表”。

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

【问题讨论】:

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


    【解决方案1】:

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

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

    您可能会发现只使用像 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");
    

    【讨论】:

    • 添加了一个使用通用类名和querySelectorAll()的代码示例。
    • 谢谢。我知道如何通过 css、html 和 js 自动化手动通知。我最感兴趣的是你所说的关于在全球范围内使一堆不同的元素都可以同时得到通知的部分。我制作的代码只是实现这一点的测试代码,然后我会将这个概念实现到我制作的一些模块中。
    • 关键是,有时,当一条数据发生变化时,由于该事件,需要更新多个内容。我可以单独使用函数来实现这一点,但我正在尝试看看事件是否会更优雅。
    • @LonnieBest - 你可以创建一个单独的&lt;div&gt; 元素,你甚至可以不放入 DOM 中。在该元素上注册所有事件侦听器,然后将事件分派给它。然后将调用所有事件侦听器,因为它们都附加到同一个对象。然后,您必须跟踪您希望每个事件侦听器执行的操作(例如修改其他一些 DOM 元素)。但是,我个人只是使​​用 eventEmitter 对象而不是自定义事件 hack。
    • @LonnieBest - 你当然可以用事件来做这一切,只是不要使用内置的自定义事件方案,因为它不像你那样工作。您只需创建自己的事件方案,按照您尝试使其工作的方式工作。
    猜你喜欢
    • 2014-12-12
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2015-03-09
    • 2017-06-02
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多