javascript replace selection all browsers
Asked Answered
M

2

15

Is there a simple js function I can use to replace the current document's selection with some html of mine?

For instance say the document contains a <p>AHAHAHA</p> somewhere and user selects the 1st "ha" text chunk.

Now I want to replace this with something like: <span><font color="red">hoho</font></span>

When I google for *javascript replace selection * I can't get a simple straightforward answer!

Mummer answered 22/3, 2011 at 15:49 Comment(0)
V
26

Yes. The following will do it in all major browsers, with an option to select the inserted content afterwards as requested in the comments (although this part is not implemented for IE <= 8):

Live demo: http://jsfiddle.net/bXsWQ/147/

Code:

function replaceSelection(html, selectInserted) {
    var sel, range, fragment;

    if (typeof window.getSelection != "undefined") {
        // IE 9 and other non-IE browsers
        sel = window.getSelection();

        // Test that the Selection object contains at least one Range
        if (sel.getRangeAt && sel.rangeCount) {
            // Get the first Range (only Firefox supports more than one)
            range = window.getSelection().getRangeAt(0);
            range.deleteContents();

            // Create a DocumentFragment to insert and populate it with HTML
            // Need to test for the existence of range.createContextualFragment
            // because it's non-standard and IE 9 does not support it
            if (range.createContextualFragment) {
                fragment = range.createContextualFragment(html);
            } else {
                // In IE 9 we need to use innerHTML of a temporary element
                var div = document.createElement("div"), child;
                div.innerHTML = html;
                fragment = document.createDocumentFragment();
                while ( (child = div.firstChild) ) {
                    fragment.appendChild(child);
                }
            }
            var firstInsertedNode = fragment.firstChild;
            var lastInsertedNode = fragment.lastChild;
            range.insertNode(fragment);
            if (selectInserted) {
                if (firstInsertedNode) {
                    range.setStartBefore(firstInsertedNode);
                    range.setEndAfter(lastInsertedNode);
                }
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        // IE 8 and below
        range = document.selection.createRange();
        range.pasteHTML(html);
    }
}

Example:

replaceSelection('<span><font color="red">hoho</font></span>', true);
Villalpando answered 22/3, 2011 at 15:54 Comment(5)
Cool! Could u plz add a small amount of comments, like wich conditions are for IE and which for other browsers, thanks!Macbeth
Works on Safari 5.2.1 on snow leopard for me too. Thanks, i really looked for the ie9 thing!Castano
How to get this to maintain the selection? So that 'hoho' is selected after the operation.Cyna
@TimDown: Thanks, it works! Is it possible to prevent replacing if the selection length is zero? Now it adds hoho, if I only click something.Cyna
@Timo: Test window.getSelection().isCollapsed in browsers other than old IE and !!document.selection.createRange().text in old IE.Villalpando
A
7

You can use the Rangy library http://code.google.com/p/rangy/

You can then do

var sel = rangy.getSelection();
var range = sel.getRangeAt(0);

range.deleteContents();
var node = range.createContextualFragment('<span><font color="red">hoho</font></span>');
range.insertNode(node);
Anatol answered 24/5, 2012 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.