Why do you have to pass the event object as a parameter? - javascript

I'm learning how to manipulate events in JavaScript and I'm wondering "why do you have to pass the event object as a parameter (argument) into a function when using event handling?"
Here's an example of what I am talking about:
<script type="text/javascript">
document.getElementById('button_1').onclick = (function (event) {
alert("The event is: " + "on" + event.type);
});
</script>
I wrote the code above and I pretty much understand what it does. I just don't understand the whole (event) passing. I thought of this as a way of assigning an anonymous function to the button_1.onclick event handler. Does the event handler try to pass in an event before it gets assigned or?... I'm having a difficult time understanding this. If someone could please clarify this for me I would be grateful.
[I tried searching it on Google but found very complex explanations and examples. Only a simple-to-intermediate explanation would help.] =)

The Ever-Present Event, Whether You Like it or Not
The event is always present, even when you don't provide a name:
$(".foo").on("click", function(){
alert( arguments[0].type );
});
That is the same as saying this:
$(".foo").on("click", function(event){
alert( event.type );
});
The event object is already being passed to your callback (whether your provide a name for it or not), you can choose to not use it if you like. For instance, if we looked to a jQuery onClick method:
$(".foo").on("click", function(){
/* Do stuff */
});
Making Use of It
You'll note that I have no event object referenced in my callback. I'm not required to. However, if I want to use it, for whatever purpose, I should give it a name:
$(".foo").on("click", function(myEvent){
myEvent.preventDefault();
myEvent.stopPropagation();
});
Now that I have granted myself access to the event details, I can prevent the default behavior that would result from the event, and I can also stop the event from bubbling up the DOM to other elements.
Practical Example
Suppose we wanted to listen for click events on an element:
$("#bigSquare").on("click", function(event){
/* Do something */
});
Click events happen on an element when you click the element itself, or any of its children. Now suppose this element had two children:
<div id="bigSquare">
<div id="redSquare"></div>
<div id="blueSquare"></div>
</div>
Clicking any of these, the big square, the red square, or the blue square will cause the "click" event on the big square - after it causes the click event on whichever element you clicked first (events bubble up the DOM).
We could determine which element was the target in any click event via the event itself:
$("#bigSquare").on("click", function(event){
alert( event.target.id );
});
Note here how we're accessing the ID of the target that raised the event. If you click on the red square, when that event bubbles up to the big square, we will see alerted "redSquare". The same goes for the blue square. If you click that, the event will bubble up to the big square and we will see alerted "blueSquare".
You can test this online via the following demo: http://jsbin.com/ejekim/edit#javascript,live
Try clicking the orange, red, or blue square to see what is alerted.

You are not passing the event parameter anywhere. You are just making a function that takes one parameter, called event.
When the browser calls the event handlers, it calls the function(s) assigned to it, and passes the event object to it as the 1st parameter.
P.S. You don't need the () around your function.
document.getElementById('button_1').onclick = function (event) {
alert("The event is: " + "on" + event.type);
};

You aren't passing an event into the function, you are naming the first parameter passed to your function event.
The browser is the one that is going to call your function and it passes an event object when it calls your function. You can choose not to name that parameter function(){} but the browser is still going to pass the event object in, you can use it or not use it as you see fit.

Simply put, the Event object passed to a handler contains details about the event. For example, a KeyboardEvent contain info about the key pressed, the corresponding character, and any modifier keys (alt, shift, control, meta) that were held down.
Does the event handler try to pass in an event before it gets assigned or?
The handler is your function, so it's the receiver of event, not the passer.
The event handler is bound when you assign it to the element's onclick property (or by calling addEventListener, the modern, preferred method), which is before the handler is invoked.
The Event object is passed when the handler is invoked, which is when the event fires.
So, when a user clicks on your #button_1, this causes a "click" event to fire on the button, which invokes the button's "click" handler, which is passed a MouseEvent.
For more information, read about event-driven programming.

To add to the others answers and comments, your code will not work with IE. For cross-browser capability, you need to test the existence of the first argument:
<body>
<button id="button_1">Click Me!</button>
<script type="text/javascript" >
document.getElementById('button_1').onclick = (
function(event) {
var e = event ? event : window.event;
alert("The event is: " + "on" + e.type);
});
</script>
</body>

Related

Accessing event object in event handler javascript

