I have a html tag which is
<span>This is first text<span >Second</span> This is third text<span>
I am trying to get the start and end index from the selected text. When I select third
I get start and end index as 34 39
But I expect 27 32
I tried the below approach
export const findTextRange = (element) => {
if (!element) return;
let start = 0, end = 0;
let sel, range, priorRange, text;
if (typeof window.getSelection != "undefined") {
sel = window.getSelection();
text = sel '';
if (window.getSelection().rangeCount <= 0) {
return;
}
range = window.getSelection().getRangeAt(0);
priorRange = range.cloneRange();
priorRange.selectNodeContents(element);
priorRange.setEnd(range.startContainer, range.startOffset);
start = priorRange.toString().length;
end = start (sel '').length;
} else if (typeof document.selection !== "undefined" &&
(sel = document.selection).type !== "Control") {
text = sel '';
range = sel.createRange();
priorRange = document.body.createTextRange();
priorRange.moveToElementText(element);
priorRange.setEndPoint("EndToStart", range);
start = priorRange.text.length;
end = start (sel '').length;
}
return { start, end, text };
}
Is there any way where I can ignore the span
element with ignore
class.
CodePudding user response:
Store the initial HTML, then remove all elements having the .ignore
class:
const html = element.innerHTML;
element.querySelectorAll('.ignore').forEach((e) => e.remove());
After getting the range, restore the original HTML:
element.innerHTML = html;
Snippet
const findTextRange = (element) => {
if (!element) return;
const html = element.innerHTML; // store original HTML
element.querySelectorAll('.ignore').forEach((e) => e.remove()); // remove ignore elements
let start = 0, end = 0;
let sel, range, priorRange, text;
if (typeof window.getSelection != "undefined") {
sel = window.getSelection();
text = sel '';
if (window.getSelection().rangeCount <= 0) {
return;
}
range = window.getSelection().getRangeAt(0);
priorRange = range.cloneRange();
priorRange.selectNodeContents(element);
priorRange.setEnd(range.startContainer, range.startOffset);
start = priorRange.toString().length;
end = start (sel '').length;
} else if (typeof document.selection !== "undefined" &&
(sel = document.selection).type !== "Control") {
text = sel '';
range = sel.createRange();
priorRange = document.body.createTextRange();
priorRange.moveToElementText(element);
priorRange.setEndPoint("EndToStart", range);
start = priorRange.text.length;
end = start (sel '').length;
}
element.innerHTML = html; // restore HTML
console.log(start, end, text);
return { start, end, text };
}
document.querySelector('#P').addEventListener('click', function() {findTextRange(this)});
<span id="P">This is first text<span >Second</span> This is third text<span>