Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-browser innerText for setting values

Let's say I have the following code:

<html>
  <head></head>
  <body>
   <div id="d">some text</div>

  <script type="text/javascript">
    var d = document.getElementByid('d');
    var innerText = d.innerText || d.textContent;

    innerText = 'new text';
  </script>
  </body>
</html>

And I want to change text value for the div tag with id='d'. Unfortunately the block code above doesn't work and the text content doesn't change.

It works if do the following recipe:

if (d.innerText) d.innerText = 'new text';
else d.textContent = 'new text';

But I dont like the recipe above because it's not compact.

Have you any suggestions why the first approach doesn't work?

like image 510
Erik Avatar asked Jul 25 '12 09:07

Erik


2 Answers

Instead of multiple assignments, you can grab the property and use that

var text = ('innerText' in d)? 'innerText' : 'textContent';
d[text] = 'New text';
like image 195
Gabriele Petrioli Avatar answered Sep 28 '22 06:09

Gabriele Petrioli


The first approach doesn't work because all it does is set the variable to the new value, it doesn't write the value to the element. The line

var innerText = d.innerText || d.textContent;

...sets the variable innerText to the value of the text property it finds, it's not a reference to the actual property itself.

You'll have to do the branch, e.g.:

var d = document.getElementById('d');
var msg = "new text";
if ("innerText" in d) {
    d.innerText = msg;
}
else {
    d.textContent = msg;
}

That feature-detects whether the browser uses innerText or textContent by looking for the existence of the property on the element (that's what the in operator does, check if an object has a property with the given name, even if that property is blank, null, undefined, etc.).

You can even write yourself a function for it:

var setText = (function() {
    function setTextInnerText(element, msg) {
        element.innerText = msg;
    }

    function setTextTextContent(element, msg) {
        element.textContent = msg;
    }

    return "innerText" in document.createElement('span') ? setTextInnerText : setTextTextContent;
})();

That does the feature-detection once, and returns a function any half-decent engine will inline for you.

Or alternately, if you want HTML markup in the message to be handled as markup (rather than literal text), you can just use innerHTML (which is consistent across browsers). But again, if you use innerHTML, markup will be processed which may not be what you want.


I find it useful to use a good JavaScript library to deal with these browser differences (and to provide a ton of useful further functionality), such as jQuery, YUI, Closure, or any of several others. Obviously there's nothing you can do with a library you can't do without one, it's just a matter of standing on the shoulders of people who've done a huge amount of work already. :-)

In this case, for instance, using jQuery the above would be:

$("#d").text("new text");

That's it.

like image 42
T.J. Crowder Avatar answered Sep 28 '22 08:09

T.J. Crowder