静态 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());
现在使用正则表达式并用<span style="text-decoration:underline"></span>
替换(换行)这些单词,并将它们设置为段落的.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 搜索,突出显示找到的单词的主要内容,如果未能解决你的问题,请参考以下文章
创建一个 chrome 扩展,它将页面上突出显示的文本插入到 popup.html 中的文本区域中