I though it is possible to listen all the events on document but following code is not working. Am I doing anything wrong here?
$(document).on('test', function() {
console.log('document is listening for test event');
});
and then fire test event from an object:
var obj = {};
$(obj).trigger('test'); //nothing happens, why?
Shouldn't above code fire function associated to test event on document?
To start with, what you have isn't event delegation, that's just a regular event binding to the document. In order for an event handler on something - such as the document - to fire, that event has to be triggered on that element - either by triggering it on that element directly or by triggering an event that propagates ("bubbles") up the DOM to that element.
Your example doesn't work because your object obj isn't part of the document, so the test event is never triggered on the document.
This will fire your event:
$(document).trigger('test');
Or any child of document:
$('body').trigger('test');
Your empty object obj is not document or a child of document so will not fire the event bound on document
Related
I'm new to JS, just a dumb question on event listener, I know how to add an event listener, but confused with what really it is, below is some code:
document.getElementById("myBtn").addEventListener("click", function(){
...
});
and I was reading a book which says sth like this:
event in the listing is triggered when the mouse button is clicked on the host element, and the event provides its listeners with ...
so can I say the listener in this case is the button element(with id myBtn)? or listener is a property of button element?
A listener is an event of DOM element, in this case, the click event is an event of your button myBtn that fires when a user makes a click in the primary button.
You can get more info from here
To answer your question in very simple terms:
There are three javascript constructs to look out for in this code
document.getElementById("myBtn").addEventListener("click", function(){ ... });
They are:
the event
The actual event that occurs on the page. This can be triggered by a user, another event, or can be time-triggered.
the event listener
This is an internalised javascript software construct that can be initialized by the programmer to listen for various events that occur on the page.
the event handler
This is a function created by the programmer and passed to the event listener to execute whenever an event occurs i.e. handle the event.
Interestingly, the only thing you can see explicitly in the above code is the event handler - function(){ ... }. Why? Because it is the only thing the programmer explicitly creates in the code.
So, the code can be read as -
get my button with id myBtn.
initialize an Event Listener to listen for click Events on this button and
delegate an anonymous Event Handler to execute when this event occurs.
I'll try to explain my problem. I'm using mouseup event listener so I can check whenever a click is performed and the target is not the desired element. This is the code I'm using:
function clickOutListener(element, callbackFunction){
$(document).mouseup(function(e){
if(!$(element).is(e.target) && $(element).has(e.target).length === 0) callbackFunction.call(this, null);
});
}
As you can see, the event listener is bound to the global document element and the way to unbind the listener would be:
$(document).off("mouseup");
Here comes what I need to achieve. If I unbind mouseup listener it will affect the other elements which use this listener (dropdowns and other features). I must guess that everytime I'm registering a listener it's not overriding the previous defined listener but adding the defined target function.
How can I access the different defined target functions for the same listeners?
$(document).mouseup(funct1);
$(document).mouseup(funct2);
$(document).mouseup(funct3);
How would you unregister the registered listener just for "funct2"?
Thank you in advance.
You can namespace your events when using the .on() syntax.
$(document).on('mouseup.myNamespace', function(e){ ... }
This allows you to remove events by namespace whilst leaving others in place.
$(document).off('mouseup.myNamespace');
I think this is best asked with code:
var event = new CustomEvent("custom", {bubbles: true}); // Create Event
// Create and attach element
var element = document.createElement("div");
document.body.appendChild(element);
element.addEventListener("custom", function(e) {
console.log("listening");
});
// At this point I thought that if the "custom" event were fired that my
// element listing would be triggered with the listener callback.
// But....
document.body.dispatchEvent(event);
// check the console... nothing :(
// the only way I am able to get my element event listener to fire is if
// the element calling the dispatchEvent(event) is the element itself.
element.dispatchEvent(event);
What am I doing wrong? Is this the way events are meant to work?
My question is how do I listen to a custom event when the event is not dispatched
dispatchEvent(event)
from the element containing the listener callback
element.addEventListener("custom", function(){});
You have to dispatch the event on the element that is actually listening for it, or an element lower in the chain if it's supposed to bubble.
You can't listen for the event on a DIV, and then dispatch the event on the BODY tag, and expect it to bubble downwards
element.dispatchEvent(event);
Is the proper way to fire the event, it won't bubble from the body to a child, events only bubble upwards the DOM chain.
I'm studying javascript and jquery am a little confused on the proper definition of an event handler.
So far I've read .on() (for example ) is technically a method but it is handling events. So would .on() be considered an event handler? Or is it an event listener because the function inside of it is the handler?
No. jQuery's on is a method which adds event listeners. It's not an event handler and does not add event handlers.
An event listener is a function that is invoked when a certain kind of event is dispatched on a specific element or one of its descendants.
function eventListener() {
console.log("I'm an event listener");
}
window.addEventListener('load', eventListener);
An event handler is some kind of special event listener:
An element can only have one event handler at a time for each kind of event
It is invoked during the bubble phase, not the capture one.
It can be stored in a raw uncompiled form which, when compiled, will run with a very weird scope.
function eventHandler() {
console.log("I'm an event handler");
}
window.onload = eventHandler;
var eventHandler = 'console.log("I\'m a raw uncompiled event handler");';
document.body.setAttribute('onload', eventHandler);
No, an event handler is what happens when the event fires. The .on() method is the plumbing that wires that up.
So for example, if you have:
function dealWithTheClick(){
alert('Clicked!');
}
$('#someButton').on('click', dealWithTheClick);
The function dealWithTheClick is the event handler, because it's the function that 'handles' the event that was fired when the click occurred.
Why does
$(document).on("keyup blur", "#my_selector", function() {
//DO SOMETHING
});
seems to work, however
$("#my_selector").on("keyup blur", function() {
//DO SOMETHING
});
Doesn't? I put them both in my ready functions, and while the above one works, the lower one doesn't. This is in context of my previous question.
If the #my_selector item is added dynamically (e.g. after an Ajax call finishes) then you may be attaching the direct event handler before the element exists in the DOM. In this case the event handler would be attached to nothing. The first one attaches a delegated event handler so it does not matter when the element appears in the DOM, the event handler would be executed.
$('selector').on('event') works like $.bind.
$(document).on('event', 'selector') works like $.live.
In other words, $('selector').on attaches an event handler to a currently existing node.
If $('#my_selector') is empty at the time of the event handler's creation, the event handler will not be attached to it.
On the other hand $(document) is always available, and you can always attach event handlers to it.
$(document).on('event', 'selector', function() { ... }) attaches an event handler to document and filters it by 'selector'. So this works just like $().live() in previous versions of jQuery, and you should use event binding in this way.