首页 > 解决方案 > 如何跳过匹配 html 属性中的文本?

问题描述

我想从 html 中获取匹配字符串的索引以突出显示 html 中的特定匹配。问题是我在脚注链接中使用带有标题的工具提示(它有脚注文本)。所以..当我试图在脚注中突出显示某些内容时,它会在脚注引用的工具提示中突出显示。

有没有办法跳过html属性的匹配并跳转到下一个匹配?(因为我需要特定匹配的索引,所以我不能使用 `$(selector).text();

请帮助我 - 下面是我的代码示例:

var selectedContent = $(selector).html();

var regex = new RegExp('/The text from footnote/', 'gi');

var indices = [];

while(result = regex.exec(selectedContent))
{
    indices .push(result.index);
}

正则表达式匹配用作脚注参考的脚注工具提示中的文本。

我的代码示例在这里。请检查一下。

标签: javascripthtmljqueryregexstring-matching

解决方案


尝试这个:

var regex = new RegExp("(?!<[^>]+)" + textToHighlight + "(?![^<]+>)", 'gi');

var finalHtml = selectedContent.replace(regex, '<highlight class="highlight">'+textToHighlight+'</highlight>');

if(finalHtml)
    $('#lipsumContainer').html(finalHtml);

[编辑]

这是一个highlightText()直接在 textnodes 中搜索字符串的函数,这意味着它不会影响属性,但是如果它在不同元素之间拆分,它将不会找到文本。

在此示例中,它将突出显示选定的文本:

function highlightText(node, text) {
  if (!node)
    return;

  if (node.nodeType == 3) { //process textnode
    const index = node.data.indexOf(text);

    if (index == -1)
      return;

    const textNodeMark = node.splitText(index),
          textNodeAfter = textNodeMark.splitText(text.length),
          mark = document.createElement("mark");

    mark.appendChild(textNodeMark);
    node.parentNode.insertBefore(mark, textNodeAfter);

  } else {
    for (let n of node.childNodes) {
      if (n.tagName !== "MARK")
        highlightText(n, text);
    }
  }
}

/* demo highlight selected text */

const container = document.getElementById("lipsumContainer");

container.addEventListener("click", e => {
  const text = document.getSelection().toString().trim();

  if (text === "")
    return;


  for(let m of container.querySelectorAll("mark"))
    m.parentNode.replaceChild(m.firstChild, m); // remove previous marks;

  container.normalize(); // join any split textnodes 
  highlightText(container, text); // add new highlighting
}, true);

$('#lipsum').on('mouseenter', '#_contentFoot1', function(){
    var tooltipPosition = $(this).position(); 
  var title = $(this).data('title');
    var tooltipHtml = '<div class="tooltip">'+
  '<span class="tooltiptext">'+title+'</span>'+'</div>'; 
    $('body').append(tooltipHtml);
    $('.tooltip').attr("style", "top: "+tooltipPosition.top+"px;left: "+tooltipPosition.left+"px;");  
})

$('#lipsum').on('mouseleave', '#_contentFoot1', function(){
    $('.tooltip').remove();
})
.tooltip .tooltiptext::after {
  content: " ";
  position: absolute;
  top: 100%;
  /* At the bottom of the tooltip */
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: black transparent transparent transparent;
}

.tooltip {
  position: absolute;
  display: inline-block;
  border-bottom: 1px dotted black;
}

.tooltip .tooltiptext {
  visibility: visible;
  width: 120px;
  background-color: black;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px 0;
  position: absolute;
  z-index: 1;
  bottom: 150%;
  left: 50%;
  margin-left: -60px;
}

mark {
  background-color: lightgreen;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="lipsumContainer">
  <div id="lipsum">
<p><b>bold</b> <i>italic</i></p>
<p><b>bold</b> <i>italic</i></p>
    <p>
      Vivamus vel commodo nisl, sed maximus lectus. Donec semper suscipit porta. Ut facilisis turpis pellentesque purus laoreet sagittis. Donec at scelerisque dui. Nullam hendrerit eros et lacinia venenatis. Nullam sodales nulla sit amet est ultrices,
      sit amet tempus risus consequat.<a id="_contentFoot1" href="#_foot1" data-toglggle="tooltip" data-title="The 1st footnote text"><sup>[1]</sup></a> Fusce suscipit ipsum vel dapibus sagittis. Nullam tellus nisl, egestas ut feugiat non, porttitor
      eget erat. Suspendisse placerat dictum nulla non sollicitudin. Maecenas nec tortor felis. Donec id cursus ligula, a volutpat sapien.
    </p>
  </div>

  <div class="footnotes">
    <p id="_foot1">
      <a href="#_contentFoot1">[1]</a> <span>The 1st footnote text</span>
    </p>
  </div>

</div>


推荐阅读