I have a html tag which is
JavaScript
x
2
1
<span>This is first text<span class="ignore">Second</span> This is third text<span>
2
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
JavaScript
1
29
29
1
export const findTextRange = (element) => {
2
if (!element) return;
3
let start = 0, end = 0;
4
let sel, range, priorRange, text;
5
if (typeof window.getSelection != "undefined") {
6
sel = window.getSelection();
7
text = sel + '';
8
if (window.getSelection().rangeCount <= 0) {
9
return;
10
}
11
range = window.getSelection().getRangeAt(0);
12
priorRange = range.cloneRange();
13
priorRange.selectNodeContents(element);
14
priorRange.setEnd(range.startContainer, range.startOffset);
15
start = priorRange.toString().length;
16
end = start + (sel + '').length;
17
} else if (typeof document.selection !== "undefined" &&
18
(sel = document.selection).type !== "Control") {
19
text = sel + '';
20
range = sel.createRange();
21
priorRange = document.body.createTextRange();
22
priorRange.moveToElementText(element);
23
priorRange.setEndPoint("EndToStart", range);
24
start = priorRange.text.length;
25
end = start + (sel + '').length;
26
}
27
return { start, end, text };
28
}
29
Is there any way where I can ignore the span
element with ignore
class.
Advertisement
Answer
Store the initial HTML, then remove all elements having the .ignore
class:
JavaScript
1
3
1
const html = element.innerHTML;
2
element.querySelectorAll('.ignore').forEach((e) => e.remove());
3
After getting the range, restore the original HTML:
JavaScript
1
2
1
element.innerHTML = html;
2
Snippet
JavaScript
1
35
35
1
const findTextRange = (element) => {
2
if (!element) return;
3
const html = element.innerHTML; // store original HTML
4
element.querySelectorAll('.ignore').forEach((e) => e.remove()); // remove ignore elements
5
6
let start = 0, end = 0;
7
let sel, range, priorRange, text;
8
if (typeof window.getSelection != "undefined") {
9
sel = window.getSelection();
10
text = sel + '';
11
if (window.getSelection().rangeCount <= 0) {
12
return;
13
}
14
range = window.getSelection().getRangeAt(0);
15
priorRange = range.cloneRange();
16
priorRange.selectNodeContents(element);
17
priorRange.setEnd(range.startContainer, range.startOffset);
18
start = priorRange.toString().length;
19
end = start + (sel + '').length;
20
} else if (typeof document.selection !== "undefined" &&
21
(sel = document.selection).type !== "Control") {
22
text = sel + '';
23
range = sel.createRange();
24
priorRange = document.body.createTextRange();
25
priorRange.moveToElementText(element);
26
priorRange.setEndPoint("EndToStart", range);
27
start = priorRange.text.length;
28
end = start + (sel + '').length;
29
}
30
element.innerHTML = html; // restore HTML
31
console.log(start, end, text);
32
return { start, end, text };
33
}
34
35
document.querySelector('#P').addEventListener('click', function() {findTextRange(this)});
JavaScript
1
1
1
<span id="P">This is first text<span class="ignore">Second</span> This is third text<span>