静态 HTML 页面中的 JQuery 搜索,突出显示找到的单词

Posted

技术标签:

【中文标题】静态 HTML 页面中的 JQuery 搜索,突出显示找到的单词【英文标题】:JQuery search in static HTML page with highlighting of found word 【发布时间】: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() 【参考方案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 以将其放在单独的标记中。

【讨论】:

好的,我理解你的想法。我会尝试做类似的事情,我只是希望我不会弄乱代码。

以上是关于静态 HTML 页面中的 JQuery 搜索,突出显示找到的单词的主要内容,如果未能解决你的问题,请参考以下文章

在 jQuery 中搜索和突出显示

jQuery / JS - 在DIV中计算结果

创建一个 chrome 扩展,它将页面上突出显示的文本插入到 popup.html 中的文本区域中

正则表达式搜索 html 返回,但不是实际的 html jQuery

加载时 jQuery 突出显示导航项

如何在 jQuery 中突出显示日期?