确定当前文本选择包含哪些 DOM 元素

Posted

技术标签:

【中文标题】确定当前文本选择包含哪些 DOM 元素【英文标题】:Determine which DOM elements the current text selection contains 【发布时间】:2011-02-01 12:37:38 【问题描述】:

我希望能够找出用户在浏览器中当前选择的文本中存在哪些 DOM 元素。

document.getSelection() 会给我们当前选择的文本。但是我们如何确定这个文本选择中包含哪些 DOM 元素呢?

【问题讨论】:

【参考方案1】:

window.getSelection() 给你一个Selection 对象。使用selection.rangeCountselection.getRangeAt() 获取一个Range 对象,表示您想要的选择。

现在您可以从range.startContainer/startOffsetrange.endContainer/endOffset 中获取选择中的第一个和最后一个节点。然后,您可以在树上走来走去,以拾取这两个位置之间的所有元素,例如。使用来自this answer 的getElementsBetweenTree() 函数。

不幸的是,IE 的TextRange 模型与 W3 和 html5 标准完全不同,而且总体上更糟。它几乎不会轻易放弃开始和结束位置,也不是以任何可靠的方式。你得到的只是parentElement 告诉你共同的祖先,从那里你只能根据创建一个新的范围来猜测范围在哪里,然后在上面调用moveToElementText,然后用选择范围调用compareEndPoints。如果您需要知道确切的文本选择,然后根据 moveStart/moveEnd​ing 范围和比较来猜测,这一点都不好玩。

【讨论】:

IERange (code.google.com/p/ierange) 在从 TextRange 创建类似 DOM Range 的对象方面做得很好。我在我的项目中使用了我自己对 IERange 算法的略微修改版本。 看起来不错。 (找到边界的关键位在TextRangeUtils.convertToDOMRange。)它不会完全替代 Range,因为 IE TextRanges 不会像 Range 应该的那样尊重元素边缘周围的范围边界,但这可能很好一般情况下就够了。 是的,同意。我不确定总体上是否可以做得更好,并且它在我使用它的所有方面都运行良好。你能想到区分边界是在一个元素的边缘还是在它的子元素的边缘是至关重要的任何情况吗? (例如,|<div><em>Text</em></div><div>|<em>Text</em></div><div><em>|Text</em></div> 是的,我认为这是您能做的最好的事情。这对我的一些富编辑器来说是个问题,尤其是空元素。希望能从 Range 上的 IE9 中获得一些迟来的快乐! WebKit 也有问题:您不能将插入符号放在空元素内或任何文本节点的开头 (bugs.webkit.org/show_bug.cgi?id=23189)。我最终编写了代码以将 Unicode BOM 字符插入(然后删除)到我希望用户能够在其中键入的空元素中,这既是一种难以形容的黑客行为,也是一种管理的痛苦。

以上是关于确定当前文本选择包含哪些 DOM 元素的主要内容,如果未能解决你的问题,请参考以下文章

使用服务器端包含,选择当前导航元素的选项都有哪些?

JS基础与DOM操作

使用 Selenium Webdriver 通过它包含的文本选择一个元素

查找带有文本的元素,然后在其上方的许多级别中选择元素

如何确定在 EditText 中选择了哪些文本? [复制]

使用 jQuery 在变量中而不是在当前 DOM 中选择内容?