Why use getElementById if id is in the window?

Asked

Viewed 1,826 times

57

Recently in my study I noticed an object that manipulated the DOM of the element that had the same name in its id.

teste.style.border = '1px solid #CCC';
teste.style.width = '500px';
teste.style.height = '50px';
<div id="teste">
</div>

Doubt

  • Why the ids go to the global space?
  • If I can access the element directly through your id, why use getElementById?

Note

Composite name objects are accessible on window

window['teste-id_composto'].style.border = '1px solid #CCC';
window['teste-id_composto'].style.width = '500px';
window['teste-id_composto'].style.height = '50px';
<div id="teste-id_composto">
</div>

3 answers

68


The fact that appointed elements* are part of the properties of document and/or window is unfortunate, the result of very simple applications that there were many years, at the beginning of DOM and Javascript.

Unfortunately because they are used and some browsers promote them they still exist to not break old code, and are even common practice. Have references to elements in the properties of document or window It is a very bad idea, since they occupy the same space as variables in the application code that are run and can be "erased". Yes, declaring a function or variable in the global space overwrites some property that comes from a named element that uses the same name.

What is the safe solution to separate the waters?

=> use document.getElementById() and/or document.querySelector()

What does W3C say?

The HTML 5.1 specification (April 12, 2016) is very clear here and recommends not to access named elements, via document or window. In the specification it says so:

As a general Rule, relying on this will lead to Brittle code. Which Ids end up Mapping to this API can Vary over time, as new Features are Added to the Web Platform, for example. Instead of this, use document.getElementById() or document.querySelector().

That is to say, "as a general rule depend on this method (window[id]) generates fragile code. This technology should be used document.getElementById() or document.querySelector()".


Note:

* - appointed elements (named Elements is the name I know in English) are all the elements that have the attribute id or name defined.

  • 4

    Now with this note from W3C I say that this is the best answer +1

29

Before there were standards for HTML, CSS and javascript who defined this were the browsers, ie each browser had its own way of doing things, as for example each had a way of catching elements of DOM, for example:

  • Internet Explorer 4 used document.all
  • Netscape4 wore document.layers

These were the main "market" browsers and were the ones that first implemented Javascript (in IE it was called Jscript)

Since the IE5.01 version, the document.getElementById and document.getElementsByTagName, the only one that didn’t work in IE was the document.getElementsByTagName("*");, that only came to be supported in IE6, for that we had to use document.all yet.

The Ids because they are "unique" elements in IE (although some developers repeat them, which is a mistake) became accessible directly in the references of global variables that in Javascript for browsers is the object window, provided that the DOM was loaded and the variable had not been declared.

IE maintained this feature to maintain compatibility with sites that had been made for previous versions, some browsers imported this feature to try to maintain compatibility

My opinion: at the time it was very common to accuse the browser for not working on a given site, when the problem was in the script, so many engine developers were forced to put these peculiarities in the engines themselves.

In Firefox for example document.layers was still supported, but issued a Warning on the console warning that it would be removed, unlike the Internetexplorer kept many things, such as the document.all (this sometimes generates a DOM list other than document.getElementsByTagName("*");).

There was an engine called iCab (until version 3 of the browser whose engine name was also called iCab, in version 4 onwards it went on to use Webkit and Cocoa API) for Macos which had similar functionalities to IE4 like document.all, This was a way to maintain compatibility with websites made for Internet Explorer.

It is likely (has nothing discussed, it is just an assumption) that with the evolution of browsers and "standards" of Ecmascript the window generate a variable that represents an element by id automatically is removed one day and only what is really needed is maintained, that is if you use something like window.meuElemento, this may fail in the future.

I also don’t recommend using the ID reference because of conflicts with variables that may have been defined and that have the same name as the id (this is a problem that can already occur and does not depend on the future).

Note that there are other properties to get DOM elements like:

  • document.forms

    Get forms by index as document.forms[0]

  • document.embeds

    Obtains elements <embed> by the index as document.embeds[0]

  • window.frames

    Obtains elements <frame> and <iframe> by the index as window.frames[0], note that window.frames does not return the DOM element of (i)frame but the object window from within, this window.frames[0] then it would be the same as doing this document.getElementsByTagName('iframe')[0].contentWindow

  • 1

    You could say it is a historical addition to the @Sergio reply. Very interesting.

  • 1

    @Guilhermelautert may be =)

4

The difference is small, it is more in the processing time. "Document" is already an element rendered by Dom, in this sense, when you use getElementById you are capturing the rendered element id itself, and there will be no error if the element does not exist in your document. Which makes the property safer not to make a mistake while at window['id_nome'], is captured by the structure of your global window, what happens in this case is that you capture the window array... There’s not much difference in you, but in the case of window['id_nome'], error may occur, especially if you enter the index erroneously, or try to locate something that does not exist in the window, it also depends a lot on the behavior of the window and the type of browser, IE is a little flawed in this issue. Because if you don’t have a proper handling at some point, you might not find the array index, but nothing that can’t be solved as in the example below:

if (window['id_name']) {
    var el = window['id_name'];
} 

PS: Just be careful using reserved words from the window.

  • Hello Ivan, could you explain exactly where IE is flawed? Sorry to talk, but about the part you claim that window['id_nome'] may cause error if the element does not exist and the getElementById no, it seems wrong to me in both cases may occur failures, window['id_nome'] if there is no element will return only undefined and document.getElementById('id_nome') will return null. The error can occur in both, since they would return Undefined and null. It is only a constructive criticism aimed at possibly you can improve your response. ;)

  • One way to avoid this error is by using: window.onload = function() { ... }, Undefined is different from null, so the error, is exactly that difference, Undefined is an undefined element, which we can consider a logic error, if something expected (a window array) would be defined, there would be no return Undefined. (this is treated as a mistake).

  • Dear Ivan, This of Undefined and null I quoted is something else, I said it will return, whether different null or Undefined, I if how to avoid this (for example https://answall.com/a/137881/3635), the question that we can not understand is the part that you speak of the IE be flawed, but it is something that has become difficult to understand where exactly this is, I wanted to understand this that you quoted ;)

  • It’s just that in IE, the gift is processed more slowly... so it fails.

  • 1

    Is that a mistake, did you do a benchmark test? You know that this is why there are events like Domcontentloaded or the property Document.readyState, being a slower rendering or processing engine does not mean any fault. By the way, if a site is not in "buffer" and is slow, DOM will take time to process anyway, be it Chrome, FF, IE, Safari.

  • Man, I don’t like IE, he hangs like hell, regardless, I’ve done a lot of tests, and I’ll tell you, he’s not stable, especially when you work with events and capturing elements of the gift, he hangs like hell, and I’m not talking about the new architectures, edge for example which is totally different, but older models, and often it hangs to the point of closing the browser... I do not need to test the PC to know that the problem is the browser, when my PC has all the requirements necessary to run and not have the same behavior with other snowmobilers.

  • And today I no longer use PC, only mac.

  • For years IE was used, whether it had problems like this or simply did not know how to use JS well and had a number of navbars installed (common things in IE) or had problems with computers, it was not a "beauty"but it did not imply anything of what we talked about or what is the subject of the question.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.