在文本选择之前/之后添加元素

问题描述:

我正在寻找允许我在选定文本之前或之后构建一些元素的功能.类似于 javascript替换所有浏览器的选择,但是在此之前或之后添加了一些内容选择而不是替换它,例如after()before() jQuery方法.我应该使用某种DOM选择方法吗(如果是的话)?还是存在更容易实现的东西?

I'm looking for function which allows me to build some element before or after selected text. Something similar like this one javascript replace selection all browsers but for adding some content before or after selection instead of replacing it, like after() and before() jQuery methods. Should I use some DOM selection method, if yes which one? Or does exist something easier to carry it out?

这里有一对函数可以做到这一点.

Here's a pair of functions to do this.

实时示例: http://jsfiddle.net/hjfVw/

代码:

var insertHtmlBeforeSelection, insertHtmlAfterSelection;

(function() {
    function createInserter(isBefore) {
        return function(html) {
            var sel, range, node;
            if (window.getSelection) {
                // IE9 and non-IE
                sel = window.getSelection();
                if (sel.getRangeAt && sel.rangeCount) {
                    range = window.getSelection().getRangeAt(0);
                    range.collapse(isBefore);

                    // Range.createContextualFragment() would be useful here but is
                    // non-standard and not supported in all browsers (IE9, for one)
                    var el = document.createElement("div");
                    el.innerHTML = html;
                    var frag = document.createDocumentFragment(), node, lastNode;
                    while ( (node = el.firstChild) ) {
                        lastNode = frag.appendChild(node);
                    }
                    range.insertNode(frag);
                }
            } else if (document.selection && document.selection.createRange) {
                // IE < 9
                range = document.selection.createRange();
                range.collapse(isBefore);
                range.pasteHTML(html);
            }
        }
    }

    insertHtmlBeforeSelection = createInserter(true);
    insertHtmlAfterSelection = createInserter(false);
})();