使用 jQuery 突出显示搜索字符串

Highlight search string using jQuery

提问人:Ben 提问时间:1/25/2018 最后编辑:Ben 更新时间:1/26/2018 访问量:1230

问:

我在这里使用代码:http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html

但是,为了创建突出显示搜索功能,代码似乎对短语进行了双重包装,如下所示:

<span class="highlight" tabindex="0"><span class="highlight" tabindex="0">Test</span></span>

谁能看到我错过了什么,我一整天都在做这件事,我想我快疯了。提前致谢:)

调用 hightlight 函数的代码为:

<script>
    $( document ).ready(function() {
      $('.highlightable').removeHighlight().highlight('<?php echo $search['query'] ?>');
      <?php if ($search['query']) { ?>
      var n = $(".highlightable").find("span.highlight").length;
      if (n == 0) {
        alert('There are no search results for <?php echo $search['query'] ?>. Please try again.');
      } else {
        alert('There are ' + n + ' search results for <?php echo $search['query'] ?>. Use TAB key to move between results.');
      }
      <?php } ?>
    });
</script>

然后是函数本身:

jQuery.fn.highlight = function(pat) {
 function innerHighlight(node, pat) {
  var skip = 0;
  if (node.nodeType == 3) {
   var pos = node.data.toUpperCase().indexOf(pat);
   pos -= (node.data.substr(0, pos).toUpperCase().length - node.data.substr(0, pos).length);
   if (pos >= 0) {
    var spannode = document.createElement('span');
    spannode.className = 'highlight';
    spannode.tabIndex = '0';
    var middlebit = node.splitText(pos);
    middlebit.splitText(pat.length);
    var middleclone = middlebit.cloneNode(true);
    spannode.appendChild(middleclone);
    middlebit.parentNode.replaceChild(spannode, middlebit);
    skip = 1;
   }
  }
  else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
   for (var i = 0; i < node.childNodes.length; ++i) {
    i += innerHighlight(node.childNodes[i], pat);
   }
  }
  return skip;
 }
 return this.length && pat && pat.length ? this.each(function() {
  innerHighlight(this, pat.toUpperCase());
 }) : this;
};

jQuery.fn.removeHighlight = function() {
 return this.find("span.highlight").each(function() {
  this.parentNode.firstChild.nodeName;
  with (this.parentNode) {
   replaceChild(this.firstChild, this);
   normalize();
  }
 }).end();
};

完成于:

<script>
    $( window ).on( "load", function() {
      $('.highlight').first().focus();
    });
</script>
JavaScript的

评论


答:

1赞 Angel Politis 1/25/2018 #1

你遇到的问题一定与你使用代码的环境有关,而不是代码本身。正如您在下面的代码片段中看到的,该函数按预期工作,将匹配的单词换行一次。

片段:

/* ----- JavaScript ----- */
var div = $("div");

function highlight () {
  div.highlight("expected");
  console.log(div.html());
}

function dehighlight () {
  div.removeHighlight();
  console.log(div.html());
}
<!----- HTML ----->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//pastebin.com/raw/6zePUJr1"></script>
<style>span.highlight {background-color: #FFFF77}</style>

<button onclick="highlight()">Highlight</button>
<button onclick="dehighlight()">Dehighlight</button>
<div>The code works as expected.</div>


更新:

如前所述,和都不是问题的原因,如上面的代码片段所示。问题也不在于您提供的附加代码($(document.ready) 函数中)。highlightremoveHighlight

相反,问题在于你把类给了两个元素(以下),其中前者是后者的父元素:highlightable

  • 第一个是main.small-12.medium-8.columns.highlightable
  • 第二个是div.sections.highlightable

基于上述情况,调用函数 on 的含义是搜索短语是双换行的。首先,它通过成为第一个元素的后代进行包装,然后再次包装,因为它也是第二个元素的后代。highlight$(".highlightable")

您可以通过在控制台中键入内容轻松识别自己。您会注意到,不仅删除了突出显示,还删除了整个短语。$(".highlightable").removeHighlight()

另外,请查看以下代码片段。它使用类的方式与您在代码中使用它的方式相同,这会导致搜索短语的双重包装,就像它发生在您身上一样。highlightable

片段(错误)

/* ----- JavaScript ----- */
var highlightable = $(".highlightable");
highlightable.highlight("expected");
console.log(highlightable.last().html());
<!----- HTML ----->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//pastebin.com/raw/6zePUJr1"></script>
<style>span.highlight {background-color: #FFFF77}</style>

<div class = "highlightable">
  <p class = "highlightable">
    The code doesn't work as expected.
  </p>
</div>

溶液:

若要解决双重包装问题,必须从上述元素之一中删除该类。如果这不是一个选项,你总是可以只使用对象中的第一个元素:highlightablejQuery

$('.highlightable').first().removeHighlight().highlight('<?= $search['query'] ?>');

评论

0赞 Ben 1/25/2018
哎呀,谢谢,那我怎么弄清楚是什么原因造成的呢?谢谢
1赞 Angel Politis 1/25/2018
编辑您的问题并添加调用该函数的脚本。问题可能出在某个地方。highlight
0赞 Ben 1/25/2018
这有帮助吗?谢谢
1赞 Angel Politis 1/26/2018
查看我的更新@Ben。你面临的问题不是源自你的代码,而是源自你的 .JavaScriptHTML
1赞 Ben 1/26/2018
非常感谢你@Angel,菜鸟错误!