I have a code snippet
$(document).on("click", "div[data-role=button]", myfunc);
function myfunc(e){
alert(event.target);
alert(e.target);
alert(event.currentTarget);
alert(e.currentTarget);
}
Each of them give different outputs when i click on the
element.
e is of type object
event is oftype MouseEvent
The e.currentTarget seems to give the correct answer.
My question is if i decided to add another parameter to my handler, how will i get to access the "e", parameter which gives the right answer.
EDIT:
I want to do
function myfunc(e,str){
}
How can i access e inside my function and how do i pass the two arguments?
EDIT 2
I found another interesting thing,
this
this correctly gives the target, even though i expected it to give the document any idea why?
You access e the same way you are already doing, I guess what you mean is how to set the handler in the click event. How about like this:
$(document).on("click", "div[data-role=button]", function(e) { myfunc(e, "some string"); });
Of course that doesn't make "some string" very flexible (unless you are rebinding the event when it changes), so it could just as easily be fixed in the myfunc function.
If you want it to be based on something, perhaps an attribute of the element being clicked, then perhaps you want:
$(document).on("click", "div[data-role=button]", function(e) { myfunc(e, $(this).data("string")); });
which will get the value of a data-string attribute, for example:
<div data-role="button" data-string="my string 1"></div>
Inside myFucnc e is a local variable that refers to the event object. event probably refers to a closure or a global variable.
The difference between target vs currentTarget is the following:
Identifies the current target for the event, as the event traverses the DOM. It always refers to the element the event handler has been attached to as opposed to event.target which identifies the element on which the event occurred.
https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget

What happens with the handlers when you change the innerHTML property

