JavaScript / jQuery getSelection高亮合并span HTML元素

3

function highlight_text(sel) {
  span = htmlSpanHlt();
  if (sel.getRangeAt) {
    range = sel.getRangeAt(0);
  }
  span.appendChild(range.extractContents());
  range.insertNode(span);
}

function htmlSpanHlt() {
  element = document.createElement("span");
  element.setAttribute('class', 'hlt');
  return element;
}
.hlt {
 background: yellow; 
}
<div class="highlight">
  <p>
    <span class="hlt">Lorem</span> ipsum dolor sit amet, zril accusata postulant at ius. Dicat etiam luptatum ea pri. Duo docendi vulputate dissentiet ut, tollit bonorum duo eu. Maiorum adolescens scriptorem usu eu, sit idque facer causae ei. Choro nostrum at pro, sumo essent suscipiantur pri ex. Quo case veritus definiebas eu, sit postulant dissentias ei.<br>
    <br>
    Mel cu porro decore, cum et simul recteque inciderint. His ne omnes sententiae, ut omittantur dissentiet accommodare sed. Pro minim necessitatibus ne, no malis integre quo. Sed utroque molestiae interpretaris ne. Oportere indoctum at has, te sale semper eum, ea nam vitae dissentiet.
  </p>
</div>

单词“Lorem”具有一个名为“hlt”的类名,已经被突出显示。我的要求是:如果我想突出显示另一个包含已经突出显示的单词“Lorem”的文本。我希望合并它们的span html元素。例如:如果我在单词“Lorem”旁边突出显示“ipsum”,并且我还包括“Lorem”,结果将是Lorem Ipsum。有人可以帮我吗?谢谢。

1个回答

1
这个怎么样?

function highlight_text(sel) {
   var hlt_element = document.getElementsByClassName('hlt')[0];
   if (!hlt_element || sel.containsNode(hlt_element,true)) {
      add_hlt_element(sel);
   }
}

function add_hlt_element(sel) {
   var element = document.createElement("span");
   var range = sel.getRangeAt(0);
   element.setAttribute('class', 'hlt');
   element.innerHTML = sel.toString().replace(/(?:\r\n|\r|\n)/g, '<br />\n');
   range.deleteContents();
   range.insertNode(element); 
   var highlight_div = document.getElementsByClassName("highlight")[0];
   highlight_div.innerHTML = highlight_div.innerHTML.replace('</span><span class="hlt">','');
}

window.onmouseup = function() {
   var sel = window.getSelection();
   highlight_text(sel);
}
.hlt {
    background: yellow; 
}
<div class="highlight">
  <p>
    Lorem ipsum dolor sit amet, zril accusata postulant at ius. Dicat etiam luptatum ea pri. Duo docendi vulputate dissentiet ut, tollit bonorum duo eu. Maiorum adolescens scriptorem usu eu, sit idque facer causae ei. Choro nostrum at pro, sumo essent suscipiantur pri ex. Quo case veritus definiebas eu, sit postulant dissentias ei.<br>
    <br>
    Mel cu porro decore, cum et simul recteque inciderint. His ne omnes sententiae, ut omittantur dissentiet accommodare sed. Pro minim necessitatibus ne, no malis integre quo. Sed utroque molestiae interpretaris ne. Oportere indoctum at has, te sale semper eum, ea nam vitae dissentiet.
  </p>
</div>


谢谢。但是什么也不会发生。我无法突出显示任何文本。而且用户可以继续突出显示并覆盖突出显示,他们的跨度将被合并。 - Roque Mejos
啊哈,它实际上起作用了。但那只是一个例子,在页面开头不应该有任何高亮显示,Lorem只是一个示例,用户突出显示文本后才会出现高亮。如果我突出显示Lorem或任何文本,那么它将被突出显示。如果我覆盖并扩展我的突出显示,那么该跨度将合并。您的第一个答案是正确的,但它只能突出显示一个单词。 - Roque Mejos
而且如果我从第二个字母开始突出显示,它也不起作用。 - Roque Mejos
你的代码很棒。只有两个小问题需要解决。首先,用户可以开始覆盖第二个或第三个字母等等。其次,用户可以突出显示未突出显示的文本,并创建一个新的span。 - Roque Mejos
太好了。但是HTML结构有些问题。首先,它不会合并span。例如,我首先突出显示了“Lorem ipsum”,结果应该是<span class="hlt">Lorem ipsum</span>,这是正确的。然后,如果我再次突出显示并覆盖到单词“dolor sit”,结果应该是<span class="hlt">Lorem ipsum dolor sit</span>。它不应该是span.hlt在span.hlt内部。你的逻辑真的很棒。 - Roque Mejos
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接