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

时间:2018-01-24 21:44:11

标签: javascript

我在这里使用代码: 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>

1 个答案:

答案 0 :(得分:1)

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

<强>段:

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

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

function dehighlight () {
  div.removeHighlight();
  console.log(div.html());
}
&#13;
<!----- 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>
&#13;
&#13;
&#13;

<强>更新

如前所述,highlightremoveHighlight都不是问题的原因,因为可以在上面的代码段中看到。问题还不在于您提供的(在$(document.ready)函数内)的附加代码。

相反,问题在于你已经将类highlightable赋予了两个元素(以下),其中前者是后者的父元素:< / p>

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

基于以上所述,在highlight上调用$(".highlightable")函数的含义是搜索短语是双重包装的。首先,它被第一个元素的后代包裹起来,然后再次被包裹,因为它也是第二个元素的后代。

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

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

Snippet (有缺陷)

&#13;
&#13;
/* ----- JavaScript ----- */
var highlightable = $(".highlightable");
highlightable.highlight("expected");
console.log(highlightable.last().html());
&#13;
<!----- 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>
&#13;
&#13;
&#13;

<强>解决方案:

要修复双重包装问题,您必须从上述元素之一中删除类highlightable。如果这不是一个选项,您可以随时使用jQuery对象中的第一个元素:

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