0

I came along some code today of which I was pretty sure it wouldn't work. Turned out I was wrong. This works for both IE and Chrome.

<img onmouseover="why(this)" src="http://placehold.it/150x100" alt="" />
<img onmouseover="why(this)" src="http://placehold.it/100x100" alt="" />
<br>
<img id="preview" src="" alt="" />
<img name="preview2" src="" alt="" />

 

function why(obj) {
    preview.src = obj.src;
    preview2.src = obj.src;
}

Why does this work? Aren't we supposed to use document.getElementById?
FIDDLE

Jonathan
  • 8,771
  • 4
  • 41
  • 78

1 Answers1

1

It works because by default, all elements that have ids are dumped on the window object, using their id as their property name. Some browsers do the same with name. Since the window object is the global object in browsers, those seemingly-free-standing variables are resolved as properties of window.

It's not a good thing to rely on, because the global namespace is very crowded and it's really easy to shadow those. For instance:

function preview() { }

Now that element with the id preview isn't available as a global symbol anymore, because I've shadowed it with a function. Or

var preview;

Boom, it's gone.

Hence using document.getElementById and such when you're looking up elements.


Re your comments below:

When I inspect the window object I can't find the property preview. Once I place a breakpoint in the function why however, window.preview suddenly is defined. Any idea how that works?

I just added window.preview as a watch expression, it returns undefined untill I hit the brekpoint.

I would expect the properties to get created as those elements were parsed. So it would depend on when you stopped and looked at window: If you were looking at it before the parser reached those DOM elements, those properties would be undefined. And that's what I see with this page:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ScratchPad</title>
</head>
<body>
<script>
debugger;
</script>
<div id="testelement"></div>
<script>
debugger;
</script>
</body>
</html>

As of the first debugger; statement, a watch (also using Chrome's devtools) on window.testelement shows undefined, but as of the second debugger; statement, it shows the div element.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • When I inspect the window object I can't find the property `preview`. Once I place a breakpoint in the function `why` however, `window.preview` suddenly is defined. Any idea how that works? – Jonathan Feb 23 '14 at 17:51
  • @Jonathan: How are you inspecting the window object? These properties are only available in the JavaScript layer, not (say) in the DOM layer... – T.J. Crowder Feb 23 '14 at 17:58
  • I just added `window.preview` as a watch expression, it returns `undefined` untill I hit the brekpoint. (Tested with Chrome devtools) – Jonathan Feb 23 '14 at 18:06
  • @Jonathan: I've added an update at the end of the answer. – T.J. Crowder Feb 23 '14 at 18:14
  • Darn, I think I was just looking at jsFiddle's `window` object and `window` just switched to the `iframe` jsFiddle uses when it hit the breakpoint... – Jonathan Feb 23 '14 at 18:26