Named Element IDs Can Be Referenced as JavaScript Globals
Do you know? DOM elements with ID can be accessed as global variables in JavaScript? This is a feature that has been around for a long time, but I've only been delving into it for the first time.
If you first hear about this feature, be prepared! Just add an ID to the element in HTML and we can see how it is applied in practice:
1 |
|
Usually, we use querySelector("#cool")
or getElementById("cool")
to define a new variable to select the element:
1 |
|
But in fact, we can access #cool
without these cumbersome operations:
Therefore, any ID (or name attribute) in HTML can be accessed in JavaScript using window[ELEMENT_ID]
. Again, this is not a "new" feature, but it is rare.
As you might have guessed, accessing global scopes with named references is not the best solution. Some people call it "global scope polluters." We will explore the reasons, but first...
Some background
This method is described in the HTML specification, which describes it as "named access to Window objects".
Internet Explorer is the first browser to implement this feature. Other browsers have added this feature. At the time, Gecko was the only browser that did not support it directly in standard mode, but chose to use it as an experimental feature. People were hesitant about implementing it, but for browser compatibility it eventually advanced (Gecko even tried to convince WebKit to remove it from standard mode) and eventually entered standard mode in Firefox 14.
What is probably less well known is that browsers have to take some precautions (various levels of success) to ensure that the generated global variables do not corrupt the web page. One of the measures is...
Variable occlusion
The most interesting part of this feature is that named element references do not obscure existing global variables. Therefore, if the ID of the DOM element is defined as a global variable, it does not overwrite the existing variable. For example:
1 |
|
1 |
|
1 |
|
Super versa:
1 |
|
1 2 |
|
This behavior is crucial because it eliminates dangerous coverage, such as <div id="alert"></div>
, otherwise it will cause conflicts by invalidating the alert API. This protection technique is most likely the reason why you (if you are like me) first learn about it.
Articles against naming global variables
I said earlier that using named global elements as references may not be the best solution. There are many reasons, and TJ VanToll has elaborated on this very well in his blog, and I will summarize it here:
- If the DOM changes, the reference will also change. This makes the code very "frail" (a term in the specification), and the separation of concerns between HTML and JavaScript may be too strict.
- Accidental quotations are too easy. A simple typo will most likely refer to a named global variable and give you unexpected results.
-
Implementation methods vary in different browsers. For example, we should be able to access anchors with IDs (e.g.
<a><code><a></a>
), but some browsers (i.e. Safari and Firefox) return a ReferenceError in the console. -
It may not return what you think it will result. According to the specification, when there are multiple instances of the same named elements in the DOM (for example, two
<div><code><div> instances), the browser should return an HTMLCollection containing the array of these instances. However, Firefox returns only the first instance. Again, the specification states that we should use an ID instance in the element tree. But doing so won't prevent the page from working or anything like that. <li> <strong>Possible performance costs? </strong> I mean, the browser has to create that reference list and maintain it. Some people have run tests in StackOverflow threads where named global variables actually perform better in one test and lower in recent tests. </li> <h3 id="Other-precautions">Other precautions</h3> <p>Suppose we abandon criticisms against the use of named global variables and continue to use them. all the best. However, there are a few things you may want to consider when you do this. </p> <h4 id="polyfills">polyfills</h4> <p> may sound extreme, but these types of global checks are typical setup requirements for polyfills. Check out the following example, we set a cookie using the new CookieStore API, polyfilling it in a browser that does not yet support it: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><div id="cool"></div></pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p> This code works fine in Chrome, but in Safari throws the following error: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">var el = querySelector("#cool");</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>At the time of writing, Safari does not support the CookieStore API. Therefore, polyfill will not be applied because the img element ID creates a global variable that conflicts with the cookieStore global variable. </p> <h4 id="JavaScript-API-Update">JavaScript API Update</h4> <p> We can change the situation and find another problem, that is, updates to the browser's JavaScript engine may break the global reference of the named element. </p> <p>Example: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">window.foo = "bar";</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div> <p>This script takes a reference to the input element and calls focus() on it. It works fine. However, we don't know how long it will work. </p> <p> You will see that the global variables we use to reference input elements stop working once the browser starts supporting the BarcodeDetector API. At that time, the window.BarcodeDetector global variable will no longer be a reference to the input element, and .focus() will throw an "window.BarcodeDetector.focus is not a function" error. </p> <h3 id="Conclusion">Conclusion</h3> <p>Let's summarize how we got to this point: </p> <ul> <li>All major browsers automatically create global references to each DOM element with an id (or in some cases the name attribute). </li> <li> Accessing these elements through their global reference is unreliable and can be dangerous. Please use <code>querySelector
orgetElementById
instead. - Since global references are automatically generated, they may have some side effects on your code. This is a good reason to avoid using the id attribute unless you do need it.
Ultimately, it is best to avoid using named global variables in JavaScript. I've quoted earlier what the specification says about it causing "frailty" code, but here is the full text to emphasize this:
Generally speaking, relying on this will lead to fragile code. Which IDs may eventually map to this API over time, for example, as new features are added to the web platform. Do not do this, use
document.getElementById()
ordocument.querySelector()
.
I think the HTML specification itself suggests avoiding this feature says it all.
The above is the detailed content of Named Element IDs Can Be Referenced as JavaScript Globals. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

It's out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That's like this.

I'd say "website" fits better than "mobile app" but I like this framing from Max Lynch:

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

CSS Grid is a collection of properties designed to make layout easier than it’s ever been. Like anything, there's a bit of a learning curve, but Grid is

I see Google Fonts rolled out a new design (Tweet). Compared to the last big redesign, this feels much more iterative. I can barely tell the difference
