3

I was looking at this basic example below (which makes all images in the DOM semi-transparent on mouseover), and was confused as to how an arbitrary function, such as handleMouseOver, receives an event object if you give it an argument.

How is it that the act of assigning such a function to the onmouseover attribute tells it to modify this function in this way, as there's nothing inherent in the function definition itself that says: "please pass me an event"? Is the assignment operator being overloaded somehow? Or is the browser doing some extra work here? I would really appreciate a link to a detailed explanation of this phenomenon because it doesn't seem to make any sense looking at it as pure JavaScript (to me at least!)

function handleMouseOver(e) {
    e.target.style.opacity = 0.5;
}

function handleMouseOut(e) {
    e.target.style.opacity = 1;
}

var elements = document.getElementsByTagName("img");

for (var i = 0; i < elements.length; i++) {
    elements[i].onmouseover = handleMouseOver;
    elements[i].onmouseout = handleMouseOut;
}
njp
  • 695
  • 2
  • 8
  • 21
  • Not all the browsers do that. With IE you have to explicitly read `window.event` – Yuriy Galanter Sep 23 '13 at 14:29
  • As you might have noticed, there's no way to tell if a function accepts arguments. What's interesting, though, is that you can pass any arguments you like to a function, whether the function signature accepts arguments or not. (You can actually accept arguments not through the function signature, too, with the `arguments` array-like object.) – Colin DeClue Sep 23 '13 at 14:30
  • @YuriyGalanter — That's very old-IE. IE supports the standard methods now. – Quentin Sep 23 '13 at 14:35
  • @YuriyGalanter: As long as you don't class IE as a browser, then it isn't a problem – musefan Sep 23 '13 at 14:38

4 Answers4

1

onmouseover, for example, is an event handler. When the event handler needs to be called (in this case when the browser javascript engine decides it) then it will call it be passing it some pre-determined arguments (all good documentation will explain what those arguments are). Your use of those arguments is optional however.

This can be demonstrated with a manual function call like so:

function myFunction(e){
   alert(e.myProperty);
}

//assign the handler
var handler = myFunction;

//when required, create event parameter data and call the function assigned to the handler
var myE = { myProperty: "some data" };
handler(myE);

It is not "exactly" how it works (because I don't know how browsers have chosen to implement their code), but it shows the concept.

Here is an example in action

musefan
  • 47,875
  • 21
  • 135
  • 185
  • 1
    Reference would be appreciated. Thanks – fahadash Sep 23 '13 at 14:32
  • Thanks, but my source of confusion is that if it's an event handler, and then I assign it to a function, then it's just a function, right? And if not, what's actually happening? Is the browser making a special case and preserving the additional event argument needed, or is it some clever JavaScript that preserves a feature of the event handler (such as the argument) upon assignment? – njp Sep 23 '13 at 14:33
  • 1
    @fahadash: I don't have a reference unfortuantely. Not everything I know has to be taught to me, I am quite capable of working things out for myself – musefan Sep 23 '13 at 14:37
1

Not only the event object is passed, but also the this value within the function is set to the event target. This is done by the browser, and dictated by the DOM specification.

EDIT:

I was hoping to find something more detailed in the DOM specification (I'm sure I've seen that before), but so far I found this:

In JavaScript, user-defined functions are considered to implement the EventListener interface. Thus the Event object will be provided as the first parameter to the user-defined function when it is invoked. Additionally, JavaScript objects can also implement the EventListener interface when they define a handleEvent method.

https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#glossary-event-handler

By the way, the last sentence is talking about an interesting way to bind event listeners, in an OO context.

Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
1

Lets break it down by taking one browser's example. IE'S OnMouseOver Event for instance.

In the remarks section it says it passes IHTMLEventObj for ALL events even for the events that don't require it such as Body.OnLoad.

When we go into IHTMLEventObj's detail, we read the following remarks

Although all event properties are available to all event objects, some properties might not have meaningful values during some events

So, Event object is passed regardless; you have to access the object in some specific events and get event-specific properties to get event-related data.

fahadash
  • 3,133
  • 1
  • 30
  • 59
0

You can pass whatever arguments you like to any JavaScript function.

Defining them in the function definition just means you have a named, local variable to access them with.

That is to say:

function foo() {

}

foo("hello");

… won't throw an error.

When a function is treated as an event handler (which is what code provided by the browser will do if you assign a function to the onmouseover property of a DOM node) then the event object will be passed as an argument.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Right on, so in the case of above, when the browser detects an onmouseover event, onmouseover(someEvent) is called which then makes it available in the arguments array. I guess then the question is, is the browser responsible for this call or is it actually a method of the HTMLElement object? – njp Sep 23 '13 at 14:41
  • @njp — The `onmouseover` function itself is provided by the page author and is a method of the instance of the HTML Element. The code that calls it is internal to the browser, so where it lives is an implementation detail that only matters if you are working on the browser's source code. – Quentin Sep 23 '13 at 14:42
  • Great, thanks. Although I would love to see a link to a spec or something - how would a developer know the event object is given to them off the bat unless this was made clear somewhere? – njp Sep 23 '13 at 14:57
  • 1
    @njp — http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-registration-html40 – Quentin Sep 23 '13 at 15:10