As mentioned above, the biggest advantage of
.on() is that it only needs to be bound to a single object, which object will be at or near the top bubble layer.
Each layer derives from the context of its declared container.
Since these are not functions, but objects, they are all in the same scope, with differing context. It's a slight different take from scope. Scope is environment related, while context is object related. As we can see, all three levels above exist in the same memory namespace, the same scope.
From your reading you will have learned that a click in the third layer bubbles up to the body layer eventually. Each layer gets a look at the event, and the first handler to be triggered follows up the event with actions. Read up on this aspect to determine if just the one handler executes, or if the event is handled further up the chain, as well.
When we register a binding on a top level parent, none of the children need to be present with the listener is attached. Only the parent needs to be present. The children can stream in afterward and not even be aware that they are the delegated objects of the attached event listener. They can be inserted and removed at will and always be hot spots for the registerd event(s).
When we attach a listener to a selector, such as a click event, That binding is created only on that object, if it exists, and only at load time. If we somehow later insert a new element and want it to have the same event profile we have to attach the listener at the time we create the new object. This gets very messy and uses a tonne of memory.
The usage is case by case. Simple static cases can use simple listeners. More complex cases almost always yearn for delegation as a demand of dynamic DOM insertion and deletion.
Now as to where an event handler is called, more or less relates back to the above. It depends on whether an event is one-off or persistent. If an interaction causes a new element to overlay a section of the page, it may have events associated with it. Depending how frequently, if at all this feature would be called upon might be a determining factor into whether it gets registered at load time, or at event time (opening the overlay).
Memory is always a factor, and lots of registered event bindings uses lots of memory. It may also introduce conflicts, another big picture to study up on. When we register events on elements individually, and those elements happen to be removed, the bindings are still in place, but doing nothing but using space. Therefore our program needs to be aware of these deletions and track down any bindings the elements may have and turn them off. This is the messy part.
Case by case. We can explore any that you may come up with over in the corner bar, if you ever want to.