【问题标题】:Highlight search string using jQuery使用 jQuery 突出显示搜索字符串
【发布时间】:2018-01-24 21:44:10
【问题描述】:

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

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

    片段:

    /* ----- 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>

    更新:

    如前所述,highlightremoveHighlight 都不是问题的原因,从上面的 sn-p 中可以看出。问题也不在于您提供的附加代码(在$(document.ready) 函数内)

    相反,问题在于您将类highlightable 赋予了两个元素(以下),其中前者是后者的父元素:

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

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

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

    另外,请查看以下 sn-p。它使用 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>

    解决方案:

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

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

    【讨论】:

    • doh,谢谢,那我该如何找出是什么原因造成的呢?谢谢
    • 编辑您的问题并添加调用highlight 函数的脚本。问题可能出在某个地方。
    • 这有帮助吗?谢谢
    • 查看我的更新@Ben。您面临的问题不是源自您的JavaScript 代码,而是源自您的HTML
    • 非常感谢@Angel,菜鸟的错误!
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 2011-02-02
    • 2015-05-04
    • 2018-06-24
    相关资源
    最近更新 更多