Why Is 'Event' Variable Available Even When Not Passed as a Parameter

Why is 'event' variable available even when not passed as a parameter?

Why is 'event' variable available even when not passed as a parameter?

It isn't, reliably. That code will fail on Firefox, for instance. It wasn't and used to fail on Firefox. Microsoft used a global event variable. DOM2 defined it as an argument to the handler. Chrome decided to throw MS-specific code a bone and do both. For a long time, Firefox did not. But the global was standardized as a legacy API for compatibility reasons (spec | MDN) and Firefox added it in v63, briefly put it behind a flag the user had to enable, and since v66 ships with it unflagged.

Even on the browsers where that code works, note that event will be a raw event object, not the jQuery-enhanced one. That means that, for instance, on IE8 you can't call event.preventDefault because IE8 doesn't supply that function. jQuery would if you accepted the argument, because jQuery provides an event object with standardized features even on browsers that are missing those features.

event object is recognized without passing it, in javascript function?

You're accessing the global window.event. Support for this object varies from browser to browser.

See http://www.quirksmode.org/js/events_access.html

The parameter passed by jQuery is normalized to avoid these browser inconsistencies, but as you realized, you weren't accessing that parameter, so you were getting the raw global event object instead.

Why is there an 'event' variable available without being defined when there was an event upstream?

It is something that got carried from the old version of IE, where the event object was not passed to the handler method instead it was set in the global context.

For backward compatibility IE still supports this model and chrome also has added support for this feature. But FF is not supporting it.

  • Event object references

Is event a global variable that is accessible everywhere inside the callback chain?

One can access the current event through window.event. Just using event is implicitly accessing window.event.

What is the meaning of this...var evt=event||window.event;

It means that the variable evt is assigned to the value of event or if event is undefined it is assigned the value of window.event.

How this works is that in javascript, boolean operators don't evaluate to true or false but instead evaluates to the value of the last object that is not falsy* or the falsy value.

So the statement first evaluates the expression event || window.event. If event is true then the expression does not need to be evaluated any further since an OR only needs one member to be true. Therefore the value of event is returned. If event is falsy then the the right side of the OR operator needs to be evaluated to determine if the result is false. In which case, if window.event is not falsy then its value is returned.

This is a very common idiom to get the event object from event handlers. On standards compliant browsers, the event object is passed as the first parameter to the event handler. But on IE the event object is a global variable. And for historical reasons, all global variables are members of the window object.

So the code should look something like this:

element.onclick = function (event) {
var evt = event || // use the value of event if available or
window.event;// if not assume it's IE and use window.event

/* ... */
}

Note: * falsy values in javascript are: false, 0, null and undefined.

What exactly is the parameter e (event) and why pass it to JavaScript functions?

The e is short for event

The simplest way to create an event is to click somewhere on the page.

When you click, a click event is triggered. This event is actually an object containing information about the action that just happened. In this example's case, the event would have info such as the coordinates of the click (event.screenX for example), the element on which you clicked (event.target), and much more.

Now, events happen all the time, however you are not interested in all the events that happen. When you are interested in some event however, it's when you add an event listener to the element you know will create events[1]. For example you are interested in knowing when the user clicks on a 'Subscribe' button and you want to do something when this event happens.

In order to do something about this event you bind an event handler to the button you are interested in. The way to bind the handler to the element is by doing element.addEventListener(eventName, handler).

eventName is a string and it's the name of the event you are interested in, in this case that would be 'click' (for the "click" event).

The handler is simply a function which does something (it's executed) when the event happens. The handler function, by default, when executed is passed the event object (that was created when the event/action you are interested in happened) as an argument.

Defining the event as a parameter of your handler function is optional but, sometimes (most times), it is useful for the handler function to know about the event that happened. When you do define it this is the e you see in the functions like the ones you mentioned. Remember, the event is just a regular javascript object, with lots of properties on it.

Hope that helped.

For more info read Creating and Triggering Events

As for your 3rd question, now you should know you cannot do that, because e only exists when an event happens. You could have the handler function, which has access to the e object when it gets executed, to store it in some global variable and work on that.

[1] That is not exactly correct, but it's simpler to understand. The more correct thing to say there is "add an event listener to the element you know will have events flow through it". See this for more information

Get calling Event inside of Class-Function without Parameter in JavaScript

When the event handler is called, the actual event will be available as a global event variable (or as window.event, see MDN), so the event object will be accessible from the event handler, without passing it directly. In the examples below, click on a square to make it focused, and press any key. The pressed key will be printed into the log.

Note that "you should avoid using this property in new code, and should instead use the Event passed into the event handler function" (see MDN for details).

// 1. Function
function onKeyDown() {
console.log("onKeyDown() ->", event.key);
event.preventDefault();
}

// 2. Method
class A {
onKeyDown() {
console.log("new A().onKeyDown() ->", event.key);
event.preventDefault();
}
}

// 3. Static method
class B {
static onKeyDown() {
console.log("B.onKeyDown() ->", event.key);
event.preventDefault();
}
}
.square {
display: inline-block;
width: 100px;
height: 100px;
background: lightblue;
text-align: center;
vertical-align: middle;
line-height: 100px;
font-family: Arial, Helvetica, sans-serif;
font-size: 10pt;
}

.square:focus {
outline: solid 1px blue;
}
<div class="square" tabIndex="0" onkeydown="onKeyDown()">Function</div>
<div class="square" tabIndex="0" onkeydown="new A().onKeyDown()">Method</div>
<div class="square" tabIndex="0" onkeydown="B.onKeyDown()">Static Method</div>

What's the difference using 'event' as parameter in these formats?

It looks like sendClickEvent is called with an object, which has a property named event. As a result:

public sendClickEvent = ({ event: e }) => {
e.preventDefault();

works because { event: e } destructures the event property from the object argument and puts the event into a variable named e. But

public sendClickEvent = (event: any) => {
event.preventDefault();

won't work because the argument is an object wrapper around it, not the event itself. You'd need something like

public sendClickEvent = (obj) => {
obj.event.preventDefault();

Since this is TypeScript, I'd also highly recommend not using any, since that effectively disables type-checking, defeating the whole purpose of using TypeScript. Figure out the exact type the function should be called with, and type the function as that, so that you don't have to use any anywhere. Perhaps something along the lines of

public sendClickEvent = ({ event: e }: { event: React.MouseEvent }) => {
e.preventDefault();

Chrome seems to define 'event' variable in Meteor/Blaze

It's nothing to do with Meteor, just Chrome: Chrome does this to support code written originally for Internet Explorer; in addition to passing the event to the handler, it also sets it as a global event variable.

Microsoft's "new" event handling in IE5 (or was it 5.5?) used a global event object and attachEvent/removeEvent. Then DOM2 came along (after IE6 had been released) and defined addEventListener/removeEventListener where the event handler recieves the event as an argument. Then years passed before Microsoft supported DOM2 (in IE9).

So when Chrome was coming up, they made the decision to provide a global event object to increase compatibility with IE-specific code. Mozilla chose not to originally, but does now; more in my answer here.

You can see it here — run this on Chrome:

document.getElementById("target").addEventListener("click", function(e) {  console.log("e === event? ", e === event);}, false);
<div id="target">Click me</div>


Related Topics



Leave a reply



Submit