Reputation: 1259
I'm trying to crate a Range Object by using
let range = document.createRange();
As you all know we must call
range.setStart(startNode,startOffset) ;
and
range.setEnd(endNode,endOffset);
I want to pass text nodes for both startNode and endNode, because if you pass a DOM node, you cannot specify custom offsets. My question is how can i get the text node of an element.
I just dont want just text as String, i want the text node.
suppose i have a paragraph
<p id="para">This is a paragraph</p>
i can get the DOM node by calling
let para = document.getElementById('para');
But how can i get the text node which is inside paragraph?
I want it as a text node, not like just a string. Please help.
Upvotes: 0
Views: 823
Reputation: 136627
To get the TextNode from
<p id="para">This is a paragraph</p>
you just need para.childNodes[0]
.
console.log(para.childNodes[0].nodeName, para.childNodes[0].textContent);
<p id="para">This is a paragraph</p>
However beware, if you actually had
<p id="para"><!--some comment-->
This is a paragraph
</p>
then this would return the CommentNode:
console.log(para.childNodes[0].nodeName, para.childNodes[0].textContent);
<p id="para"><!--some comment-->
This is a paragraph
</p>
And even, depending on how your element has been populated, you may very well have different TextNodes in the same element:
para.append('This ', 'is ', 'a ', 'paragraph');
console.log(para.childNodes[0].nodeName, para.childNodes[0].textContent);
<p id="para"></p>
So you'd probably want to iterate over each Nodes of the childNodes
NodeList, or simply call setStart on your Element since it's also allowed:
const range = document.createRange();
range.setStart(para,0);
range.setEnd(para, para.childNodes.length);
// which is actually the same as range.selectNode(para)
getSelection().addRange(range);
<p id="para">This is a paragraph</p>
And if you really need to walk along the TextNodes of your element, then consider using a TreeWalker with the NodeFilter.SHOW_TEXT
filter:
para.append('This ', 'is ', 'a ', 'paragraph');
function getNodeAtTextIndex(elem, index) {
const treeWalker = document.createTreeWalker(
elem,
NodeFilter.SHOW_TEXT,
null,
false
);
let str = '';
while(treeWalker.nextNode()) {
const node = treeWalker.currentNode;
str += node.textContent;
if(str.length >= index) return {
node: node,
index: node.length - (str.length - index)
};
}
return null;
}
const start = getNodeAtTextIndex(para, 2);
const end = getNodeAtTextIndex(para, 9);
const range = document.createRange();
range.setStart(start.node, start.index);
range.setEnd(end.node, end.index);
getSelection().addRange(range);
<p id="para"></p>
Upvotes: 3
Reputation: 841
Every DOMElement
has a childNodes
array-like object that you can access.
Try changing the textNode
value with
const textNode = document.querySelector('#para').childNodes[0];
Upvotes: 0
Reputation: 3427
You can use para.innerText
to get the value This is a paragraph
out.
Update: this should work for you.
const textNode = document.querySelector('#para').childNodes[0];
Upvotes: 0