首页 > 解决方案 > 获取网页上用户选择的文本中包含的元素列表

问题描述

给定这样的页面:

 <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.”),我想返回“1”和“3”。

如果用户选择句子的一部分(从 span 1 中的“some”到 span 2 中的“the”),我想返回“1”和“2”。

这里最好的方法是什么?

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

例如:“这里有一些文本”和“用户可以选择”。- 在这种情况下,将返回 [[1,2],[2,3]]。

标签: javascriptcsstextselection

解决方案


编辑:我刚刚发现实际上有一个selection.containsNode方法,听起来它对你来说是完美的,但显然它仍然是一项实验性技术。

javascript 中没有广泛的高亮事件,因此解决方案不会简单明了,而且文本被拆分为多个元素的事实使其变得更加困难。您可以document.selection其用作此类似问题的最佳答案,但是您仍然需要根据span元素的 innerHTML 解析返回的文本,这看起来很繁琐。

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

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>


推荐阅读