25

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"
user-id-14900042
  • 686
  • 4
  • 17
nipponese
  • 2,813
  • 6
  • 35
  • 51

8 Answers8

16

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.

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 1
    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"; – nipponese Nov 19 '11 at 18:40
  • 5
    @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. – ruakh Nov 19 '11 at 18:50
  • 1
    @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. – 0zkr PM Apr 11 '18 at 20:26
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
no_name_here
  • 136
  • 2
3

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.

Daniel Butler
  • 3,239
  • 2
  • 24
  • 37
  • 3
    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?](https://stackoverflow.com/q/10693845/215552)... – Heretic Monkey Sep 03 '19 at 01:27
  • 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. https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName – Daniel Butler Sep 03 '19 at 01:51
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];
kofifus
  • 17,260
  • 17
  • 99
  • 173
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>
bobt
  • 411
  • 3
  • 8
0

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!

Jamal Salman
  • 199
  • 1
  • 10
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

AJE
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34677627) – Amolgorithm Jul 17 '23 at 05:48
0

you should set the innerHTML value like

 var myDivValue = document.getElementById("my_div").innerHTML = "Hello";
david
  • 4,218
  • 3
  • 23
  • 25
  • you where setting myDivValue to return a string containing "Bye" and then Reassigned myDiVElem to equal "Hello" – david Nov 19 '11 at 18:51