javascript 在选择后插入 HTML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3597116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 01:39:21  来源:igfitidea点击:

Insert HTML after a selection

javascriptdom

提问by Lucy

I want to be able to double-click to select some text in a div, which then triggers a JavaScript function that inserts some HTML after the selected text, much like the 'edit/reply' feature in Google Wave.

我希望能够双击以选择 div 中的一些文本,然后触发一个 JavaScript 函数,在所选文本后插入一些 HTML,就像 Google Wave 中的“编辑/回复”功能一样。

I have already established how to trigger a function on double-clicking, it is locating the selection and subsequently inserting HTML after it that is the problem.

我已经确定了如何在双击时触发功能,它正在定位选择并随后在它之后插入 HTML,这就是问题所在。

回答by Tim Down

The following function will insert a DOM node (element or text node) at the end of the selection in all major browsers (note that Firefox now allows multiple selections by default; the following uses only the first selection):

下面的函数会在所有主流浏览器的选择末尾插入一个 DOM 节点(元素或文本节点)(注意 Firefox 现在默认允许多选;以下只使用第一个选择):

function insertNodeAfterSelection(node) {
    var sel, range, html;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.collapse(false);
            range.insertNode(node);
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.collapse(false);
        html = (node.nodeType == 3) ? node.data : node.outerHTML;
        range.pasteHTML(html);
    }
}

If you would rather insert an HTML string:

如果您更愿意插入 HTML 字符串:

function insertHtmlAfterSelection(html) {
    var sel, range, node;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = window.getSelection().getRangeAt(0);
            range.collapse(false);

            // 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) {
        range = document.selection.createRange();
        range.collapse(false);
        range.pasteHTML(html);
    }
}

Update 18 January 2012

2012 年 1 月 18 日更新

Finally, here's a version that inserts HTML and preserves the selection (i.e. expands the selection to include the originally selected content plus the inserted content).

最后,这是一个插入 HTML 并保留选择的版本(即扩展选择以包括最初选择的内容和插入的内容)。

Live demo: http://jsfiddle.net/timdown/JPb75/1/

现场演示:http: //jsfiddle.net/timdown/JPb75/1/

Code:

代码:

function insertHtmlAfterSelection(html) {
    var sel, range, expandedSelRange, node;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = window.getSelection().getRangeAt(0);
            expandedSelRange = range.cloneRange();
            range.collapse(false);

            // 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);

            // Preserve the selection
            if (lastNode) {
                expandedSelRange.setEndAfter(lastNode);
                sel.removeAllRanges();
                sel.addRange(expandedSelRange);
            }
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        expandedSelRange = range.duplicate();
        range.collapse(false);
        range.pasteHTML(html);
        expandedSelRange.setEndPoint("EndToEnd", range);
        expandedSelRange.select();
    }
}

回答by Bob

window.getSelection() will get you the selected text (Documentation). You can use the jQuery.after() (Documentation) to insert new html after an element.

window.getSelection() 将为您提供选定的文本(文档)。您可以使用 jQuery.after() (文档)在元素后插入新的 html。

On your selected text function call you will have to loop through all your DOM elements checking their x&y positions to the current cursor position - get the closest element and insert after or use the function .elementFromPoint(x,y) (Documentation)

在您选择的文本函数调用中,您必须遍历所有 DOM 元素,检查它们的 x&y 位置到当前光标位置 - 获取最近的元素并插入或使用函数 .elementFromPoint(x,y) (文档

This is the best way I can currently think of. It's not perfect, but it is somewhere to start.

这是我目前能想到的最好的方法。这并不完美,但它是一个开始的地方。

回答by BrunoLM

I don't know if it is possible, but I though of a partial solution.

我不知道是否有可能,但我认为是部分解决方案。

On your double click event you can get the event object and access the propertytarget.

在您的双击事件中,您可以获得事件对象并访问属性target

Having the target element, you can get the selected text.

有了目标元素,您就可以获得选定的文本

Now get the target element html and find the index of the selected text and it's length, inject your html on the index + lengthposition.

现在获取目标元素 html 并找到所选文本的索引及其长度,将您的 html 注入该index + length位置。

I think you already saw the problem, it could match the text in multiple places. To solve it you might have to find the position of the cursor and compare to the element, I don't know how to do that...

我想你已经看到了这个问题,它可以在多个地方匹配文本。要解决它,您可能必须找到光标的位置并与元素进行比较,我不知道该怎么做...

Hope I could help a bit.

希望我能帮上一点忙。