How to get selected html text with javascript? [duplicate]
Asked Answered
Y

5

41

I can use the following code to get selected text:

text=window.getSelection(); /// for Firefox text=document.selection.createRange().text; /// for IE

But how can I get the selected Html, which includes the text and html tags?

Yodle answered 13/4, 2011 at 2:1 Comment(1)
Rangy is now on GitHub.Eightieth
N
31

In IE <= 10 browsers, it's:

document.selection.createRange().htmlText

As @DarrenMB pointed out IE11 no longer supports this. See this answer for reference.


In non-IE browsers, I just tried playing with this... this seems to work, WILL have side effects from breaking nodes in half and creating an extra span, but it's a starting point:

var range = window.getSelection().getRangeAt(0),
  content = range.extractContents(),
     span = document.createElement('SPAN');

span.appendChild(content);
var htmlContent = span.innerHTML;

range.insertNode(span);

alert(htmlContent);

Unfortunately, I can't seem to put the node back as it was (since you can be pulling half the text from a span, for instance).

Northington answered 13/4, 2011 at 2:25 Comment(2)
You should use cloneContents() instead of extractContents()Pomeroy
also no one capitalizes HTML tags anymoreEachern
B
68

Here's a function that will get you HTML corresponding to the current selection in all major browsers. It also handles multiple ranges within a selection (currently only implemented in Firefox):

function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
}

alert(getSelectionHtml());
Bulgaria answered 12/7, 2011 at 17:8 Comment(5)
What if I wanted the text after the text which is selected, in a textarea?Fleta
@think123: textarea.value.slice(textarea.selectionEnd), except in IE <= 8 (I've posted a solution for old IE textarea selections on SO before).Bulgaria
The problem with this solution is that when you select the caps-locked part of <p>first paragraph TEXT TO</p><p>BE SELECTED second paragraph</p> you don't get expected "TEXT TO</p><p>BE SELECTED" but "<p>TEXT TO</p><p>BE SELECTED</p> - for some reason browser ads tags that are not in the selection in order to close the ones that are. Is there any way how to get only what really is in the selection?Fitted
I have noticed that the result of getSelectionHtml() includes additional line breaks - apart from that this is a great fix!Sholes
I run this function inside a loop and was wondering if .createElement can cause memory leaks... shouldn't we use container.remove(); to clean up or it will be GC collected anyway?Expectorant
N
31

In IE <= 10 browsers, it's:

document.selection.createRange().htmlText

As @DarrenMB pointed out IE11 no longer supports this. See this answer for reference.


In non-IE browsers, I just tried playing with this... this seems to work, WILL have side effects from breaking nodes in half and creating an extra span, but it's a starting point:

var range = window.getSelection().getRangeAt(0),
  content = range.extractContents(),
     span = document.createElement('SPAN');

span.appendChild(content);
var htmlContent = span.innerHTML;

range.insertNode(span);

alert(htmlContent);

Unfortunately, I can't seem to put the node back as it was (since you can be pulling half the text from a span, for instance).

Northington answered 13/4, 2011 at 2:25 Comment(2)
You should use cloneContents() instead of extractContents()Pomeroy
also no one capitalizes HTML tags anymoreEachern
N
6

Here's what I came up with. Tested with IE, Chrome, Firefox, Safari, Opera. Doesn't return empty string.

function getSelected() {
    var text = "";
    if (window.getSelection
    && window.getSelection().toString()
    && $(window.getSelection()).attr('type') != "Caret") {
        text = window.getSelection();
        return text;
    }
    else if (document.getSelection
    && document.getSelection().toString()
    && $(document.getSelection()).attr('type') != "Caret") {
        text = document.getSelection();
        return text;
    }
    else {
        var selection = document.selection && document.selection.createRange();

        if (!(typeof selection === "undefined")
        && selection.text
        && selection.text.toString()) {
            text = selection.text;
            return text;
        }
    }

    return false;
}
Nightlong answered 16/4, 2012 at 19:26 Comment(3)
This doesn't return HTML tags!Expellee
This seems to be the way how CTRL-C or CMD-C copies selections.Burgundy
This looses all current formatting(bold, italics, bg color etc.)Sholes
S
0

@zyklus:

I modified your function to work (I'm using jQuery but those pieces can be easily rewritten in Javascript):

function getSelectionHtml() {
    var htmlContent = ''

    // IE
    if ($.browser.msie) {
        htmlContent = document.selection.createRange().htmlText;
    } else {
        var range = window.getSelection().getRangeAt(0);
        var content = range.cloneContents();

        $('body').append('<span id="selection_html_placeholder"></span>');
        var placeholder = document.getElementById('selection_html_placeholder');

        placeholder.appendChild(content);

        htmlContent = placeholder.innerHTML;
        $('#selection_html_placeholder').remove();

    }


    return htmlContent;
}
Sorcery answered 25/1, 2014 at 12:46 Comment(0)
P
-3

I found highlight plugin to be the best match, it is very light and with it you can highlight part of the content:

$('li').highlight('bla');
Proscenium answered 24/2, 2014 at 22:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.