Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert innerHTML of a contenteditable text to normal string

I use a content-editable element :

<span id="myinput" contenteditable="true">This is editable.</span>

and

document.getElementById('myinput').innerHTML

to read its content from Javascript.

But the result is :

  • "blah " => innerHTML = "blah &nbsp "

  • "bonjour\n bonsoir" => innerHTML = "bonjour<br>bonsoir" (Firefox) and innerHTML = "bonjour<div>bonsoir</div>" (Chrome)

  • maybe there are lots of other things that are translated into HTML...

How to convert innerHTML into normal text?

(i.e. in my 2 examples : "blah " and "bonjour\n bonsoir")

like image 585
Basj Avatar asked Sep 17 '14 13:09

Basj


People also ask

Why you shouldn't use innerHTML?

'innerHTML' Presents a Security Risk The use of innerHTML creates a potential security risk for your website. Malicious users can use cross-site scripting (XSS) to add malicious client-side scripts that steal private user information stored in session cookies.

What is the difference between innerHTML and inner text?

innerText returns all text contained by an element and all its child elements. innerHtml returns all text, including html tags, that is contained by an element.


2 Answers

Try using;

// for IE
document.getElementById('myinput').innerText

// for everyone else
document.getElementById('myinput').textContent

In terms of finding linebreaks, etc, consider;

el = document.getElementById('myinput');
var nodes = el.childNodes;
var text = '';

for(var i = 0; i < nodes.length; i++) {                        
    switch(nodes[i].nodeName) {
        case '#text'    : text = text + nodes[i].nodeValue;   break;
        case 'BR'       : text = text + '\n';      break;
    }
}
console.log(text);
like image 165
EvilEpidemic Avatar answered Nov 15 '22 18:11

EvilEpidemic


Due to the fact this behaviour is not consistent in different browsers, you have to implement this yourself:

var convert = (function() {
    var convertElement = function(element) {
        switch(element.tagName) {
            case "BR": 
                return "\n";
            case "P": // fall through to DIV
            case "DIV": 
                return (element.previousSibling ? "\n" : "") 
                    + [].map.call(element.childNodes, convertElement).join("");
            default: 
                return element.textContent;
        }
    };

    return function(element) {
        return [].map.call(element.childNodes, convertElement).join("");
    };
})();

In action: http://jsfiddle.net/koyd8h59/1/

Of course you'll need to add your own code if you want to use <h1> and other block-level tags.

like image 24
Bart Avatar answered Nov 15 '22 17:11

Bart