如何获取DOM范围内的所有文本节点?

4
我是一名与实时编辑器一起工作的人,需要查找用户所选择的范围内的所有文本节点。
例如("|"标记为选择范围的起始点和终止点):
<p>Here starts the |selection.</p>
<p>This is fully in the range.</p>
<p>This only |partial.</p>

如何找到所有这些节点?(如果第一个段落中有多个文本节点,我不想找到文本节点“Here”!(可能会有几个!))


这个 SO 回答可能会有用 https://dev59.com/k3E95IYBdhLWcg3wDpmg#2477306 - Narendra Yadala
谢谢提供链接,但我不想扩大用户的选择。 - Thariama
3个回答

11

Rangy(声明:由我编写)可以为您完成此操作:

range.getNodes([3]); // 3 is Node.TEXT_NODE
否则,我建议遍历范围的commonAncestorContainer的DOM,并对遇到的每个文本节点进行检查,通过为文本节点创建一个范围(使用selectNode()),并使用其compareBoundaryPoints()方法将其与选择范围进行比较,来检查它是否与范围重叠。

Rangy听起来不错,但我需要尽可能少地使用库。对于非Rangy方法,我获取了commonAncestorContainer的所有textnodes,但我无法使函数工作,以确定给定的文本节点是否在范围内。有什么建议吗? - Thariama
1
@Thariama:这里的rangIntersectsNode()函数可能有帮助:https://dev59.com/tknSa4cB1Zd3GeqPO4g7#1483487 - Tim Down
我可以假设这是 3,就像 Node.ELEMENT_NODE 中的 3 一样吗? - Lori
1
@Lori: 好吧,它是 TEXT_NODE 而不是 ELEMENT_NODE。旧版本的IE(<= 8,我想)没有节点常量,因此我使用数字。 - Tim Down

5
假设您只想消除未被选择的文本节点,那么以下内容可能适用于您。
 var selectedTextOfFirstNode = '';
 //for simplicity assuming one selected range
 var range = window.getSelection().getRangeAt(0);
 if (range.startContainer.nodeType == 3)   
     selectedTextOfFirstNode = range.startContainer.textContent
                                           .substring(range.startOffset);

这会返回字符串 "selection.",省略未被选中的文本。如果你对节点感兴趣而不是选中的文本,你可以使用 range.endContainer 做同样的事情。现在你可以创建文本节点来使用这个文本。

0

嘿,朋友,尝试下面的代码:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>payam jabbari</title>
<script src="http://code.jquery.com/jquery-2.0.2.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function(){
    var startNode = $('p.first').contents().get(0);
var endNode = $('span.second').contents().get(0);
var range = document.createRange();
range.setStart(startNode, 0);
range.setEnd(endNode, 5);
var selection = document.getSelection();
selection.addRange(range);
// below code return all nodes in selection range. this code work in all browser
var nodes = range.cloneContents().querySelectorAll("*");
for(var i=0;i<nodes.length;i++)
{
   alert(nodes[i].innerHTML);
}
});
</script>
</head>

<body>
<div>

<p class="first">Even a week ago, the idea of a Russian military intervention in Ukraine seemed far-fetched if not totally alarmist. But the arrival of Russian troops in Crimea over the weekend has shown that he is not averse to reckless adventures, even ones that offer little gain. In the coming days and weeks</p>

<ol>
    <li>China says military will respond to provocations.</li>
    <li >This Man Has Served 20 <span class="second"> Years—and May Die—in </span> Prison for Marijuana.</li>
    <li>At White House, Israel's Netanyahu pushes back against Obama diplomacy.</li>
</ol>
</div>
</body>
</html>

该方法返回节点的克隆,而不是范围内实际的节点。 - moomoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接