I've discovered this behavior by accident:
I can access an HTML-element in JavaScript just by it's HTML attribute "id". Normally I used getElementById for that.
I have even write-access to it's properties.
Made this demo and tried it out in Firefox, Safari and Chrome.
It worked everywhere.
alert(test1.innerHTML);
test1.innerHTML = 'Foobar';
alert(test1.innerHTML);
<div id="test1">Demo 123</div>
So, to be honest: I'm astonished and confused because I haven't known that that's possible.
Moreover I ask myself: What sense does getElementById make when I can get and set the element directly?
Sure: I'm aware that the inventors haven't incorporated the method without some intention.
Can anyone give me some explanations why I have access to elements via id-attribute?
And why one uses getElementById nevertheless?
As far as I remember, this behaviour was introduced by Internet Explorer. After a while, other vendors picked it up. I don't think it was ever standardized and, as such, might stop functioning at any time. Also, if you have a variable test1 in your code it will override the test1 defined by the controls.
Worth mentioning, in certain IE versions, trying to create a global variable with the same name as the id of an element fails. The book "JavaScript: The Definitive Guide" by David Flanagan also says that if the variable already exists in the global scope when the element is created, then the variable will not be overwritten by the element with the same id.
More on the subject here: Is there a spec that the id of elements should be made global variable? and here: Do DOM tree elements with ids become global variables?
Related
I have a website that contains the following HTML/javascript:
<input type="text" id="txtPhaseID" onkeypress="return onlyNumbers();" />
<a id="btnLookup" onclick="GetEventLookupData(txtPhaseID.value);this.blur();return false;" href="javascript:void(0);" class="btn"><span>Lookup</span></a>
The reference to txtPhaseID.value in the onclick event works in IE8 but fails in IE11. I'd expect it to fail in both since you should have to use document.getElementById.
Why does this work in IE8?
Technically when you add an id to an element you could access it directly from the DOM with id.property - but it's always been considered very bad practice to a point that no one was ever taught that way. I can only imagine it was finally removed in Internet Explorer 11. I have no idea what this is called and I don't think it's ever been given a specific name, which means Googling will return pretty limited results. Unfortunately, if they did remove it there probably isn't anything saying so.
Here are some other resources from stackoverflow for more information:
Do DOM tree elements with ids become global variables?
Why don't we just use element IDs as identifiers in JavaScript?
Check out this fiddle (partial code snippet below): http://jsfiddle.net/QJJb8/
<button id='mybutton'>MY BUTTON</button>
mybutton.addEventListener('click', mybuttonClick, false);
function mybuttonClick(e){
alert(e.target.textContent+' WAS CLICKED!');
}
Note how I'm not using getElementById() to get a reference to the button. Why does it still work? (Tested in Firefox, Chrome and IE9 & 10.)
Is it bad-practice/quirk, or is it built in functionality for button elements? If the latter, that's an awesome perk/shortcut when using button elements! Or perhaps I've just been over-using getElementById() all this time?
//ANSWER UPDATE//////////////////////////////////////////////////////////////////////
After some research it seems the behavior discussed above is in fact part of the HTML5 spec. In addition to RobG's answer below, see also the following links for more insight:
http://tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/
https://stackoverflow.com/a/3434388/2434324 (link supplied by yoelp)
http://jsperf.com/named-access-on-the-window-object
Because way back at the begining of browser scripting, IE decided to make element names and IDs global variables that referenced the element. Everyone else thought that was a bad idea (it was) and didn't do it.
However, IE grabbed about 95% of the browser market and developers developed for IE's quirks, so other browsers implemented the same behaviour but didn't advertise it (same with support for document.all). So now all browsers do it, but (almost) no one uses it.
Except when someone stumbles across it…
So where you have:
<button id='mybutton' ...>
browsers create a global mybutton variable that references the element.
This works on all DOM elements, not only buttons, Its probably a bad practice since any one may change mybutton to something else (ie.mybutton = "BLABLA") then your code breaks
also see this
I'm working on a website which was coded a while ago.
I've found a Javascript function that uses the following syntax to set a value for a text box
document.myForm.myText.value = "value";
I've tested this code and it works in IE, Firefox and Chrome.
My question is whether this way of setting/selecting DOM elements is ok going forward (ie. is it going to get depreciated)? Should I change instances of this type of element selecting to the more standard (in my experience) code below?
document.getElementById("myText").value = "value";
Thanks in advance.
I don't think it'll make a difference cause the browsers dom representation will have change to break the code; That'll probably break half the web pages on the internet.
Your code is better than the first because you will then be coding to the contract of the method getElementById, which returns the HTMLElement you need. This means that the JS Engine has to adhere to the standards of ECMAScript and return the exact element. Hence your code doesn't need to worry if tomorrow a browser changes it's structure and your element is now document.forms.myForm.myText.value instead of what you anticipated.
I have been learning HTML5. One of the examples I have encountered uses an input element of type range and an output element (this example currently only works in Chrome, Safari and Opera). The following form produces a slider with the result echoed to the output element.
<form>
<p>
<input type="range" id="slideValue" value="50"
oninput="slideCurrent.value = parseInt (slideValue.value);" />
<output id="slideCurrent">50</output>
</p>
<input type="submit" value="Send">
</form>
My question concerns the oninput attribute. The oninput attribute contains JavaScript. In pre-HTML5 JavaScript I commonly see JavaScript references to this.value. However in the above HTML5 example the references to slideCurrent and slideValue work (apparently without the need to use getElementById). I believe this is a new way for JavaScript to behave.
Is this new JavaScript method of action documented somewhere?
Code within inline event handlers is scoped to the element, as if it was in a with block.
Therefore, you can use properties of the element as global variables.
This is a little-known and dangerous feature, and is not new to HTML5.
It's a method introduced by IE, that elements' names and ids are references in the global scope. Other browsers have copied it, but it's considered as bad use. Mozilla throws a warning:
element referenced by ID/NAME in global scope. Use WC3 standard
document.getElementById() instead...
You can find lots of threads when googling for that. A good article can be found here. In the event handler you can use this
as a reference to the element, but the output element should be acessed by standard dom methods.
EDIT: Oh shit, yes, its in the spec: http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem. But with a big red alert:
It is possible that this will change. Browser vendors are considering limiting this behaviour to quirks mode. Read more...
See also Mozilla bugs 303420 and 602381
I came across some javascript at work today that used jQuery to fetch two elements. It then used elem.nodeIndex to determine the position in the elements parent for each element. Nothing is setting this property anywhere and I do now see a reference to it in the msdn, mdc, or anywhere else.
I stepped through this javascript in FireFox with FireBug and tested the code in chrome and opera. I am sure nothing was trying to set this property. However, I can't find any information on this nodeIndex property anywhere.
Does nodeIndex exist as a DOM property in IE, or did I miss something while debugging my code?
UPDATE: I asked the same question on the jQuery list and they confirmed the property is for internal use only.:
It looks like it's jQuery that's adding nodeIndex to nodes in some cases.
Well, the easy answer is: If it isn't documentated anywhere like MDC, MSDN or W3, then it isn't a 'real' DOM property.
The idea of using nodeIndex, is also wrong, why would you want to do that?