Setting innerHTML: Why won't it update the DOM?
Asked Answered
E

8

27

Wondering why I can't get document.getElementById("my_div").innerHTML to update the DOM when I re-assign the variable. For example:

<div id="my_div" onclick="clicky();">
    Bye.
</div>
<script type="text/javascript" charset="utf-8">
    function clicky() {
        var myDivValue = document.getElementById("my_div").innerHTML;
        myDivValue = "Hello";
        console.log(myDivValue);
    }
</script>

In the log I can see the variable get re-assigned when I click, but the innerHTML of my_div remains unchanged. Why is this?


**After several years more experience...**

For those just starting out (like I was) and found yourself asking the same thing, there are two important concepts that need to be understood:

  1. Assign by reference: My mistake was that I thought var myDivValue = element.innerHTML would create a reference/address to innerHTML and every time I assigned a new value to that reference, I could just update content, but that's not how it works.
  2. Assign by value: Instead, I was simply making a copy of element.innerHTML value (which was blank) and assigning the value to myDivValue, then in myDivValue = "Hello";, I was assigning a new value to myDivValue, so of course it would never update element.innerHTML.

The confusing part: when using the assignment operator (=) in JS, it's not explicit that you're either assigning a reference or value ( var referenceName = reference_to_thing vs. var containerName = newValue),

As many have said in the answers, the right way to do this is to assign the document.getElementById("my_div") element to myDiv:

var myDiv = document.getElementById("my_div")

And now that I have a reference to the element called myDiv, I can update the innerHTML property whenever I like:

myDiv.innerHTML = "Hello" // innerHTML is now "Hello"
myDiv.innerHTML = "Goodbye" // Changed it to "Goodbye"
Ecosphere answered 19/11, 2011 at 18:29 Comment(4)
innerHTML returns a string, not a reference to the DOM.Poliomyelitis
Btw, you don't have to manually query for the element - just pass its reference to the handler by invoking it with a this argument.Poliomyelitis
Sorry, I don't understand how this works in this case. I tried console.log(document.this) but it only returns an Undefined.Ecosphere
<div id="my_div" onclick="clicky(this);"> and then function clicky ( elem ) { elem.innerHTML = ... Poliomyelitis
G
17

innerHTML evaluates to a string. I'm not sure why you would expect anything different. Consider this:

var a = 'foo'; // now a = 'foo'
var b = a; // now a = 'foo', b = 'foo'
b = 'bar'; // now a = 'foo', b = 'bar'

Re-assigning b doesn't change a.

Edited to add: In case it's not clear from the above, if you want to change innerHTML, you can just assign to it directly:

document.getElementById("my_div").innerHTML = "Hello";

You don't need, and can't use, an intermediary variable.

Galvanometer answered 19/11, 2011 at 18:33 Comment(3)
Ah, I think I get it. One cannot assign a variable to a property of an object, only the object. Is that correct? Seems like this works: var myDivValue = document.getElementById("my_div"); myDivValue.innerHTML = "Hello";Ecosphere
@nipponese: Re-assigning a variable won't affect whatever it was previously assigned to. To write var myDiv = document.getElementById("my_div"); myDiv.innerHTML = ...; would set the innerHTML property on the object that both myDiv and document.getElementById("my_div") designate; but, for example, var myDiv = document.getElementById("my_div"); myDiv = document.getElementById("other_div"); would not have any effect on document.getElementById("my_div"), it would just change myDiv to designate a different element-object.Galvanometer
@nipponese: just think that innerHTML is a property of string type: You can get or put a string on it. On the other hand, getElementById returns a reference, an object type, like you figure out.Guillema
G
8
 var myDivValue = document.getElementById("my_div").innerHTML;

stores the value of innerHTML, innerHTML contains a string value, not an object. So no reference to the elem is possible. You must to store directly the object to modify its properties.

var myDiVElem = document.getElementById("my_div");
myDiVElem.innerHTML = 'Hello'; // this makes the change
Galvez answered 19/11, 2011 at 18:36 Comment(0)
G
5

For people still struggling, make sure you're spelling the property right. As it is innerHTML and not innerHtml. It's so easy to get it wrong!

Glasgow answered 6/2, 2023 at 17:3 Comment(0)
P
4

For future googlers my problem was that I was calling the plural elements.

document.getElementsByClassName(‘class’).innerHTML

So it returned an Array not a single element. I changed it to the singular.

document.getElementByClassName(‘class’).innerHTML

That made it so I could update the innerHTML value.

Protostele answered 3/9, 2019 at 1:16 Comment(2)
This answer doesn't really have anything to do with innerHTML. Also, there is no function getElementByClassName so this wouldn't actually help. See What do querySelectorAll and getElementsBy* methods return?...Malkamalkah
I was referring to document.getElementsByClassName I was assuming it was called from an element. I’ve updated my answer for it. Incase there is any confusion there is a document.getElementsByClassName function. developer.mozilla.org/en-US/docs/Web/API/Element/…Protostele
G
0

you should set the innerHTML value like

 var myDivValue = document.getElementById("my_div").innerHTML = "Hello";
Gee answered 19/11, 2011 at 18:31 Comment(1)
you where setting myDivValue to return a string containing "Bye" and then Reassigned myDiVElem to equal "Hello"Gee
T
0

you need to reassign the element after setting innerHTML/outerHTML:

let indexInParent=[].slice.call(elem.parentElement.children).indexOf(elem);
elem.innerHTML=innerHTML;
elem=elem.parentElement.children[indexInParent];
Trave answered 26/8, 2016 at 3:58 Comment(0)
C
0

I had the same question (Setting innerHTML: Why won't it update the DOM?) but for my case, it's a different issue. My issue turned out to be using "InnerHtml" instead of "InnerHTML". The frustrating thing is that js would let you go ahead and run it without any warning whatsoever. For example with this code below, after click there's no error and console log will show that innerHtml got modified successfully. But yet on the html page, you see it still says "Bye".

<div id="my_div" onclick="clicky();">
    Bye.
</div>

<script type="text/javascript" charset="utf-8">
  function clicky() {
    document.getElementById("my_div").innerHtml="<div>Hello</div>";
    console.log(document.getElementById("my_div").innerHtml);
  }
</script>
Crimmer answered 26/12, 2022 at 18:58 Comment(0)
O
0

And having just wasted a couple of hours, I can also add that its critical not to accidentally have two elements with the same ID

Outcaste answered 12/7, 2023 at 8:32 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewDraughty

© 2022 - 2024 — McMap. All rights reserved.