1

I'm testing behaviour of various browsers dating as far back as 2004. Some don't support the textContent property of DOM elements. This answer shows an elegant solution which works on IE8, but sadly not on earlier versions of IE, and not on Opera 8.5. Is there an alternative, which doesn't require Object.defineProperty, and which doesn't use __defineGetter__, __defineSetter__ as there are also not supported in Opera 8.5.?

At the moment I'm using this ugly workaround:

function setTextContent(el,s) {
    if (typeof el.textContent === 'undefined') {
        el.innerText = s;
    } else {
        el.textContent = s;
    }
}

and similarly for getting it.

EDIT:

As @LeroyStav suggested document.createTextNode can be used to set the text content. It doesn't provide an alternative for getting the text content, but if the element into with the newly created text node has no children, innerHTML would return the same thing. This works in IE7 and Opera 8.5, which are the oldest I've tested:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script charset="utf-8">
      window.onload = function () {
        var t = document.createTextNode('<'+'script>alert("foo")<'+'/script>');
        var cont = document.getElementById('foo'); // set the text content
        cont.appendChild(t);
        alert(cont.innerHTML); // get the text content (if no children)
      }
    </script>
  </head>
  <body>
    <div id='foo'></div>
  </body>
</html>
Aayla Secura
  • 271
  • 4
  • 12
  • It looks like setters and getters were introduced [in ES5](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set#Specifications), so functionality that depends on invoking a setter or getter may not be possible in extremely ancient browsers? (opera 8.5 = 2005) – CertainPerformance Jan 20 '19 at 00:41
  • "works on IE8, but sadly not on earlier versions of IE" I'm sorry, for what *possible* reason do you have to support browsers from 15 years ago??? IE 6 and 7 *together* make up .33% of total desktop browser share... *worldwide*... and I would put down a whole lot of money that the *vast* majority of *that* share is from Africa and South/East Asia. Seriously. Why are you looking to support anything that old? – Leroy Stav Jan 20 '19 at 01:01
  • @CertainPerformance I see... Any other ideas other than the workaround I added in my edit now? – Aayla Secura Jan 20 '19 at 01:08
  • 1
    @LeroyStav As I've already said in my post it is for testing purposes. Any further details are unnecessary. – Aayla Secura Jan 20 '19 at 01:09
  • It may be a silly thing to invest effort into implementing, but it's still an interesting puzzle to figure out IMO, how *did* these sorts of things work before setters and getters, maybe a browser-internal thing? Unfortunately, MDN's [compatibility tables](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText#Browser_compatibility) [2](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) don't seem to be accurate – CertainPerformance Jan 20 '19 at 01:30
  • Back then the js engines were simpler. No getters and setters so you simply had to code in a way that didn't require them. Computed properties were just .getMyComputedProperty() ... setters were just .setSomeProps(). You simply didn't use certain programming paradigms if the language didn't support them. Using ASP2.0? No lambdas for you, thank you. The question can't be "how did you do so and so?"... the answer is "we didn't" in the same way you can't ask "I'm testing behaviors of older processors and I noticed that the 486 didn't have any graphics capabilities. How do I do multiplex math?" – Leroy Stav Jan 20 '19 at 01:40
  • I was going to say you might use `.innerHTML` instead, parsing the tag characters into `<` and the like, but an [MDN table](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#Browser_compatibility) says that Opera didn't even support `.innerHTML` until Opera 9. – CertainPerformance Jan 20 '19 at 01:56
  • Maybe you could recursively iterate through `childNodes` and concatenate the `nodeValue` of text nodes... though that sounds quite ugly, makes me think there probably was a better way – CertainPerformance Jan 20 '19 at 02:05
  • @CertainPerformance indeed, if defining a property or method for `Element.prototype` is not an option, then the hackaround I posted (using a function and passing the element) is probably the least hassle. I was simply wondering if there was an elegant solution, but as @LeroyStav said there probably isn't. – Aayla Secura Jan 20 '19 at 02:08
  • If memory serves, @CertainPerformance is correct. Try .createTextNode(someStr) on the element. But again, this is silly. Also, if you really want to know how we did cross browser stuff back then, I have one word for you: jQuery. Before that, I have two words for you: Pain and Liquor – Leroy Stav Jan 20 '19 at 02:35

0 Answers0