Search code examples
javascripthtmldomhiddencustom-data-attribute

set/attach invisible/unseen attribute/value into html element through vanilla js


EDIT

why i try to achieve this ?

Encapsulation purpose. generally every programmer encapsulate his/her code. also think about encrypt url or slug url and programmer also use uuid (Universally unique identifier) instead of id (integer id).

END EDIT

I set data attribute as a id to my html element and when I console log or debug html element I can see the data id (1,2)....

I want if anyone debug my html he can not see my data id(1,2) ...

how I will do it invisible or unseeable ? or is there is a way do it invisible or unseeable ?

below example..

 const list = document.querySelectorAll('.item');
        for(let x = 0; x < list.length; x++){
            // list[x].setAttribute('data-id',(x+1));
            list[x].dataset.id = x+1;
            console.log( list[x]);
            list[x].addEventListener('click',goCategoryPage)
        }
       function goCategoryPage(e){
           e.preventDefault()
          //    
       }
<ul class="list">
        <li class="item">Category 1</li>
        <li class="item">Category  2</li>
    </ul>


Solution

  • The short and simple Answer is: Use something like list[x].myId = x+1; To set a custom property. As opposed to attributes, properties are not reflected in the DOM.

    This gets the job done. But is considered bad practice. Because there are some caveats:

    1. Your custom property today, might be a standard property in the future, but with a completely different meaning. To make sure this won't become an issue in the future, make sure to add a prefix like your apps name or at least "my" to your property.
    2. It is okay to store primitive data like numbers, booleans or strings this way. But you might get issues with memory leaks if you start storing more complex data. Especially if you start to store references to other DOM Nodes.

    More details on the topic of custom properties are discussed here: Can I add arbitrary properties to DOM objects? I think it is a question of personal taste and you really need to make sure you don't produce (future) name collisions and don't store complex data.

    For primitive data like your id, I don't see a reason not to store it as a data attribute. There should be nothing to be ashamed of. It also is quite hard to keep a secret in JavaScript in the Browser.

    There are two other approaches I'd consider if I had to store more complex data.

    1. Use a WeakMap. You keep your WeakMap in a central place. It has the DOM Node as key and your data as Value. If the Node is garbage collected your data is too.
    2. Create a new function (closure) for each node, which contains the ID and attach it to the click event of your Node. Event listeners are also garbage collected.

    Here details on the closure approach:

    const list = document.querySelectorAll('.item');
    for(let x = 0; x < list.length; x++){
        console.log(list[x]);
        list[x].addEventListener('click', function () {
            const id = x+1;
            e.preventDefault();
            // stuff to be done on click
        });
    }
    

    For each iteration of the loop, a new function (with a new closure) is created. Inside this closure the value of x is the value of x in the current iteration - where the function is created.