我正在尝试使用window.getSelection().getRangeAt(0)
来获取句子中所选单词的索引。它在没有任何<mark>
和<abbr>
的文本中工作得很好。但是当一个句子中有这样的标签时,这个函数似乎会把句子分成几个部分。
例如,超文本标记语言中的一句话看起来像My car <abbr title="car_state"><mark>broke down</mark></abbr>. What do I do?
当我选择broke down
之前的文本时,它工作得很好。但是,当我选择e What
之后的文本时,它会给出2
处的startOffset
,而不是22
。
有可能获得整个句子的索引吗?
受Kaiido的回答启发,以下方法将有效。虽然突出显示的文本不匹配,但无论如何我都不需要突出显示的文本
请随时添加有关该解决方案的评论。
正在运行的示例
$('#selected_text').click(function(){
var text = "My car is broke down. What do I do?";
var range = window.getSelection().getRangeAt(0);
var start = range.startOffset;
var end = range.endOffset;
var extra = 0;
var selected_string = range.toString();
var t = $('span').contents();
for(var i = 0; i < t.length; i++){
console.log(extra);
if(t[i].wholeText === undefined){
extra += t[i].textContent.length;
}else if(t[i].wholeText.includes(selected_string)){
break;
}else{
extra += t[i].length;
}
}
start += extra;
end += extra;
console.log("start index: " + start);
console.log("end index: " + end);
console.log(text.slice(start, end));
console.log(selected_string);
console.log("match: ", (selected_string === text.slice(start, end)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<span>My car is <abbr title="car_state"><mark>broke down</mark></abbr>. What do <mark>I</mark> d<mark>o</mark>?</span>
<button id='selected_text'>show selected text</button>
</body>
</html>
发布于 2018-06-14 10:01:51
Range.startOffset只读属性
返回一个数字,表示范围在startContainer中的起始位置。
也是如此,它返回endContainer中的位置。
当您在页面中选择单词What时,startContainer
是在</abbr>
之后启动的TextNode。所以你得到的索引是相对于这个TextNode的。
如果您想要获取选定的文本,那么只需调用方法。
$('#selected_text').click(function() {
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var start = range.startOffset;
var end = range.endOffset;
console.log("start index: " + start);
console.log("end index: " + end);
console.log('startContainer', range.startContainer.nodeName, range.startContainer.textContent);
console.log('endContainer', range.endContainer.nodeName, range.endContainer.textContent);
console.log('toString:', sel.toString());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>My car is <abbr title="car_state"><mark>broke down</mark></abbr>. What do I do?</span>
<button id='selected_text'>show selected text</button>
如果您知道公共容器并想知道相对于这个祖先的文本内容所处的位置,那么您必须遍历它的childNodes,直到找到startContainer和endContainer。
var container = $('#container')[0];
$('#selected_text').click(function() {
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var sel_start = range.startOffset;
var sel_end = range.endOffset;
var charsBeforeStart = getCharactersCountUntilNode(range.startContainer, container);
var charsBeforeEnd = getCharactersCountUntilNode(range.endContainer, container);
if(charsBeforeStart < 0 || charsBeforeEnd < 0) {
console.warn('out of range');
return;
}
var start_index = charsBeforeStart + sel_start;
var end_index = charsBeforeEnd + sel_end;
console.log('start index', start_index);
console.log('end index', end_index);
console.log(container.textContent.slice(start_index, end_index));
});
function getCharactersCountUntilNode(node, parent) {
var walker = document.createTreeWalker(
parent || document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
var found = false;
var chars = 0;
while (walker.nextNode()) {
if(walker.currentNode === node) {
found = true;
break;
}
chars += walker.currentNode.textContent.length;
}
if(found) {
return chars;
}
else return -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="container">My car is <abbr title="car_state"><mark>broke down</mark></abbr>. What do I do?</span>
<button id='selected_text'>show selected text</button>
https://stackoverflow.com/questions/50843340
复制相似问题