如何获得dom范围内的所有文本节点?

时间:2022-03-22 08:44:16

I am working with a real time editor and need to find all text nodes that are inside the range a user has selected.

我正在使用实时编辑器,需要查找用户选择范围内的所有文本节点。

Example (the "|" marks the selection range start and end point):

示例(“|”标记选择范围开始和结束点):

<p>Here starts the |selection.</p>
<p>This is fully in the range.</p>
<p>This only |partial.</p>

How do i find all those nodes? (i do not want to find the textnode "Here" in case there is more than one textnodes in the first paragraph! (there could be several!))

如何找到这些节点?(我不想在这里找到“这里”的文本节点,因为第一段中有多个textnode !)(可能有几个!))

3 个解决方案

#1


9  

Rangy (disclosure: written by me) does this for you:

兰吉(披露:我写的):

range.getNodes([3]); // 3 is Node.TEXT_NODE

Otherwise, I'd suggest traversing the DOM of the range's commonAncestorContainer and for each text node encountered, check whether it overlaps the range by creating a range for the text node (using selectNode()) and using its compareBoundaryPoints() method to compare it to the selection range.

否则,我建议遍历范围的commonAncestorContainer的DOM,并针对遇到的每个文本节点,通过为文本节点(使用selectNode())创建范围并使用其compareboundary()方法将其与选择范围进行比较,检查它是否与该范围重叠。

#2


4  

Assuming you are interested only in eliminating the text nodes that are not selected, this might work for you.

假设您只对没有选中的文本节点感兴趣,这可能对您有用。

 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);

This gives the string "selection." and leaves off the text that is not selected. You can do the same thing with range.endContainer Now you can create text nodes using this text if you are interested in nodes and not the text that is selected.

这将给出字符串“selection”,并删除未选中的文本。你可以用range做同样的事情。现在,如果您对节点感兴趣,而不是选中的文本,则可以使用该文本创建文本节点。

#3


0  

Hey firend try below code

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

    <!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> * for Marijuana.</li>
    <li>At White House, Israel's Netanyahu pushes back against Obama diplomacy.</li>
</ol>
</div>
</body>
</html>

#1


9  

Rangy (disclosure: written by me) does this for you:

兰吉(披露:我写的):

range.getNodes([3]); // 3 is Node.TEXT_NODE

Otherwise, I'd suggest traversing the DOM of the range's commonAncestorContainer and for each text node encountered, check whether it overlaps the range by creating a range for the text node (using selectNode()) and using its compareBoundaryPoints() method to compare it to the selection range.

否则,我建议遍历范围的commonAncestorContainer的DOM,并针对遇到的每个文本节点,通过为文本节点(使用selectNode())创建范围并使用其compareboundary()方法将其与选择范围进行比较,检查它是否与该范围重叠。

#2


4  

Assuming you are interested only in eliminating the text nodes that are not selected, this might work for you.

假设您只对没有选中的文本节点感兴趣,这可能对您有用。

 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);

This gives the string "selection." and leaves off the text that is not selected. You can do the same thing with range.endContainer Now you can create text nodes using this text if you are interested in nodes and not the text that is selected.

这将给出字符串“selection”,并删除未选中的文本。你可以用range做同样的事情。现在,如果您对节点感兴趣,而不是选中的文本,则可以使用该文本创建文本节点。

#3


0  

Hey firend try below code

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

    <!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> * for Marijuana.</li>
    <li>At White House, Israel's Netanyahu pushes back against Obama diplomacy.</li>
</ol>
</div>
</body>
</html>