Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove all HTML tags inside of selection in contenteditable

I have a <div /> which is contenteditable and can contain several types of HTML elements such as <span />, <a />, <b />, <u /> and so on.

Now when I select text in my contenteditable I would like to have a button that removes all the styles within the selection.

Example 1:

The Selection:

Hello <b>there</b>. I am <u>a selection</u>

would become:

Hello there. I am a selection

Example 2:

The Selection:

<a href="#">I am a link</a>

would become:

I am a link

You get the idea...

I have found this helpful function https://stackoverflow.com/a/3997896/1503476 which replaces the current selection with custom text. But I just cannot get the content of the selection first and strip the tags out before replacing it. How can I do that?

like image 509
Horen Avatar asked Dec 14 '12 13:12

Horen


People also ask

How do I turn off Contenteditable in HTML?

Just set contentEditable="false" . See this answer.

How do I stop Enter key in Contenteditable?

To prevent contenteditable element from adding div on pressing enter with Chrome and JavaScript, we can listen for the keydown event on the contenteditable element and prevent the default behavior when Enter is pressed. to add a contenteditable div. document. addEventListener("keydown", (event) => { if (event.

How do I remove a tag from a string?

The HTML tags can be removed from a given string by using replaceAll() method of String class. We can remove the HTML tags from a given string by using a regular expression. After removing the HTML tags from a string, it will return a string as normal text.


1 Answers

The way I would do this is to iterate over the nodes within the selection and remove inline nodes (maybe leaving <br> elements alone). Here's an example, using my Rangy library for convenience. It works in all major browsers (including IE 6) but is not quite perfect: for example, it does not split partially selected formatting elements, meaning that a partially selected formatting element is completely removed rather than just the selected portion. To fix this would be more tricky.

Demo: http://jsfiddle.net/fQCZT/4/

Code:

var getComputedDisplay = (typeof window.getComputedStyle != "undefined") ?
    function(el) {
        return window.getComputedStyle(el, null).display;
    } :
    function(el) {
        return el.currentStyle.display;
    };

function replaceWithOwnChildren(el) {
    var parent = el.parentNode;
    while (el.hasChildNodes()) {
        parent.insertBefore(el.firstChild, el);
    }
    parent.removeChild(el);
}


function removeSelectionFormatting() {
    var sel = rangy.getSelection();

    if (!sel.isCollapsed) {
        for (var i = 0, range; i < sel.rangeCount; ++i) {
            range = sel.getRangeAt(i);

            // Split partially selected nodes 
            range.splitBoundaries();

            // Get formatting elements. For this example, we'll count any
            // element with display: inline, except <br>s.
            var formattingEls = range.getNodes([1], function(el) {
                return el.tagName != "BR" && getComputedDisplay(el) == "inline";
            });

            // Remove the formatting elements
            for (var i = 0, el; el = formattingEls[i++]; ) {
                replaceWithOwnChildren(el);
            }
        }
    }
}
​
like image 67
Tim Down Avatar answered Oct 26 '22 23:10

Tim Down