Ok lets say I have
<div id="container"/>
and I put a button in this container with id = "button". Then I make .click handler for it
$("#button").click(function() {
foo();
}
Then I change the innerHTML of the div like this:
$("#container").html = "<h1> Foo </h1>";
Then I set timer for let's say 5 seconds that after that will execute the following code :
function(){
$("#container").html = "<button id="button" type="button">Click Meh!</button>"
$("#button").click(function() {
foo();
}
}
My question is: The first button was "destroyed", so was the first .click() handler for it destroyed too? Or the second .click() will just make a second handler for the same button and if I want to have only 1 handler I have to use $("#button").off("click") before calling the second .click() ?
Yes, when you removed the element (by overwriting the html of the element), you've disassosciated the click handler with the element.
Instead, we should just be looking at delegating the event. We target a static parent element (like container), and delegate the event to it:
$('#container').on('click', '#button', foo);
Now when the button is clicked, we'll fire off the foo function. Even if you remove the button and add it later, the event will still be delegated to '#container'.
Yes once you deleted the button the first handler will also destroyed because you are using ".click()" function. You no need to explicitly remove that click handler.
or else use the below ".on" function then you no need to write the function again and again. it will check dynamically adding elements and attach the events.
$( "body" ).on( "click", "#button", function() {
foo();
});
If your question is if you have to re-bind the onclick handlers when the dom changes, the answer is yes.
If you're asking what happens to the handler function, my guess is it will get garbage collected when the node gets deleted, if you want to avoid the creation of several functions, just write the handler as named function, and use that instead of anonymous one..
If you're asking whether the handler will get bound twice: it will get bound to whatever is in the selection result, if the first button exists when you run the .click then it will, though #id only returns 1 node so, it will bind to the first #button it finds, regardless of if it's already bound...

Basic jQuery understanding

What is the event
$(document).ready(function(){
$("a").click(function(event){
alert("Thanks for visiting!");
});
});
and also this one
$(document).ready(function(){
$("a").click(function(){
alert("Thanks for visiting!");
});
});
these two JS blocks are doing the same thing, but one with an event, if someone could explain what is function(event), also I saw something like function(e),function(g), what are those? Is there a tutorial I could learn?
The callback function that you're providing to $("a").click is a function that takes an argument. This argument is an event object containing details about the object. Your function declaration can take this argument with any name you like — event, e, g... and it can also simply leave it out since you're not using it inside of your function.
Consider that these two functions are essentially the same:
function foo(hi) {
alert(hi);
}
function foo(bye) {
alert(bye);
}
And that you may leave out the argument if it's not used:
function bar() {
alert("hello!");
}
bar(12345);
Event is an object that represents the... event that produced that function to be executed.
Here's more information about the topic:
http://api.jquery.com/category/events/event-object/
It is often used to prevent default behaviour of a certain event, or to stop the propagation of the event to parent objects:
function(e){
e.stopPropagation();
e.preventDefault();
}
The event in the first example is an unused argument.
jQuery passes various arguments into each event handler - you can find details of what these arguments are in the documentation (e.g. http://api.jquery.com/click/).
As you do not need to use the event object (or e, or g - you can give the parameter any name you want) then it doesn't matter whether or not you include it
However, if you needed to use the handler for some reason (e.g. to call event.preventDefault() to prevent the default click behaviour from happening) then you would need to include it.
jQuery passes eventObject to the handler/callback function which is not used in your example.
You could read more about the eventObject in JQuery.
Events : An event in JavaScript is something that happens with or on the webpage.
Example of events:
A mouse click
The webpage loading
Mousing over a hot spot on the webpage, also known as hovering
Selecting an input box in an HTML form
A keystroke etc...
Events in Jquery
Using e is just a short for event.You could use any variable say g instead of e
$('#xyz_id').click(function(g){
var clicked_target = g.target;
});
You could have a look at events in jquery further at
http://api.jquery.com/category/events/event-object/
event argument is a optional parameter and it can be any valid variable name. Based on your requirement you can pass or ignore it.
Visit http://api.jquery.com/click/ for more info.
.click( handler(eventObject) )
handler(eventObject)A function to execute each time the event is triggered.
version added: 1.4.3.click( [eventData], handler(eventObject) )
eventDataA map of data that will be passed to the event handler.
handler(eventObject)A function to execute each time the event is triggered.
version added: 1.0.click()

How do you change the event firing order of the same event?

Jquery bind is amazing, but I don't know in what order the binding happens. My current problem is thus:
$(document.body).delegate('form', methods.checkForm);
$('form').bind('submit', methods.submitFormIfCheckedFormIsTrue);
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
return false;
}
return true;
};
methods.submitFormIfCheckedFormIsTrue = function (e) {
e.preventDefault();
$.ajax("/submitForm", {
data:$(this).serialize(),
type:"post"
});
};
This is obviously not the actual code that I'm using, but it's pretty close. What happens is, the submitFormIfCheckedFormIsTrue function fires before, or during, the checkForm function, so the checking is pretty useless. My hack for it was to add the class "checked" to the form and the check if the form has that class in the other function...but then you click submit, it checks, then you have to click it again to submit it if everything went right...which is retarded.
Another thing that's important regarding this problem is that I'm they're in completely different parts of my application, for reasons that can't change. Also, they're being loaded asynchronously.
The main thing I want to know then...is how to change the order, or set the priority of the events somehow...
If you are using 'delegate' the way you have it in your example, then the ajax submission is always going to run first, so the short answer to your question is "You Can't". Your delegate is attached to the 'body' element, so events attached to elements closer to the form in the DOM tree will fire first.
Events bubble from the form -> body, so there is no ordering when you are doing that.
One option would be to have your verification trigger a second event.
methods.checkForm = function (e) {
e.preventDefault()
if ($(this).isVerified()) {
$(this).trigger('form-verified');
}
};
Then instead of binding the other handler to 'submit', you would bind it to 'form-verified'.
$('form').bind('form-verified', methods.submitFormIfCheckedFormIsTrue);
This is also another way to accomplish ordering event if they are attached to the same element instead of using delegate.
Also, if you are using jQuery >= 1.7, then you should be using on instead of bind and delegate. http://api.jquery.com/on/
Update
If both are bound to the same element, then they will be triggered in the order that they were attached to the element. Assuming checkForm is bound before the other one, then the issue is that return false; does not stop other events from firing if they are attached to the same element. For that you also need e.stopImmediatePropagation().
methods.checkForm = function (e) {
e.preventDefault()
if (!$(this).isVerified()) {
e.stopImmediatePropagation();
}
};
There is also a useful answer over here if you ever have to tweak the ordering of events. jQuery event handlers always execute in order they were bound - any way around this?
In a general sense event handlers will be called in the order that they were bound, but only if they're bound at the same level. In your case you're binding one directly to the form while the other is a delegated handler bound at the document.body level. The directly bound one will happen first and then the event bubbles up to be handled by the other.
If you bind both handlers at the same level with .delegate() then they should be called in order:
$(document.body).delegate('form', 'submit', methods.checkForm);
$(document.body).delegate('form', 'submit',
methods.submitFormIfCheckedFormIsTrue);
Then in the first (generic) handler you should call the event.stopImmediatePropagation() method to prevent other handlers being called (noting that simply returning false prevents the default and stops the event bubbling up further, but it doesn't stop other handlers at that level from running):
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
e.stopImmediatePropagation();
return false;
}
return true;
};
(By the way, the code shown in the question left out the event (second param) from the .delegate() call - I've put it in in my code.)
Or bind both handlers directly rather than using .delegate(). And speaking of using .delegate(), if you're using the latest version of jQuery you may like to switch over to using .on(), the new do-everything event binding method.
"What happens is, the submitFormIfCheckedFormIsTrue function fires before, or during, the checkForm function"
Definitely before, not during. (In pretty much all browsers) JavaScript runs on a single thread, so you will not ever have two functions running simultaneously.

JavaScript: parameters for unnamed functions

In the following jQuery JavaScript code, what value does the parameter "e" take on within the function? I'm having difficulty understanding this because this function cannot be passed an argument elsewhere in the code so how would having a parameter work? And how would I use parameters in such functions that are not named and not called anywhere else in the code?
$(document).ready( function() {
$('div').each(function() {
$(this).click(function(e){
//some code
});
});
});
click sets the event handler. The click handler gets called by the browser when the event occurs, and the e parameter contains information about that event.
For keypress events, it contains which keys were pressed and what modifiers were pressed at that time (shift, control, etc.).
For mouse events, it contains the position of the click and which button was used.
See http://www.quirksmode.org/js/events_properties.html for more information about the properties of the event structure.
e is an eventObject as you can see in the jQuery click documentation.
I do not know what you can do with it however, but it should contain information about the click event. Maybe it's the standard DOM event.
That anonymous function is called when the event is fired, and e is an eventObject:
click( fn )
// fn, a function to bind to the click event on each of the matched elements.
function callback(eventObject) {
this; // dom element
}

Categories

Resources