22

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"
nipponese
  • 2,633
  • 6
  • 30
  • 51

5 Answers5

14

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
  • 166,710
  • 24
  • 259
  • 294
  • 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
  • 2,515
  • 2
  • 19
  • 33
  • 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?](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
  • 14,411
  • 12
  • 82
  • 140
0

you should set the innerHTML value like

 var myDivValue = document.getElementById("my_div").innerHTML = "Hello";
david
  • 4,088
  • 3
  • 21
  • 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