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?

user570494
  • 557
  • 3
  • 8
  • 14

5 Answers5

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());
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 1
    What if I wanted the text after the text which is selected, in a textarea? – Lucas Aug 22 '13 at 09:24
  • @think123: `textarea.value.slice(textarea.selectionEnd)`, except in IE <= 8 (I've posted a solution for old IE textarea selections on SO before). – Tim Down Aug 22 '13 at 09:34
  • 1
    The problem with this solution is that when you select the caps-locked part of

    first paragraph TEXT TO

    BE SELECTED second paragraph

    you don't get expected "TEXT TO

    BE SELECTED" but "

    TEXT TO

    BE SELECTED

    - 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?
    – HonzaBé Aug 08 '15 at 06:20
  • I have noticed that the result of `getSelectionHtml()` includes additional line breaks - apart from that this is a great fix! – James Poulose Mar 29 '18 at 16:14
  • 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? – Alex from Jitbit May 07 '20 at 10:18
30

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

Community
  • 1
  • 1
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;
}
Alex
  • 9,250
  • 11
  • 70
  • 81
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;
}
nkkollaw
  • 1,947
  • 1
  • 19
  • 29
-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');
Vikram Deshmukh
  • 12,304
  • 4
  • 36
  • 38
Igor G.
  • 6,955
  • 6
  • 26
  • 26