Can't set innerHTML when using strings that start with '<' - javascript

I have a textarea that will populate another section with what the user inputs and my code works fine as long as I dont type anything starting with "<". Whenever I have a string like "<anything else can follow" that starts with "<", it wont set the innerhtml.
var text = "<i wont print"
text = "i will print!"
trans_txt.innerHTML = text;
Is "<" some kind of override character for innerhtml? I was wondering if anyone knew what was happening and if there is a way I could change the text var into purely string without having to worry about my string not showing up.
edit: I realized this because the default textarea message is "<text area"

<i followed by a space is HTML syntax for "Start an <i> (idiomatic/italic) tag" Since the parser doesn't see the end of the tag's definition (that is, a >), everything between the <i and the end is considered an error and dropped.
If you want to insert plain text only, use textContent instead:
var text = "<i wont print"
document.body.textContent = text;
textContent is also faster and safer. Only use innerHTML when deliberately inserting HTML markup.
Don't use innerText - best to prefer textContent instead in almost all situations.

Related

jQuery - escaping inline styles with HTML entities

I came across a curious problem when attempting to insert HTML edited by a Javascript editor (CKEditor) into some div. In the HTML to be inserted, double-quotes are replaced by the HTML entity " which works fine.
EXCEPT if the " appears in an inline style - then jQuery removes the entire inline sytyle.
I don't want them to be removed. I do prefer to keep the HTML entities if possible. The question is why does this happen? Any workaround?
In below example, I insert a text which should make the span red with regular quotes and with HTML-entity escaped quotes in an inline style.
The first line (div1) makes the span red, div2 is not red at all.
window.onload = function() {
$('#div1').html('<span style="color:red;">This text "here" is red</span>, while this is not.' );
$('#div2').html('<span style="color:red;">This text "here" is red</span>, while this is not.' ); }
See JSFiddle/L7cq2pfd here
jQuery inserts this as style=""color:red;"" - convert " to " with replace(/"/g, '"') before inserting as HTML :
$('#div2').html('<span style="color:red;">This text "here" is red</span>, while this is not.'.replace(/"/g, '"') );
http://jsfiddle.net/kb709s27/
Why? The automatically rendering of a " to " is a browser feature, not a javascript feature. jQuery seems to parse the inserted HTML and tries to correct malformed attributes. If you insert
$('#div2').html('<span style=color:red>');
then jQuery corrects this and inserts <span style="color:red">. In your case jQuery only see a malformed attribute and therefore tries to correct it, wrapping "color:red;" into quotes.

What's the use of textContent/innerText when innerHTML does the job better?

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).

nodeValue vs innerHTML and textContent. How to choose? [duplicate]

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

Preserving Linebreaks in textarea.value

I have to use textarea.value text but it does not preserve line breaks as input by the user. I don't want to use replace(/\n\r?/g, '<br />') trick as it is useful only to render text as html.
Is there any other way to access textarea.value as it is?
In this example http://jsfiddle.net/jfriend00/Gy7W3/, the text area is returning a linefeed character on the .value property everywhere the user enters a line break so it seems to already do what you want.

"<" sign not showing in javascript?

I have a div-element that I want to show the symbol '<'.
div-element.innerHMTL = '<';
The string actually do not appears, I think the problem lies in that the browser thinks that it is a beginning of a tag element
Anyone seen this problem before?
You should use an HTML entity - <. This will be displayed by the browser as <, rather than being interpreted as the start of an HTML tag.
Here's a handy list of common HTML entities: http://www.danshort.com/HTMLentities/
divElement.innerHTML = '<';
innerHTML sets does not encode and can be used to set html elements.
innerText sets encodes and cannot be used to set html elements.
You should use innerText when you just want to set text or you should encode the text when you want to mix html with text
This might be useful link which shows all symbols
http://www.w3schools.com/HTML/html_entities.asp

Categories