获取网页上用户选择的文本中包含的元素列表

Getting a list of elements contained in user-selected text on a webpage

给定这样一个页面:

 <p>
 <span class="1">Here's some text</span>
 <span class="2">that the user</span>
 <span class="3">could select.</span>
 </p>

如果用户选择了整个句子(从"Here's"到"select."),我想return“1”和“3”。

如果用户选择了句子的一部分(从跨度 1 中的 "some" 到跨度 2 中的 "the"),我想 return“1”和“2”。

最好的方法是什么?

*Edit - 我正在寻找一种允许同时突出显示多段(非重叠)文本的解决方案。

例如: "Here's some text that" 和 "user could select." - 在这种情况下,[[1,2],[2,3]] 将被 returned.

编辑:我刚刚发现实际上有一个 selection.containsNode 方法,听起来很适合您,但显然它仍然是一项实验性技术。

javascript 中没有广泛的突出显示事件,因此解决方案不会简单明了,而且文本被拆分成多个元素这一事实使解决方案变得更加困难。您 可以 document.selection 用作 the top answer to this similar question suggests,但是您仍然需要根据 span 元素的 innerHTML 解析返回的文本,这看起来像会很麻烦。

我认为在这种情况下,您最好的选择是基本上使用现有的 JS 事件重新创建突出显示功能。这是一个天真的实现,缺少一些功能,如双击 select 和键盘 selection,但你明白了。

const hLights = Array.from(document.querySelectorAll('.hlight'));
let active = false;
let hoveredEls = [];

window.addEventListener('mousedown', function() {
  active = true;
});

window.addEventListener('mouseup', function() {
  active = false;
  console.log(hoveredEls);
  hoveredEls = [];
});

hLights.forEach(el => {
  el.addEventListener('mousemove', function() {
    if (active && !hoveredEls.includes(el.id)) hoveredEls.push(el.id);
  });
  el.addEventListener('mouseenter', function() {
    if (active) {
      if(hoveredEls.includes(el.id)) {
        const idx = hoveredEls.findIndex(el => el === el.id);
        hoveredEls.splice(idx, 1);
      } else {
        hoveredEls.push(el.id);
      }
    }
  });
});
<p>
 <span id="1" class="hlight">Here's some text</span>
 <span id="2" class="hlight">that the user</span>
 <span id="3" class="hlight">could select.</span>
</p>

so here is the html

    <span class="class-1" 
    onmousedown="getElementBegin('1')" onmouseup="getElementEnd('1')" >
        algum texto 1
    </span> <br>
    <span class="class-2" 
    onmousedown="getElementBegin('2')" onmouseup="getElementEnd('2')">
        algum texto 2
    </span> <br>
    <span class="class-3" 
    onmousedown="getElementBegin('3')" onmouseup="getElementEnd('3')">
        algum texto 3
    </span> <br>

    <p id="selected"> nada!</p>

And here is the js:

let begin
let end
let selection

document.onmouseup = function () {
selection = window.getSelection().toString()
console.log(selection);

selected = document.getElementById('selected')
selected.innerHTML = `selection goes to: ${begin} until ${end} <br> selection: ${selection}`
}

function getElementBegin(beginElement) {
begin = beginElement
console.log(begin)
}

function getElementEnd(endElement) {
end = endElement
console.log(end)
}