【问题标题】:Getting a list of elements contained in user-selected text on a webpage获取网页上用户选择的文本中包含的元素列表
【发布时间】:2020-10-05 11:22:52
【问题描述】:

给定这样的页面:

 <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”。

这里最好的方法是什么?

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

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

【问题讨论】:

    标签: javascript css textselection


    【解决方案1】:

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

    在 javascript 中没有广泛的高亮事件,因此解决方案不会很简单,而且文本被拆分为多个元素的事实使其更加困难。您可以document.selection 用作the top answer to this similar question suggests,但是您仍然需要根据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>

    【讨论】:

    • 这是一个很棒的实现。问题虽然;我打算以某种方式实现此功能,即某人可以在一页文本中同时进行多个高亮显示。这个想法是不是简单地增加并为每个新选择添加一个新的“活动”变量来存储额外的亮点?
    • 您不应该需要多个活动变量,因为这意味着用户按住鼠标(即拖动)。您可能想要做的是创建一个新的高亮对象——比如{id: 1, highlightedEls: [1, 2]}——每次用户拖动它们并将它们存储在一个数组中。我建议您查看新的Selection API,当我发布我的答案时我并不知道,因为如果您正在开发的浏览器支持它,它可能会更可靠。
    【解决方案2】:

    这里是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>
    

    这里是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)
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-21
      • 2021-11-17
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 2023-03-18
      • 2017-09-20
      相关资源
      最近更新 更多