Why is document.getElementById not needed? [duplicate]
1) Question 1
The following example works without using “document.getElementById(‘myId’)”. Why is that and is it OK to skip “document.getElementById(‘myId’)”?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Javascript question</title>
<script>
window.onload = function(){
myId.style.color="red";
}
</script>
</head>
<body>
<div id=myId>
<p>Make this color red.</p>
</div>
</body>
</html>
2) Question 2
I usually store browser-objects to reduce DOM traversal (see example below). Will it be more DOM traversal if I dont store the ID in a variable or is it some how already a variable?
window.onload = function(){
var myId = document.getElementById('myId'); /* stored ID that will be used multiple times */
myId.style.color="red";
}
Thanks!
The following example works without using “document.getElementById(‘myId’)”. Why is that and is it OK to skip “document.getElementById(‘myId’)”?
Because browsers dump references to all elements with id
s into the global namespace, using the id
as the variable name. (Technically, as the property name on the global object; properties of the global object are global variables.) I strongly recommend not relying on it and using document.getElementById
(or similar) instead. The global namespace is really crowded and there are lots of other things there which can conflict.
For instance, if you have
<div id="foo">...</div>
and
function foo() {
}
Then just using foo
in your code will give you the function, not the element.
Similarly if you have
<input type="text" id="name">
…and use name
in your code, you’ll get the window’s name (a string), not the HTMLInputElement
for your id="name"
field.
This business of dumping references to the elements into the global namespace is covered in §5.2.4 of the HTML5 spec, which in this case is largely documenting what browsers have done for a long time.
Will it be more DOM traversal if I dont store the ID in a variable or is it some how already a varible?
It’s already a global variable per the above, so there’s no additional DOM traversal. In a deeply-nested function there may be more scope chain traversal, but that’s unlikely to be a major issue.
But again, I strongly recommend not relying on the automatic element globals. Instead, wrap your code in a scoping function (as you’ve shown), and get the elements on purpose with getElementById
, querySelector
, querySelectorAll
, etc., as appropriate. If you rely on the automatic globals, odds are eventually you’ll get bitten by a conflict. But this is opinion.
Note that looking up elements with getElementById
is really really fast, so caching references is not usually necessary for performance reasons (you may want to do so for other reasons, like coding convenience). Looking things up with selectors (querySelector
, querySelectorAll
) is a bit slower, but I’d say worry about it when/if there’s a problem. 🙂