This question already has answers here:
innerText vs innerHTML vs label vs text vs textContent vs outerText
(6 answers)
Closed 1 year ago.
I'm using plain js to alter the inner text of a label element, and I wasn't sure on what grounds I should use innerHTML or nodeValue or textContent. I don't need to create a new node or change the HTML elements or anything — just replace the text. Here's an example of the code:
var myLabel = document.getElementById("#someLabel");
myLabel.innerHTML = "Some new label text!"; // this works
myLabel.firstChild.nodeValue = "Some new label text!"; // this also works.
myLabel.textContent = "Some new label text!"; // this also works.
I looked through the jQuery source, and it uses nodeValue exactly one time but innerHTML and textContent several times. Then I found this jsperf test that indicates the firstChild.nodeValue is significantly faster. At least that's what I interpret it to mean.
If firstChild.nodeValue is so much faster, what's the catch? Is it not widely supported? Is there some other issue?
Differences between textContent/innerText/innerHTML on MDN.
And a Stackoverflow answer about innerText/nodeValue.
Summary
innerHTML parses content as HTML, so it takes longer.
nodeValue uses straight text, does not parse HTML, and is faster.
textContent uses straight text, does not parse HTML, and is faster.
innerText Takes styles into consideration. It won't get hidden text for instance.
innerText didn't exist in firefox until FireFox 45 according to caniuse but is now supported in all major browsers.
.textContent outputs text/plain while .innerHTML outputs text/html.
Quick example:
var example = document.getElementById('exampleId');
example.textContent = 'google';
output: google
example.innerHTML = 'google';
output: google
You can see from the first example that output of type text/plain is not parsed by the browser and results in the full content displaying. Output of the type text/html tells the browser to parse it before displaying it.
MDN innerHTML, MDN textContent, MDN nodeValue
The two I know well and work with are innerHTML and textContent.
I use textContent when I just want to change the text of a paragraph or heading like so:
var heading = document.getElementById('heading')
var paragraph = document.getElementById('paragraph')
setTimeout(function () {
heading.textContent = 'My New Title!'
paragraph.textContent = 'My second <em>six word</em> story.'
}, 2000)
em { font-style: italic; }
<h1 id="heading">My Title</h1>
<p id="paragraph">My six word story right here.</p>
So, textContent just changes the text, but it doesn't parse HTML, as we can tell from the tags visible in plain text in the result there.
If we want to parse HTML, we use innerHTML like this:
var heading = document.getElementById('heading')
var paragraph = document.getElementById('paragraph')
setTimeout(function () {
heading.innerHTML = 'My <em>New</em> Title!'
paragraph.innerHTML = 'My second <em>six word</em> story.'
}, 2000)
em { font-style: italic; }
<h1 id="heading">My Title</h1>
<p id="paragraph">My six word story right here.</p>
So, that second example parses the string I assign to the DOM element's innerHTML property as HTML.
This is awesome, and a big security vulnerability : )
(look up XSS if you want to know about security for this)
innerText is roughly what you would get if you selected the text and copied it. Elements that are not rendered are not present in innerText.
textContent is a concatenation of the values of all TextNodes in the sub-tree. Whether rendered or not.
Here is a great post detailing the differences
innerHTML should not be included in a comparison with innerText or textContent, as it is totally different, and you should really know why:-) Look it up separately
[Note: this post is more about sharing a specific data that might help someone than telling people what to do]
In case someone is wondering what's the fastest today:
https://jsperf.com/set-innertext-vs-innerhtml-vs-textcontent
& https://jsperf.com/get-innertext-vs-innerhtml-vs-textcontent (for the second test, the span's content is plain text, results might change according to its content)
It seems that .innerHtml is the great winner in terms of pure speed!
(NOTE: I'm only talking about speed here, you might want to look for others criteria before choosing which one to use!)
Element.innerHTML property to set, or get element's HTML code.
Ex: We have a <h1> tag and strong style with it:
<h1 id="myHeader" style="color: green"><strong>My Header</strong> Normal Text</h1>
To get content of the element has id equals to "myHeader", we will do the same:
var element = document.getElementById("myHeader");
element.innerHTML
Return result:
<strong>My Header</strong> Normal Text`
To "set" new content (value) for this element, the code will be here:
Element.innerHTML = "My Header My Text";
So this property not only works with plain text, but it is aimed at passing or copying HTML code.
=> We should not use it.
However, many programmers (including myself) use this attribute to insert text into a web page, and this method carries a potential risk:
Wrong operation: inserting each text only sometimes deletes all other HTML code of the inserted element.
For security: Of course, the two examples above are completely harmless, even if using the tag is still no problem because the HTML5 standard has prevented the execution of the command line inside the tag. when inserted into the web page via the innerHTML attribute. See this rule here.
Because of this reason, using innerHTML is not recommended when inserting plain text, instead use textContent. The textContent property will not understand that the code you pass is an HTML syntax, but just a 100% text no more and no less.
The result returns if using textContent in the above example:
My Header My Text
Related
This might be a newbie question for most of you but it was explained to me that innerText ONLY gets the element's text and it can't be modified using any HTML tags, while innerHTML does the same job and HTML can as well be used. So, what's the point in having all of them?
Advantages of textContent over innerHTML:
It works on all nodes, not only elements.
var node = document.createTextNode('hello');
node.innerHTML; // undefined
node.textContent; // 'hello'
It gets the text contents of an element, without having to strip HTML tags manually.
var el = document.createElement('div');
el.innerHTML = 'A<p>B<span>C</span>D</p>D';
el.textContent; // "ABCDD" (HTML tags stripped successfully)
It sets the contents of an element to a bunch of plain text, without having to HTML-escape it.
var el = document.createElement('div');
el.textContent = 'A<p>B<span>C</span>D</p>D';
el.children.length; // 0 (plain text HTML-escaped successfully)
Sure, when you use them on elements, innerHTML can be more powerful. But when you only care about the text content but not HTML content, textContent is simpler and likely to have better performance.
So we have both of them, and choose the most appropriate for each case.
If you have an element that's just supposed to contain text, without any HTML formatting, you can assign to .textContent and not have to worry about the string possibly containing characters that look like HTML. For instance, suppose you have an input field, and the user enters something into it, which you then put into a DIV. The user isn't supposed to be able to enter HTML in the input field, so you want to copy it literally. So you write:
div.textContent = input.value;
If you wanted to do this with .innerHTML, you would have to write something like:
div.textContent = input.value.replace(/</g, '<').replace(/&/g, '&');
to prevent HTML from being interpreted.
When reading from an element, you can use .textContent if you just want to get the plain text of it, and ignore any formatting. E.g. if you have
<div id="x">This is <strong>important</strong> stuff</div>
you would use document.getElementById("x").textContent to get just "This is important stuff", and not have to remove the <strong> tag yourself.
BTW, don't use innerText, it's nonstandard and not supported in FireFox.
Sadly, textContent does not work in IE 11. So far, innerHTML is pretty much the only one that consistently works on all browsers (I've tested my sites using it on 15+ versions of Firefox, several versions of IE (using virtualized Windows) and 20+ other browsers (including ones no one else has heard of). It works on every platform I've tried: Windows, Linux, OS X, Android, iOS.
I understand the potential security issues. This is why you always verify inputs into a form before posting them (and check them again if they are passed to another page for processing).
I am currently learning Javascript DOM and innerHTML and found some problems in understanding innerHTML.
Here are my codes: http://jsfiddle.net/hphchan/bfjx1w70/1/
I have learnt standard DOM method and innerHTML methods and it works fine, BUT I don't know why it is wrong to code the following:
// this method fails
var element2 = document.createElement('p');
element2.innerHTML = "hello <em>Herbert</em>";
// standard methods of innerHTML method I learnt from textbook, BUT it requires to type tags in HTML
var element3 = document.getElementById('el');
element3.innerHTML = "innerHTML: hello <em>Herbert</em>";
I want to ask why it does not work for the first method. What is the problem of doing in this way? In addition, what if I don't want to type anything (including tags) in HTML and want to use innerText to fulfil the same output as what the JSFiddle shows "hello Herbert"?
The main error is the innerText usage. For most purposes, I would stay away from that in general, as innerHTML works for both situations. (text and markup)
Although I suppose innerText has it's charms if you want to display HTML code as it is rather than render it.
So, because you have an HTML tag inside the string, it's not a normal text node. If you simply used 'hello Herbert' instead of 'hello Herbert' it would work.
var element2 = document.getElementById('el');
element2.innerText = "hello Herbert";
<p id='el'></p>
The other problem is though you have the element, until you have actually put it in the DOM, it is useless, which is why example 2 isn't working.
Try
document.body.appendChild(element2);
So,
var element2 = document.createElement('p');
element2.innerHTML = "hello <em>Herbert</em>";
document.body.appendChild(element2);
Hope it helps! Look at http://www.w3schools.com/jsref/met_node_appendchild.asp for more info.
Because "hello <em>Herbert</em>" contains html tag (em) so innerText won't work but innerHTML work.
The text "hello <em>Herbert</em>" is not exactly a text, as it has HTML Content in it. You really need to use innerHTML for this case:
element2.innerHTML = "hello <em>Herbert</em>";
With innerText you can only apply plain Strings without formatting to an element. Useful in a dynamic function if you don't want that the text inside an element gets formatted. If it contains tags, they will be just shown as plain text. With innerHTML you can add anything to that element, including HTML-Tags.
EDIT: Now I've just seen that your problem was that the element wasn't even displaying at all, I just thought you wonder why Herbert didn't got italic. In this case it's because you didn't append the 2nd element to the body, like you did in the first version. The third version isn't creating an element, it uses an existing one, therefore you don't need to append it. ;)
I am having trouble getting the contents of a textarea with js. I feel like I've done this many times before without problems but something is throwing it off or I have a mental block.
html
<textarea id="productdescript">test copy..asdfd</textarea><button value="Enter" onclick="addProduct()">
js
function addProduct() {
var descript = document.getElementById('productdescript').textContent;
alert(descript);
}
Firefox is the only browser I have currently.
When I use textContent, the alert box appears but it is blank.
When I use value, the alert box appears and says "Undefined"
When I use innerHTML, all the HTML appears including the tags.
Also, I understand that textContent only runs in FF and for cross browser compatibility you need to do something like innerText and textContent but textContent is not working in FF. There is no jquery on this app
What is the correct cross browser way to get contents of textarea! Thanks for any suggestions.
For textarea, you could only use .value in your scenario (I tested your given code and it works fine).
.
Also,
1) keep in mind that you call this function addProduct() ONLY after your element is mentioned in the code, otherwise it will be undefined.
2) there must not be another element with id as productdescript
3) there must not be a JS variable called productdescript
This are your code?
you write document.getElementByID.... and the "D" should be written lowercase "d"
document.getElementById('productdescript').textContent;
In IE when i set div's innerHTML as:
<abc>1<abc>
the innerHTML will be convert to:
1</ABC>
because 'abc' is a custom tag. But if i set:
1<abc>2</abc>
the innerHTML will keep the 'abc' tag, so the innerHTML is:
1<ABC>2</ABC>
Ask for the description of the behavior.
... I see. You're wondering why it removes the opening tag when you set an element's innerHTML to 1 and it keeps it when you prepend the innerHTML with a number...
lesser IE that does not support html5 tags will behave oddly. In this case it is likely interpreting the second case as a string where as the first case it is seeing it as an invalid tag and just plain erroring.
try this if you use jQuery -
instead of doing something like
$('#some_element').html('<abc>1</abc>'); // equal to document.getElementById('some_element').innerHTML = '<abc>1</abc>';
try
(function(){if(!/*#cc_on!#*/0)return;var e = "abc,other_custom_tags".split(',');for(var i=0;i<e.length;i++){document.createElement(e[i])}})(); // add the custom tag
var elem = $('<abc>');
elem.html('1');
$('#some_element').html(elem);
and declare abc as a valid tag in your css:
abc{
display:block;
}
of course, this assumes you know that abc will be a tag used on your site. if the potential tag is unknown then this may not be of much use.
The behaviour of the innerHTML property is not standardised (though some attempt has been made in HTML5). It is implemented differently in different browsers.
How would I get the raw HTML of the selected content on a page using Javascript? For the sake of simplicity, I'm sticking with browsers supporting window.getSelection.
Here is an example; the content between both | represent my selection.
<p>
The <em>quick brown f|ox</em> jumps over the lazy <strong>d|og</strong>.
</p>
I can capture and alert the normalized HTML with the following Javascript.
var selectionRange = window.getSelection().getRangeAt(0);
selectionContents = selectionRange.cloneContents(),
fragmentContainer = document.createElement('div');
fragmentContainer.appendChild(selectionContents);
alert(fragmentContainer.innerHTML);
In the above example, the alerted contents would collapse the trailing elements and return the string <em>ox</em> jumps over the lazy <strong>d</strong>.
How might I return the string ox</em> jumps over the lazy <strong>d?
You would have to effectively write your own HTML serialiser.
Start at the selectionRange.startContainer/startOffset and walk the tree forwards from there until you get to endContainer/endOffset, outputting HTML markup from the nodes as you go, including open tags and attributes when you walk into an Element and close tags when you go up a parentNode.
Not much fun, especially if you are going to have to support the very different IE<9 Range model at some point...
(Note also that you won't be able to get the completely raw original HTML, because that information is gone. Only the current DOM tree is stored by the browser, and that means details like tag case, attribute order, whitespace, and omitted implicit tags will differ between the source and what you get out.)
Looking at the API's, I don't think you can extract the HTML without it being converted to a DocumentFragment, which by default will close any open tags to make it valid HTML.
See Converting Range or DocumentFragment to string for a similar Q.