DEV Community

Tracy Gilmore
Tracy Gilmore

Posted on • Edited on

Just an idea: Using a prefix with id attributes for direct JS access

A little-known fact is that valid DOM element id attributes are exposed by the DOM into the JavaScript space as properties of the window (globalThis) object. This means an element such as:

<div id=”testDiv”>Hello, World!</div> 
Enter fullscreen mode Exit fullscreen mode

Can be accessed as follows without the need to use document.querySelector(‘#testDiv’) or its older cousin document.getElementById(‘testDiv’).

console.log(testDiv.textContent); // “Hello, World!” 
Enter fullscreen mode Exit fullscreen mode

However, as is, this pollutes the global namespace and MDN cautions against using the id attribute this way primarily because of the potential conflict with other entities in the global namespace such as window properties. MDN advises using the aforementioned document methods.

When hand-crafting CSS, a long-lost art, the general (and sound) advice is to avoid using the id of an element to apply styling as this could be too specific. Personally, I have not had too much of an issue with styling by id but usually only in hobby projects and prototypes. In production code I usually stick with the guidance and would recommend the guidance to fellow frontend developers.

But, what if we could force the CSS issue whilst considerably reducing the potential of global namespace collision? Whilst testDiv is a valid CSS selection by id #testDiv, adding a dollar symbol to the front makes it invalid (#$testDiv is not a valid CSS selector).

At the same time, it is highly unlikely that the window API will acquire properties with such a prefix, reducing collision potential.

There are JS libraries (of old) that use the $ symbol, the most well-known of course being JQuery, and whilst there is a wealth of code out there in the wide using such libraries, I suspect they are not used anywhere near as much in production code these days.

In conclusion, prefixing element id attributes with a dollar symbol would:

  1. Impede the use of the id in CSS styling, not that it is done very often these days.
  2. Enable JS to reference the DOM element directly without the need to look up the element first using a document method such as querySelector or getElementById.
<div id=”$testDiv”>Hello, World!</div> 
Enter fullscreen mode Exit fullscreen mode
console.log($testDiv.textContent); // “Hello, World!” 
Enter fullscreen mode Exit fullscreen mode

Is this a crazy idea? I would like to hear what others have to say in the comments below.

Top comments (3)

Collapse
 
artyprog profile image
ArtyProg

use data-id='xxx'

Collapse
 
tracygjg profile image
Tracy Gilmore

Thank you for your comment but I do not think your suggestion is applicable. We could use the data attribute to provide an identifier for a DOM element and use it to style it in CSS. It would be less Specific than an id attribute but still dedicated to styling the specific element, especially when the value of the attribute is included and assuming it is unique.

As for selecting DOM elements in JS code, using the data attribute would still require using the querySelector method, in fact that would be the only way as there is no getElementByAttribute method.

All that said, your comment has set me thinking about a couple of things (thank you).

1, Referencing DOM elements directly is generally not useful when using a JS framework that employs a virtual DOM because the reference is likely to be lost with subsequent updates of the DOM.

2, The fact that by prefixing the dollar symbol to an id attribute invalidates it as a CSS select also means we would be unable to use the querySelector method even if we wanted to. However, one of the benefits of using the prefix is we should not need either document method to select the element, it will already have been done.

Going back to my first thought, I have prepared a GitHub gist to demonstrate the point.

Thanks again for your comment, much appreciated.

Collapse
 
artyprog profile image
ArtyProg

My pleasure :-)