Home > OS >  Why JavaScript console prints inconsistent value?
Why JavaScript console prints inconsistent value?

Time:05-21

<body>
    <div id="wrap">
        <input type="button" id="btn" onclick="alpha"  value="ccc">
    </div>
    
    <script>
        
        console.log(btn.attributes.getNamedItem("onclick")) ;
        console.log(btn.attributes.getNamedItem("onclick").value) ;

        btn.attributes.getNamedItem("onclick").value = "beta()";
        function beta(){
            alert(`alpha changed to beta`);
        }

    </script>
</body>

About

console.log(btn.attributes.getNamedItem("onclick"));

This line prints onclick="beta()",

console.log(btn.attributes.getNamedItem("onclick").value);
This line prints alpha

Above two lines are identically written before the overwriting line
btn.attributes.getNamedItem("onclick").value = "beta()";

I think these two console.log() line should operate in same way

        console.log(btn.attributes.getNamedItem("onclick")) ;
        console.log(btn.attributes.getNamedItem("onclick").value) ;

Only difference is just second one prints first one's .value
But where these different result derived from?

CodePudding user response:

The short answer is that by logging onclick, you are logging the event object and with onclick.value you are logging the event handling callback reference (alpha).

Now, you are accessing the element in JavaScript via its id attribute directly, rather than with a DOM querying technique. When you give an element an id, it becomes a Global property of the window object and if you access it solely by the id, you are accessing a window property, which holds a reference to an object. window is not part of the DOM and therefore not standard.

However, if you access the element via document.querySelector(), which is a DOM querying method, you get back a DOM object and will see standard DOM properties.

The use of getNamedItem(), setAttribute(), and getAttribute() is not needed. Simply accessing the property directly will give you access to that data (i.e. btn.onclick = foo()).

Also, the use of event properties (like onclick) is discouraged. This is an older way of setting up events, but it's not as robust as the modern, standard of .addEventListener(), which is what you should be using.

Here's an example of the standards-based way of interacting with DOM elements. The following is standards-based code and will yield consistent results in all modern clients.

<body>
    <div id="wrap">
        <!-- Notice that the id and onclick attributes have been removed. -->
        <input type="button" value="ccc">
    </div>
    
    <script>
        // Instead of direct referencing elements via their id attribute,
        // use a standard DOM querying method to get a DOM element reference
        const btn = document.querySelector("input[type='button']");
        
        // Instead of wiring up elements to events in HTML with event attributes,
        // use the modern standard of .addEventListener() which allows for
        // multiple event handlers for any given event.
        btn.addEventListener("click", alpha);
        btn.addEventListener("click", beta);
        
        function alpha(event){
            // To access details about a DOM element, just access the 
            // property directly. In this event callback function, the 
            // object that fired the event can be referenced via its DOM
            // reference (btn), the event target (event.target), or the object
            // that caused the event callback to be called (this).
            console.log("Hello from alpha");
            console.log("You clicked: ", event.target);
            console.log("The element is a: ", this.nodeName);
            console.log("...with a type of: ", btn.type);
            console.log("...with a value of: "   event.target.value);
            console.log("The event being handled is: ", event.type);
            console.log("And the event object itself is: ", event);
        }
        function beta(){
            console.log("Hello from beta");
        }

    </script>
</body>

  • Related