Perhaps this is a misconception of mine, but I thought that when you create a custom event, and later create "elements with event listeners" (listening for that event), that the event (itself) keeps track of all the listeners who are waiting for the event to occur and that when the event occurs all listeners are automatically notified.
However, in all the examples I've seen, it looks like the notification-process is very explicit (not very automatic); you have to manually code the dispatching of the event to each listening element via:
elementName.dispatchEvent(eventName);
For example, I just wrote this test-code to:
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);
Obviously, I expected the last line of the code above to only make the last div's background color red, but I'm not aware of a method (without creating a loop) to dispatch to all listeners.
However, before trying this experiment, I assumed there would be some method of the event object that would dispatch the event to all subscribed listeners (and make all DIVs red). I thought that was the main purpose of the addEventListener method: to create some type of "behind the scenes list" of all the elements to be notified when an event occurs.
Do you really have to manually dispatch to each element that is listening?
A custom event is dispatched to the listeners of a specific target object. It is not dispatched to all listeners of that event no matter which object the event is dispatched to or which object is being listened to? It basically works exactly like a 'click' event works. The event is dispatched only to a specific object and only the listeners for that event attached to that specific object.
If you want a global event and global listeners like you seem to want, then you can create a single known object, have everyone listen to events on that object and then dispatch the event to that object. Then, everyone will get notified of the event.
You may find it easier to just use an eventEmitter object like this.
But, if all you want to do is to change some attribute of a bunch of div
objects, then I'd suggest you just put a common class name on them and use document.querySelectorAll()
to retrieve all the target elements and then run some code on them. I don't see any particular reason here for custom event listeners as they don't really do what you're doing.
You could use something like this:
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;
});
Or a version that works on a style setting without a callback function:
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");