如何使用 html 标记从 window.getSelection().getRangeAt(0) 包装文本选择?

IT技术 javascript jquery dom
2021-03-17 08:24:06

如何从 window.getSelection().getRangeAt(0) 中选取一个选项并用 HTML 标记(例如“span”或“mark”)包围它?我更喜欢直接的 javascript 或 jQuery 解决方案。

我能够使用警报输出选定的文本,但还没有弄清楚如何用附加标记包围它。我已经看到很多在选择上运行 execCommand 的例子,但这不是我想要的。

jsfiddle 中查看我的工作示例

有任何想法吗?谢谢

3个回答

如果选中的文本全部包含在单个文本节点中,则可以使用surroundContents()Range方法。但是,这在一般情况下不起作用。要做的事情是将范围内的每个文本节点包围在一个<span>. 我的Rangy库有一个module可以执行此操作并跨浏览器工作(IE <= 8 本身不支持 DOM Range)。

使用 Rangy 的示例代码:

<style type="text/css">
    span.highlighted {
        background-color: yellow;
    }
</style>
<script type="text/javascript">
    var highlightApplier;

    window.onload = function() {
        rangy.init();
        highlightApplier = rangy.createCssClassApplier("highlighted ", true);
    };

    function applyHighlight() {
        highlightApplier.applyToSelection();
    }
</script>
比我自己的(hack-ish)尝试更好的解决方案...... +1 :)
2021-04-28 08:24:06
关于 aroundContents() 的有趣点。我需要尝试一些不同的场景,看看它是如何工作的。我会看看你的图书馆。谢谢!
2021-05-02 08:24:06

(根据我发布我的帖子时发现的类似问题回答我自己的问题......)

这个问答线程中的人走在一条有趣的轨道上。它只是使用了与我所寻找的不同的格式。修改他们的代码,我能够做到以下几点:

<h3><a href="#" id="btnRange">Display Range</a> |
<a href="#" id="btnMark">Mark Range</a></h3>

<div contenteditable="true" id="editor">
    This is sample text. You should be able to type in this box or select anywhere in this div and then click the link at the top to get the selected range.
</div>

<script type="text/javascript">
    var btnDisplay = $("#btnRange"),
        btnMark = $("#btnMark");

    btnDisplay.click(function() {
        alert(window.getSelection().getRangeAt(0));
        return false;
    });

    btnMark.click(function() {
        var range = window.getSelection().getRangeAt(0);
        var newNode = document.createElement("mark");
        range.surroundContents(newNode);
        return false;
    });

我可以进一步抽象 btnMark.click() 函数中的代码以接受标签名称,然后创建一行按钮以使用 mark、pre、blockquote 标记代码。

可以在此处找到有效的解决方案:http : //jsfiddle.net/3tvSL/

虽然这在我的超级简单的纯文本示例中效果很好,正如 Tim Down 的另一个答案中所述,“如果所选文本都包含在单个文本节点中,您可以使用 Range 的 aroundContents() 方法。但是,在一般情况下不起作用。”
2021-05-02 08:24:06

首先获取范围:

var savedRange;
savedRange = window.getSelection().getRangeAt(0);

在按钮上单击:

   function formatCode(e){
        var textAreaVal = document.getElementById('divWithContentEditable').innerText;
        if(textAreaVal.length>0){
            var newtxt = '<pre><code>'+savedRange+'</code></pre>'
            replaceIt($('#topicDetails')[0], newtxt);
        }
    }

添加/替换文本周围的元素:

replaceIt(txtarea, newtxt) {
    $(txtarea).text(newtxt));  
}

当然,您可以使用Rangy,但我发现不建议为简单要求添加额外的500kb