如何找到 DOM 文本选择的开始和结束索引?

Posted

技术标签:

【中文标题】如何找到 DOM 文本选择的开始和结束索引?【英文标题】:How to find start and end index of DOM text selection? 【发布时间】:2021-11-01 20:04:45 【问题描述】:

在 jQuery 终端中,我想添加一个返回所选内容索引的 API。

我拥有的示例 html

<div class="cmd" style="width: 100%; --cursor-line:1; top: 0px;">
    <div class="cmd-wrapper" style="">
        <span class="cmd-prompt" style="visibility: visible; margin-left: 0px;">
            <span data-text=">&nbsp;">
                <span style="width: 2ch;">&gt;&nbsp;</span>
            </span>
        </span>
        <div role="presentation" aria-hidden="true" class="cmd-end-line">
            <span data-text="H">
                <span>H</span>
            </span>
            <span data-text="e">
                <span>e</span>
            </span>
            <span data-text="l">
                <span>l</span>
            </span>
            <span data-text="l">
                <span>l</span>
            </span>
            <span data-text="o">
                <span>o</span>
            </span>
            <span data-text="&nbsp;">
                <span>&nbsp;</span>
            </span>
            <span data-text="W">
                <span>W</span>
            </span>
            <span data-text="o">
                <span>o</span>
            </span>
            <span data-text="r">
                <span>r</span>
            </span>
            <span data-text="l">
                <span>l</span>
            </span>
            <span data-text="d">
                <span>d</span>
            </span>
            <span data-text="&nbsp;">
                <span>&nbsp;</span>
            </span>
        </div>
        <div class="cmd-cursor-line" role="presentation" aria-hidden="true">
            <span>
                <span data-text="x">
                    <span>x</span>
                </span>
                <span data-text="x">
                    <span>x</span>
                </span>
                <span data-text="x">
                    <span>x</span>
                </span>
                <span data-text="x">
                    <span>x</span>
                </span>
                <span data-text="x">
                    <span>x</span>
                </span>
            </span>
            <span class="cmd-cursor" style="">
                <span data-text="" class="end">
                    <span>&nbsp;<span></span></span>
                </span>
            </span>
            <span></span>
        </div>
    </div>
    <textarea autocapitalize="off" spellcheck="false" tabindex="1" class="cmd-clipboard" data-cmd-prompt=">&nbsp;" style=""></textarea>
</div>

这是输入“Hello World\nxxxxx”并使用https://jsonformatter.org/html-pretty-print进行格式化和漂亮打​​印后的DOM复制粘贴

我的问题是我应该怎么做才能获得选择索引?

例如,我有一个这样的命令:

> He|lo wor|d

我应该得到[2, 8],如果选择超出范围:示例

>|>> Hello| world

&gt;&gt;&gt; 提示我应该得到[0, 5] 我不在乎是否定的。当整个选择都在外面时,我也应该处理

|>>>| Hello World

它应该返回 [0, 0] 或 null。

如何实现这样的事情?注意:我只关心window.getSelection API它是100%支持,不需要傻和支持 IE8。

【问题讨论】:

我不明白:window.getSelection (with it's start and end api) 不是答案吗? @ControlAltDel 你在哪里有选择的开始和结束API,我在MDN上没有看到它developer.mozilla.org/en-US/docs/Web/API/Selection 【参考方案1】:

你想要类似的东西

var range = window.getSelection().getRangeAt(0);
var start = range.startOffset;
var end = range.endOffset;

请注意,此代码假定 range.startContainer === range.endContainer(它经常这样做)。如果要获取起始容器和结束容器之间的文本/文本长度,则需要递归遍历它们之间的 DOM。还有一个问题是DOM中的文本长度与HTML中的文本长度不一样(浏览器有时会添加空格和其他HTML元素)

如果您猜到我已经在 J​​avascript 中进行了一系列选择,那么您是对的。 IMO 这是一场噩梦。 Tim Down 写了一个非常流行的包,叫做Rangy,我非常推荐它。您应该检查一下,看看它是否符合您所做的要求。

【讨论】:

【参考方案2】:

我自己解决了这个问题:

 var selection = window.getSelection();
 var start = $(selection.anchorNode);
 var end = $(selection.focusNode);

 var before = start.closest('.cmd [role="presentation"]').prevUntil('.cmd-prompt');
 var count = 0;
 if (before.length > 1) 
     count = before.find('[data-text]').length;
 
 var s = start.closest('.cmd [role="presentation"] [data-text]');
 var e = end.closest('.cmd [role="presentation"] [data-text]');

 if ((s.length || e.length)) 
     start = count + s.index();
     end = count + e.index() + 1;
     console.log(start, end);
 

【讨论】:

以上是关于如何找到 DOM 文本选择的开始和结束索引?的主要内容,如果未能解决你的问题,请参考以下文章

获取所选文本的开始和结束索引? [复制]

如何使用 javascript 在 getSelection() 中查找所选文本的索引?

如何使用Scala计算Spark中数据框中列的开始索引和结束索引之间的行的平均值?

DOM中文本节点索引方法

您如何根据偏好创建开始时间和结束时间选择器?

给定开始和结束索引,如何在 C 中复制字符串的一部分?