Xoog
Xoog

Reputation: 926

textContent and innerHTML not changing the DOM

Good morning,

I'm hoping someone can help me with this seemingly simple question. I can't figure out why my textContent or innerHTML won't update my DOM. It shows in my console that it has changed, but for some reason that escapes me I can't figure out why the DOM isn't changing. Any help is appreciated!

I have the following code

        function updateText() {

            document.querySelectorAll('.userRoleStyle').forEach(function (e) {

                var grabtext = e.textContent || e.innerHTML;

                if (grabtext === 'SUPER') {

                    grabtext = 'Super User';

                }
                console.log(grabtext);
            })
        };
    table td {
        padding: 10px;
    }
<body>
    <table>
        <thead>
            <tr>

                <th>Username</th>
                <th>Email address</th>
                <th>User Role</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>TEST1</td>
                <td>[email protected]</td>
                <td class="userRoleStyle">ADMINISTRATOR</td>
                <td>
                    <a href="#" onclick="updateText();">Test</a>
                </td>
            </tr>
            <tr class="userList">
                <td>TEST2</td>
                <td>[email protected]</td>
                <td class="userRoleStyle">ADMINISTRATOR</td>
                <td>
                    <a href="#" onclick="updateText();">Test</a>
                </td>
            </tr>
            <tr class="userList">
                <td>TEST3</td>
                <td>[email protected]</td>
                <td class="userRoleStyle">SUPER</td>
                <td>
                    <a href="#" onclick="updateText();">Test</a>
                </td>
            </tr>
        </tbody>
    </table>
</body>

Upvotes: 2

Views: 2119

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1075755

Nothing in your code changes what's in the DOM. Assigning to your grabText variable just changes the value of that variable, not the element you got the text from.

To do that, you'd havE to assign back to textContent/innerHTML.

Separately: innerHTML is very different from textContent. If you're going to feature-detect, use textContent and fall back to innerText, not innerHTML¹. When feature-detecting this, don't just use ||, it can pick the wrong one if the element's text is blank. Instead, look to see if the element has a property with the desired name. You only need to do it once and remember it.

var textPropName = "textContent" in document.createElement("div") ? "textContent" : "innerText";

function updateText() {
  document.querySelectorAll('.userRoleStyle').forEach(function(e) {
    if (e[textPropName] === 'SUPER') {
      e[textPropName] = 'Super User';
    }
  })
}

var textPropName = "textContent" in document.createElement("div") ? "textContent" : "innerText";

function updateText() {
  document.querySelectorAll('.userRoleStyle').forEach(function(e) {
    if (e[textPropName] === 'SUPER') {
      e[textPropName] = 'Super User';
    }
  })
}
table td {
  padding: 10px;
}
<body>
  <table>
    <thead>
      <tr>

        <th>Username</th>
        <th>Email address</th>
        <th>User Role</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>TEST1</td>
        <td>[email protected]</td>
        <td class="userRoleStyle">ADMINISTRATOR</td>
        <td>
          <a href="#" onclick="updateText();">Test</a>
        </td>
      </tr>
      <tr class="userList">
        <td>TEST2</td>
        <td>[email protected]</td>
        <td class="userRoleStyle">ADMINISTRATOR</td>
        <td>
          <a href="#" onclick="updateText();">Test</a>
        </td>
      </tr>
      <tr class="userList">
        <td>TEST3</td>
        <td>[email protected]</td>
        <td class="userRoleStyle">SUPER</td>
        <td>
          <a href="#" onclick="updateText();">Test</a>
        </td>
      </tr>
    </tbody>
  </table>
</body>


Side note: You don't put ; after function declarations. It's a statement terminator; declarations aren't statements. You'd have one after an assignment statement with a function expression, but not after a declaration. (It's harmless, though.)


¹ textContent and innerText are also different from one another, but the differences don't matter in your case.

Upvotes: 1

gurvinder372
gurvinder372

Reputation: 68443

innerHTML and textContent are basically setters and getters. Getting their reference in a variable and setting value to that reference will not invoke the setter.

You need to set value directly to them

e.textContent ? 
 ( e.textContent == 'SUPER' ? (e.textContent = 'Super User') : "" ) : 
 ( e.innerHTML == 'SUPER' ? (e.innerHTML = 'Super User') : "" ) 

Upvotes: 2

Piyush Bhati
Piyush Bhati

Reputation: 956

I have updated the snippet.

You were not assigning the Super User value to e.textContent inside if condition

function updateText() {

            document.querySelectorAll('.userRoleStyle').forEach(function (e) {
           
                var grabtext = e.textContent || e.innerHTML;

                if (grabtext === 'SUPER') {

                    e.textContent = 'Super User';

                }
            })
        };
table td {
        padding: 10px;
    }
<body>
    <table>
        <thead>
            <tr>

                <th>Username</th>
                <th>Email address</th>
                <th>User Role</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>TEST1</td>
                <td>[email protected]</td>
                <td class="userRoleStyle">ADMINISTRATOR</td>
                <td>
                    <a href="#" onclick="updateText();">Test</a>
                </td>
            </tr>
            <tr class="userList">
                <td>TEST2</td>
                <td>[email protected]</td>
                <td class="userRoleStyle">ADMINISTRATOR</td>
                <td>
                    <a href="#" onclick="updateText();">Test</a>
                </td>
            </tr>
            <tr class="userList">
                <td>TEST3</td>
                <td>[email protected]</td>
                <td class="userRoleStyle">SUPER</td>
                <td>
                    <a href="#" onclick="updateText();">Test</a>
                </td>
            </tr>
        </tbody>
    </table>
</body>

Hope this will help

Upvotes: 1

Related Questions