使用 JQuery 检查所选文本是否是较大节点的一部分

Checking whether selected text is part of a larger node with JQuery

本文关键字:节点 一部分 是否是 文本 JQuery 检查 使用      更新时间:2023-09-26

我正在使用JQuery编写文档编辑器,并实现了基本的格式设置:选择文本,单击按钮,文本被适当的标签包围。

为了改善这一点,我现在需要检查选择前后的文本,以查看标签是否已打开等。有没有简单的方法来检查选择是否是较大节点的一部分?

例如,如果我在以下文本中选择"跳转"并单击,正确的行为是取消<strong>它,因为它已经在<strong>节点中。

The <strong>quick brown fox jumps over the lazy dog</strong>.

将其包装在临时标记中,使其成为可选的 DOM 元素

The <strong>quick brown fox <tmp>jumps</tmp> over the lazy dog</strong>.

然后调用临时标记的父标记,并将其与正在应用的标记进行比较。

var $tmp = $('tmp');
var enclosingTagType = $tmp.parent()[0].tagName;
if (enclosingTagType == requestedTagType {
  ....profit...
}

甚至

$tmp.closest(requestedTagType)

看看它是否被包裹了...

为了改善这一点,我现在需要检查选择前后的文本,以查看标签是否已打开等。有没有简单的方法来检查选择是否是较大节点的一部分?

(标记是打开的 [在 HTML 中,带有 <],但你真正的意思是元素是否已启动。这种差异对于您了解您在这里做什么至关重要。

由于文档中的节点是文档的一部分,并且文本节点最多只能是一个非文本节点的子节点,因此每个文本选择都是"较大节点的一部分"。 但是,您是否能够找出该节点是什么,以及它是否容易做到取决于您的能力和浏览器,因为它取决于浏览器布局引擎使用的 DOM 实现。

例如,在基于 Gecko 的浏览器(如 Firefox)和基于 WebCore 的浏览器(如 Chrome/Google Chrome)中,您可以执行

var selection = window.getSelection();

在选择时。 在selection中,您将有一个对实现Selection(壁虎)或DOMSelection(WebCore)接口的对象的引用,该对象具有诸如anchorNode之类的属性,这些属性引用了实现Text接口的对象(请参阅MDN的Gecko DOM参考)。

该对象表示所选内容开头所属的文本节点,具有一个 parentNode 属性,该属性获取元素节点对象,并通过其 tagNamenodeName 属性获取元素类型名称:

var textParent = selection.anchorNode.parentNode;
var textParentType = textParent.nodeName;

然后,可以使用 textParent.parentNode 的值在文档树 aso 中再遍历一个级别。

anchorNodefocusNode 属性引用不同的文本节点对象时,必须格外小心,因为选择通常不仅跨越多个文本节点,而且跨越多个元素。 也就是说,在表格中,用户可以轻松地选择文本"foobar",如<td>foo</td><td>bar</td>

通过运行时功能测试和异常处理,您可以确定支持哪个接口,而无需求助于容易出错的浏览器嗅探。

例如,如果我在以下文本中选择"跳转"并单击,正确的行为是取消strong它,因为它已经在strong节点中。

您可能需要重新考虑这一点。也许你刚刚选了一个不好的例子,但strong元素中的strong元素可能有价值;内部元素的 CSS 属性不一定是多余的。 另一个示例是强调 em 元素中已有的文本,用户可能希望使用 strong 元素。

避免使用jQuery;你不需要它,仔细检查你甚至不需要它。

在这里,试试这个:

http://jsbin.com/asajuk/7/edit

var getSelectedNode = function ()
    {
        var node, selection;
        if (window.getSelection)
        {
            selection = getSelection();
            node = selection.anchorNode;
        }
        if (!node && document.selection)
        {
            selection = document.selection
            var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange();
            node = range.commonAncestorContainer ? range.commonAncestorContainer : range.parentElement ? range.parentElement() : range.item(0);
        }
        if (node)
        {
            return (node.nodeName == "#text" ? node.parentNode : node);
        }
    };