【问题标题】:JQuery search in static HTML page with highlighting of found word静态 HTML 页面中的 JQuery 搜索,突出显示找到的单词
【发布时间】:2012-04-18 04:14:31
【问题描述】:

我一直在尝试使用 JQuery 在静态 HTML 页面中进行简单搜索。不得不提的是,这只是我第一次使用 JQuery。

我正在尝试更改页面中找到的单词的背景,这是我迄今为止尝试过的:

myJavascript.js:

$(document).ready(function(){

     $('#searchfor').keyup(function(){
         page = $('#all_text').text();
         searchedText = $('#searchfor').val();
         $("p:contains('"+searchedText+"')").css("color", "white");
    });
});

这也是 HTML 代码:

page.html:

<html>
<head>
    <title>Test page</title>
</head>
<body bgcolor="#55c066">
<input type="text" id="searchfor"></input>
    <p id="all_text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euism modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.
    <font color="red">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tinci futurum.</font>
    </p>
</body>
    <script src="jquery-1.7.2.min.js"></script>
    <script src="myJavascript.js"></script>
</html>

使用 Firebug 检查页面后,我可以看到 JQuery 中的变量确实从输入字段中获取了值,但我想我搞砸了突出显示部分。

提前感谢您的帮助!

【问题讨论】:

  • 您需要下划线还是整个段落(p)?
  • 只有单词,我把标题改成了我真正想要的,突出显示找到的单词。
  • 如果您只想在搜索到的单词下划线,您需要将单词包裹在一个html标签中,例如span(将span的样式设置为下划线)并替换内容p 元素的
  • 抱歉后面的编辑,我想突出显示找到的单词。这就是我的代码正在尝试做的事情。下划线是我尝试的第一件事,然后我改变主意并尝试突出显示该单词但忘记更改标题。
  • 一个想法:获取段落的文本($("p:contains('"+searchedText+"')").html()); 现在使用正则表达式并用&lt;span style="text-decoration:underline"&gt;&lt;/span&gt; 替换(换行)这些单词,并将它们设置为段落的.html()

标签: jquery html css search highlight


【解决方案1】:

