0

<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?

6
  • 1
    It must be that this isn't a valid way of writing to the DOM. Use setAttribute instead - developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute Commented May 19, 2022 at 18:16
  • huh. interestingly enough, in Firefox (as opposed to Chrome) it prints the alpha twice, as expected. Commented May 19, 2022 at 18:18
  • 2
    I'd recommend using getAttribute() and setAttribute() for consistency. console.log(btn.getAttribute('onclick')); btn.attributes.getNamedItem("onclick").value = "beta()"; console.log(btn.getAttribute('onclick')); works as expected. Commented May 19, 2022 at 18:19
  • 1
    It happens because what you're attempting is not safe javascript - it will either yield the wrong result, or inconsistent results. Either way, stick to best practices - hence the recommendations Commented May 19, 2022 at 18:25
  • 1
    btn.attributes.getNamedItem("onclick") in firefox outputs the full developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap/… object, not just onclick="beta()". This seems to work as expected though: console.log(btn.attributes.getNamedItem("onclick").value) ; btn.attributes.getNamedItem("onclick").value = "beta()"; console.log(btn.attributes.getNamedItem("onclick").value) ; so it looks like it depends on which browser you're using. Commented May 19, 2022 at 18:34

1 Answer 1

1

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>

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.