使用 Rangy 库突出显示特定的父节点

Highlight specific parent nodes using Rangy library

我正在使用 Rangy 库来突出显示文本。当我使用下面的代码时,如果没有标签,它只是添加一个带有 class 注释的 span 标签,而当我在 span 标签之间 selecting 整个文本时,它只是分配 class 使用 highlighter.highlightSelection("note");.

到现有标签

现在我的要求是,我需要突出显示其父节点的整个文本,而不是突出显示 selected 文本。正如您在以下代码片段中看到的,我有一个带有 s-class 句子的 span 标记,它再次由使用一个或多个子 span 标记组成。现在我想,如果用户 select 子 span 标签中的一些文本比具有属性 s-class=sentence 的父标签应该突出显示。如果用户试图 select 跨多个父跨度标签的文本,则应突出显示受此 selection 影响的所有父标签。

<p>
<span s-class="sentence">
<span>Contrary to popular belief, Lorem Ipsum is not simply random text. </span>
</span>
<span s-class="sentence">
<span>It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. </span>
</span>
<span s-class="sentence">
<span>Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. </span>
</span>
<span s-class="sentence">
<span>Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. </span>
</span>
<span s-class="sentence">
<span>This book is a treatise on the theory of ethics, very popular during the Renaissance. </span></span>
<span s-class="sentence">
<span>The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet.."</span><span >, comes from a line in section 1.10.32.</span>
</span>
</p>

用例 1 => 用户 select 仅从第一个跨度“大众信仰,Lorem”开始测试,然后突出显示的 html 应该是-

<span s-class="sentence" class="note">
<span>Contrary to popular belief, Lorem Ipsum is not simply random text. </span>
</span>

用例 2 => 如果 select 来自两个或多个跨度(第一个和第二个)“ 随机文本。它有根 ” 然后结果突出显示 html 应该是 -

<span s-class="sentence" class="note">
<span>Contrary to popular belief, Lorem Ipsum is not simply random text. </span>
</span>
<span s-class="sentence" class="note">
<span>It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. </span>
</span>

用例 3 - 如果用户 select 在具有属性 s-class-"senetence" 的父标签内跨多个子元素的一些文本,则只需要突出显示该父标签.即用户 selects "sit amet.., comes" 那么结果 HTML 应该是 -

<span s-class="sentence" class="note">
<span>The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet.."</span><span >, comes from a line in section 1.10.32.</span>
</span>

我正在从 Word 文档转换此 HTML,然后制作句子,所以我想 select 所有受到 select 影响的句子,而不仅仅是突出显示的文本。

此外,当我取消突出显示时,selection 应该从这些父跨度中删除。

这应该适合你。

var selection = rangy.getSelection();
        if (selection.rangeCount > 0) {
            var range = selection.getRangeAt(0);
            var startNode = $(range.startContainer).closest("span[s-class=sentence]");
            var endNode = $(range.endContainer).closest("span[s-class=sentence]");
            $(startNode).addClass("selectionstart");
            $(endNode).addClass("selectionend");
            var rangeSel = $('span').rangeSelector();
            if(rangeSel!==undefined && rangeSel.length>0){
                $(startNode).addClass('note');
                $(endNode).addClass('note');
                rangeSel.addClass("note"); 
}}
//jquery extension method
$.fn.rangeSelector = function (options) {
    var settings = $.extend({ startClass: 'selectionstart', endClass: 'selectionend' }, options || {});
    var name = 'span';
    var startNode = name + '.' + settings.startClass;
    var endNode = name + '.' + settings.endClass;
    var parentNode = $(startNode).parent().closest("p");
    var startIndex = parentNode.find(startNode).index();
    var endIndex = parentNode.find(endNode).index();
    if ((startIndex === endIndex) || (endIndex === startIndex+1))
        return $('<span />');
    if (endIndex < 0)
        return undefined;
    var result = $(startNode).nextUntil(endNode);
    return result;
}