纯 JS,因为它也可以帮助其他搜索者。
使用与 input 文本匹配的 regex(不区分大小写 - i ,所有出现次数 - g

var searchQuery = document.querySelector("#inputSearch");
var context = document.querySelector("#context");

searchQuery.addEventListener('input', searchQueryResults)

function searchQueryResults() {
  context.innerHTML = context.textContent.replace(new RegExp(searchQuery.value, "gi"), (match) => `<u>${match}</u>`);
}
<input type="text" value="" id="inputSearch">
<div id="context">
  Lorem ipsum dolor test sit amet
</div>

【讨论】:

    【解决方案2】:

    $(function() {
      $("input").on("input.highlight", function() {
        // Determine specified search term
        var searchTerm = $(this).val();
        // Highlight search term inside a specific context
        $("#context").unmark().mark(searchTerm);
      }).trigger("input.highlight").focus();
    });
    mark {
      background: orange;
      color: black;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/mark.js/7.0.0/jquery.mark.min.js"></script>
    <input type="text" value="test">
    <div id="context">
      Lorem ipsum dolor test sit amet
    </div>

    【讨论】:

      【解决方案3】:

      为什么使用自制的高亮功能是个坏主意

      从头开始构建自己的突出显示功能可能不是一个好主意,因为您肯定会遇到其他人已经解决的问题。挑战:

      • 您需要删除带有 HTML 元素的文本节点以突出显示您的匹配项,而不会破坏 DOM 事件并一遍又一遍地触发 DOM 重新生成(例如 innerHTML 就是这种情况)
      • 如果要删除突出显示的元素,则必须删除 HTML 元素及其内容,还必须合并拆分的文本节点以进行进一步搜索。这是必要的,因为每个荧光笔插件都会在文本节点内搜索匹配项,如果您的关键字将被拆分为多个文本节点,它们将不会被找到。
      • 您还需要构建测试以确保您的插件在您没有考虑过的情况下工作。我说的是跨浏览器测试!

      听起来很复杂?如果您想要一些功能,例如忽略突出显示中的某些元素、变音符号映射、同义词映射、iframe 内搜索、分词搜索等,这将变得越来越复杂。

      使用现有插件

      当使用现有的、实施良好的插件时,您不必担心上面提到的事情。 Sitepoint 上的文章 10 jQuery text highlighter plugins 比较了流行的荧光笔插件。这包括这个问题的答案插件。

      看看mark.js

      mark.js 就是这样一个用纯 JavaScript 编写的插件,但也可以作为 jQuery 插件使用。它的开发目的是提供比其他插件更多的机会,并提供以下选项:

      • 单独搜索关键字而不是完整的字词
      • 地图变音符号(例如,如果“justo”也应该匹配“justò”)
      • 忽略自定义元素内的匹配项
      • 使用自定义突出显示元素
      • 使用自定义高亮类
      • 映射自定义同义词
      • 也在 iframe 内搜索
      • 收到未找到的条款

      DEMO

      您也可以看到this fiddle

      使用示例

      // Highlight "keyword" in the specified context
      $(".context").mark("keyword");
      
      // Highlight the custom regular expression in the specified context
      $(".context").markRegExp(/Lorem/gmi);
      

      它是在 GitHub (project reference) 上免费开发的开源软件。

      使用您的代码突出显示 mark.js 关键字的示例

      $(function() {
        $("input").on("input.highlight", function() {
          // Determine specified search term
          var searchTerm = $(this).val();
          // Highlight search term inside a specific context
          $("#context").unmark().mark(searchTerm);
        }).trigger("input.highlight").focus();
      });
      mark {
        background: orange;
        color: black;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <script src="https://cdn.jsdelivr.net/mark.js/7.0.0/jquery.mark.min.js"></script>
      <input type="text" value="test">
      <div id="context">
        Lorem ipsum dolor test sit amet
      </div>

      【讨论】:

      • 我同意你所说的,但是由于这个问题可以追溯到 2012 年,当时没有多少 JS 库可用,这是我完成工作的唯一方法。因此,继续前进,您绝对应该寻找现有的插件。否则,开始自己制作并分享吧!
      【解决方案4】:

      这是我的:http://jsfiddle.net/x8rpY/1/

      JS:

      $('#searchfor').keyup(function(){
               var page = $('#all_text');
               var pageText = page.text().replace("<span>","").replace("</span>");
               var searchedText = $('#searchfor').val();
               var theRegEx = new RegExp("("+searchedText+")", "igm");    
               var newHtml = pageText.replace(theRegEx ,"<span>$1</span>");
               page.html(newHtml);
          });
      

      CSS:

      #all_text span
      {
          text-decoration:underline;
          background-color:yellow;    
      }
      

      也适用于重复搜索。

      【讨论】:

      • 谢谢,但是如果我搜索大写字母并找到与小写完全相同的字母,那么它将小写字母转换为大写字母。
      • @mshsayem 很棒的代码,谢谢。是否可以将文档移动到 Jquery 中出现单词的位置?因为我的网页很大,所以我需要将指针移动到实际单词所在的位置,例如 Google chrome (ctrl+f5) 功能。
      • 有可能;只需获取span 元素并调用.scrollIntoView()
      • 使用innerHTML (VanillaJS) 或.html (jQuery) 是邪恶的!!!它会破坏元素内的所有事件并一次又一次地触发 DOM 的生成。看看我的回答!
      【解决方案5】:

      做这样的事情

       $("p:contains('"+searchedText+"')").each( function( i, element ) {
            var content = $(element).text();
            content = content.replace( searchedText, '<span class="search-found">' + searchedText + '</span>' );
            element.html( content );
       });
      
       .search-found {
           text-decoration: underline;
       }
      

      附言这只有在每个“元素”都只有纯文本内容时才有效,否则它将删除子节点

      编辑:删除了 each 回调中多余的 ')'

      【讨论】:

      • 我已经尝试过您的代码,但 Firebug 给了我一个错误:在第 6 行第 66 列,但那里什么都没有。我看到each()函数中应该有另一个参数,但我似乎无法理解它是什么。
      • element 删除其中一个之后还有一个额外的),即.function( i, element ){,但老实说,您应该能够自己进行这种小规模调试——我已经更新了上面的代码
      • 嗯,element.text() 不是函数。我可以看到该元素是 [object HTMLParagraphElement]
      • do $(element).text(),拜托,这是基础
      • 使用innerHTML (VanillaJS) 或.html (jQuery) 是邪恶的!!!它会破坏元素内的所有事件并一次又一次地触发 DOM 的生成。看看我的回答!
      【解决方案6】:

      这是我快速破解的另一个示例:http://jsfiddle.net/VCJUX/

      【讨论】:

      • 这其实很酷,问题是;如果您正在搜索具有任何样式的页面,它会通过删除所有 p 标记、跨度、链接等来破坏整个页面...
      【解决方案7】:

      (对于你想要使用背景颜色而不是颜色作为背景的一件事)

      我将为普通创建一个 css 类,为突出显示的文本创建一个单独的(继承的)css 类,然后在您找到所需内容时使用 JQuery 更改 css 类。

      只是我最初的想法,不确定是否有更好的方法。

      编辑:如果您只想更改特定的单词,则必须修改 innerHTML 以将其放在单独的标记中。

      【讨论】:

      • 好的,我理解你的想法。我会尝试做类似的事情,我只是希望我不会弄乱代码。
      猜你喜欢
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 2019-10-26
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      相关资源
      最近更新 更多