首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当文本由<mark>换行时,window.getSelection().getRange(0)不起作用

当文本由<mark>换行时,window.getSelection().getRange(0)不起作用
EN

Stack Overflow用户
提问于 2018-06-14 01:49:42
回答 1查看 1.6K关注 0票数 0

我正在尝试使用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的回答启发,以下方法将有效。虽然突出显示的文本不匹配,但无论如何我都不需要突出显示的文本

请随时添加有关该解决方案的评论。

正在运行的示例

代码语言:javascript
复制
$('#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)));
});
代码语言:javascript
复制
<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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-14 10:01:51

Quoting MDN

Range.startOffset只读属性

返回一个数字,表示范围在startContainer中的起始位置。

也是如此,它返回endContainer中的位置。

当您在页面中选择单词What时,startContainer是在</abbr>之后启动的TextNode。所以你得到的索引是相对于这个TextNode的。

如果您想要获取选定的文本,那么只需调用方法。

代码语言:javascript
复制
$('#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());
});
代码语言:javascript
复制
<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。

代码语言:javascript
复制
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;
}
代码语言:javascript
复制
<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>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50843340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档