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.
Related
Is there a possibility to programmatically call the mousemove event in jQuery?
Obviously, I'm not going to change the actual position of the cursor - it's impossible. All I want is re-call this event so all other scripts that have attached their handers to it will also be called.
To trigger event handlers bound to the mousemove event you can use trigger()
$('#elementID').on('mousemove', function() {
// do stuff
});
$('#elementID').trigger('mousemove'); // triggers above event handler
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
Say I have an button with an id:
<input id='someButton' />
I want to attach an event listener on this button:
$('#form').on('click', '#someButton', function() {
alert("My listener called");
});
However, unbeknownst to me, someone previously wrote an event listener for this very same button:
$('#form').on('click', '#someButton', function() {
alert("Some other listener called");
});
I encountered some code that effectively does the same thing as above, and it seems like the first listener registered is the one that is used. Am I correct in assuming jQuery will always call the first event listener registered on a specific id (and only that listener)?
Incorrect. jQuery will call ALL event listeners bound to an element, in the order they were bound.
To remove an existing event handler, use .off():
$('#form').off('click'); // click event handler(s) removed
$('#form').off(); // all event handler(s) removed
Be aware that events delegated from ancestor DOM elements won't be removed this way, though.
you could use mousedown:
$('#form').on('mousedown', '#someButton', function() {
alert("My listener called");
});
Hope this help.
We have a Web system that uses a combination of OnBlur and OnMouseDown events. Unfortunately, for a strange reason the OnMouseDown event handler is being triggered before calling the OnBlur event handler.
This is not what we want. Instead, we want to always call the OnBlur event handler prior to calling the onMouseDown event handler. Is there a way to do so, perhaps giving the onBlur a higher priority?
Previously, instead of using the onMouseDown event handler we had the onclick event. However, this posed a number of problems especially due to the single-threaded nature of JavaScript.
Catch event #2, fire event #1. Then let event #2 go through.
.. Catch-and-release pattern :)
You'll have to fake it by using a status variable. It's a bit dirty, but it works: the meat of doImportantStuff will only be run once.
var importantStuffDone = false;
function doImportantStuff(){
if(!importantStuffDone){
// Do something important
importantStuffDone = true;
}
}
function doOnBlur(){
// This function gets bound to the blur event
doImportantStuff();
// Do other blur stuff
}
function doOnMouseDown(){
// This function gets bound to the mousedown event
doImportantStuff();
// Do other mousedown stuff
}
I have setup onclick event handler in the following manner:
element.onclick = function() { /*code */ }
Imagine there are event handlers setup using jQuery method bind() or similar handlers.
$('element').bind('click', function(){/*another function*/})
How can I prevent invoking handler defined with jQuery from the handler I have described in the beginning?
NB stopPropagation() and etc. jQuery's methods doesn't work from that function, because it is passed with native event object.
I'm not 100% sure what you're asking but maybe this will help:
You can create a new event object (compliant with W3C DOM) via jQuery's exposed Event constructor:
For example:
element.onclick = function(e) {
var aBetterEventObject = jQuery.Event(e);
// Now you can do what you want: (Cross-browser)
aBetterEventObject.preventDefault()
aBetterEventObject.isDefaultPrevented()
aBetterEventObject.stopPropagation()
aBetterEventObject.isPropagationStopped()
aBetterEventObject.stopImmediatePropagation()
aBetterEventObject.isImmediatePropagationStopped()
}
EDIT: Reading through your question again, I don't think propagation is the problem - you seem to want to cancel an event handler from running within an event handler - I'm not sure this is possible. You could just unbind all handlers (jQuery(elem).unbind('click')) but I don't think that's what you're after...
try to add the following line in the jQuery event handler:
return false;
Following on from JimmyP's answer. I've tried this
$('#x').click( function(e){
alert('hello');
});
document.getElementById('x').onclick = function(){
$('#x').unbind('click');
alert("goodbye");
}
The jQuery event runs once in this example. I don't think you can rely on the order of handlers being invoked however you define them, so I guess you'll have to accept that the jQuery event might fire once. Adding the onclick first does prevent the jQuery event from firing at all but, as I said, I don't think that's reliable.
Jquery has a method for namespacing events. http://docs.jquery.com/Namespaced_Events
You can add, trigger and remove separate functions bound to the same event via namespaces:
$("a").bind("click.custom1",function(){ ... });
$("a").bind("click.custom2",function(){ ... });
$("a").trigger("click.custom2");
$("a").unbind("click.custom2");
As long as you unbind the namespaced event your normal onclick should be unaffected. You may have to bind two separate namespaces to the click event as above if that doesn't work.