提问人:nickf 提问时间:9/23/2008 最后编辑:arhaknickf 更新时间:7/29/2022 访问量:197136
使用 jQuery 突出显示单词
Highlight a word with jQuery
问:
我基本上需要突出显示文本块中的特定单词。例如,假设我想在这段文字中突出显示“dolor”这个词:
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</p>
<p>
Quisque bibendum sem ut lacus. Integer dolor ullamcorper libero.
Aliquam rhoncus eros at augue. Suspendisse vitae mauris.
</p>
如何将上述内容转换为如下所示:
<p>
Lorem ipsum <span class="myClass">dolor</span> sit amet, consectetuer adipiscing elit.
</p>
<p>
Quisque bibendum sem ut lacus. Integer <span class="myClass">dolor</span> ullamcorper
libero. Aliquam rhoncus eros at augue. Suspendisse vitae mauris.
</p>
jQuery可能吗?
编辑:正如Sebastian所指出的,如果没有jQuery,这是很有可能的 - 但我希望可能有一种特殊的jQuery方法,可以让你对文本本身进行选择器。我已经在这个网站上大量使用jQuery,所以把所有东西都包在jQuery中会让事情变得更整洁一些。
答:
您需要获取 p 标签的内容,并将其中的所有 dolors 替换为突出显示的版本。
你甚至不需要有jQuery。:-)
评论
尝试突出显示:JavaScript 文本突出显示 jQuery 插件。 警告:此页面上提供的源代码包含加密货币挖掘脚本,请使用下面的代码或从从网站下载的脚本中删除挖掘脚本。
/*
highlight v4
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:[email protected]>
*/
jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = 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();
};
还可以尝试原始脚本的“更新”版本。
/*
* jQuery Highlight plugin
*
* Based on highlight v3 by Johann Burkard
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
* Code a little bit refactored and cleaned (in my humble opinion).
* Most important changes:
* - has an option to highlight only entire words (wordsOnly - false by default),
* - has an option to be case sensitive (caseSensitive - false by default)
* - highlight element tag and class names can be specified in options
*
* Usage:
* // wrap every occurrance of text 'lorem' in content
* // with <span class='highlight'> (default options)
* $('#content').highlight('lorem');
*
* // search for and highlight more terms at once
* // so you can save some time on traversing DOM
* $('#content').highlight(['lorem', 'ipsum']);
* $('#content').highlight('lorem ipsum');
*
* // search only for entire word 'lorem'
* $('#content').highlight('lorem', { wordsOnly: true });
*
* // don't ignore case during search of term 'lorem'
* $('#content').highlight('lorem', { caseSensitive: true });
*
* // wrap every occurrance of term 'ipsum' in content
* // with <em class='important'>
* $('#content').highlight('ipsum', { element: 'em', className: 'important' });
*
* // remove default highlight
* $('#content').unhighlight();
*
* // remove custom highlight
* $('#content').unhighlight({ element: 'em', className: 'important' });
*
*
* Copyright (c) 2009 Bartek Szopka
*
* Licensed under MIT license.
*
*/
jQuery.extend({
highlight: function (node, re, nodeName, className) {
if (node.nodeType === 3) {
var match = node.data.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
}
}
return 0;
}
});
jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);
return this.find(settings.element + "." + settings.className).each(function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};
jQuery.fn.highlight = function (words, options) {
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
jQuery.extend(settings, options);
if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i){
return word != '';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
});
if (words.length == 0) { return this; };
var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}
var re = new RegExp(pattern, flag);
return this.each(function () {
jQuery.highlight(this, re, settings.element, settings.className);
});
};
评论
function hiliter(word, element) {
var rgxp = new RegExp(word, 'g');
var repl = '<span class="myClass">' + word + '</span>';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
}
hiliter('dolor');
评论
是否有可能得到上面的例子:
jQuery.fn.highlight = function (str, className)
{
var regex = new RegExp(str, "g");
return this.each(function ()
{
this.innerHTML = this.innerHTML.replace(
regex,
"<span class=\"" + className + "\">" + str + "</span>"
);
});
};
不要替换 html 标签中的文本,否则会破坏页面。
下面是一个忽略并保留大小写的变体:
jQuery.fn.highlight = function (str, className) {
var regex = new RegExp("\\b"+str+"\\b", "gi");
return this.each(function () {
this.innerHTML = this.innerHTML.replace(regex, function(matched) {return "<span class=\"" + className + "\">" + matched + "</span>";});
});
};
评论
innerHTML
是邪恶的,请看我的答案。此外,不适用于 unicode 字符。此外,此函数几乎会遗漏任何内容,例如在嵌套子项中搜索。\\b
我编写了一个非常简单的函数,它使用 jQuery 来迭代元素,并用 .highlight 类包装每个关键字。
function highlight_words(word, element) {
if(word) {
var textNodes;
word = word.replace(/\W/g, '');
var str = word.split(" ");
$(str).each(function() {
var term = this;
var textNodes = $(element).contents().filter(function() { return this.nodeType === 3 });
textNodes.each(function() {
var content = $(this).text();
var regex = new RegExp(term, "gi");
content = content.replace(regex, '<span class="highlight">' + term + '</span>');
$(this).replaceWith(content);
});
});
}
}
更多信息:
http://www.hawkee.com/snippet/9854/
评论
您可以使用我的高亮插件 jQuiteLight,它也可以使用正则表达式。
若要使用 npm 进行安装,请键入:
npm install jquitelight --save
要使用 bower 类型进行安装:
bower install jquitelight
用法:
// for strings
$(".element").mark("query here");
// for RegExp
$(".element").mark(new RegExp(/query h[a-z]+/));
更高级的用法在这里
评论
var oldMark = $.fn.mark.noConflict()
为什么使用自制的突出显示功能是个坏主意
从头开始构建自己的高亮功能可能是一个坏主意的原因是因为您肯定会遇到其他人已经解决的问题。挑战:
- 您需要删除带有 HTML 元素的文本节点以突出显示您的匹配项,而不会破坏 DOM 事件并一遍又一遍地触发 DOM 重新生成(例如,这种情况就是这种情况
innerHTML
) - 如果要删除突出显示的元素,则必须删除 HTML 元素及其内容,并且还必须组合拆分的文本节点以进行进一步搜索。这是必要的,因为每个荧光笔插件都会在文本节点内搜索匹配项,如果您的关键字将被拆分为多个文本节点,则不会找到它们。
- 您还需要构建测试以确保您的插件在您没有想到的情况下工作。我说的是跨浏览器测试!
听起来很复杂?如果您想要一些功能,例如忽略突出显示、变音符号映射、同义词映射、iframe 内部搜索、分隔单词搜索等元素,这将变得越来越复杂。
使用现有插件
当使用现有的、实施良好的插件时,您不必担心上面提到的问题。文章 Sitepoint 上的 10 个 jQuery 文本荧光笔插件比较了流行的荧光笔插件。这包括这个问题的答案插件。
看一看马克.js
mark.js就是这样一个用纯JavaScript编写的插件,但也可以作为jQuery插件使用。它的开发是为了提供比其他插件更多的机会,并提供以下选项:
- 单独搜索关键字,而不是搜索完整的术语
- 地图变音符号(例如,如果“justo”也应匹配“justò”)
- 忽略自定义元素中的匹配项
- 使用自定义突出显示元素
- 使用自定义突出显示类
- 映射自定义同义词
- 同时在 iframe 中搜索
- 接收未找到的字词
或者,您可以看到这把小提琴。
使用示例:
// Highlight "keyword" in the specified context
$(".context").mark("keyword");
// Highlight the custom regular expression in the specified context
$(".context").markRegExp(/Lorem/gmi);
它是免费的,在 GitHub 上开源开发(项目参考)。
评论
mark.js
$(function () {
$("#txtSearch").keyup(function (event) {
var txt = $("#txtSearch").val()
if (txt.length > 3) {
$("span.hilightable").each(function (i, v) {
v.innerHTML = v.innerText.replace(txt, "<hilight>" + txt + "</hilight>");
});
}
});
});
Jfiddle在这里
评论
hilight
没有有效的 HTML 元素
我创建了一个类似概念的存储库,该存储库更改了 html5 识别其颜色的文本的颜色(我们不必使用实际的 #rrggbb 值,并且可以仅使用名称作为 html5 标准化的大约 140 个)
$( document ).ready(function() {
function hiliter(word, element) {
var rgxp = new RegExp("\\b" + word + "\\b" , 'gi'); // g modifier for global and i for case insensitive
var repl = '<span class="myClass">' + word + '</span>';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
};
hiliter('dolor', document.getElementById('dolor'));
});
.myClass{
background-color:red;
}
<!DOCTYPE html>
<html>
<head>
<title>highlight</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link href="main.css" type="text/css" rel="stylesheet"/>
</head>
<body id='dolor'>
<p >
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</p>
<p>
Quisque bibendum sem ut lacus. Integer dolor ullamcorper libero.
Aliquam rhoncus eros at augue. Suspendisse vitae mauris.
</p>
<script type="text/javascript" src="main.js" charset="utf-8"></script>
</body>
</html>
使用。使用 jQuery 1.11 和 3.2 进行测试。.each()
.replace()
.html()
在上面的示例中,读取要突出显示的“关键字”,并在 span 标记中附加“highlight”类。文本“关键字”将突出显示为 ..each()
[HTML全
<body>
<label name="lblKeyword" id="lblKeyword" class="highlight">keyword</label>
<p class="filename">keyword</p>
<p class="content">keyword</p>
<p class="system"><i>keyword</i></p>
</body>
JS公司
$(document).ready(function() {
var keyWord = $("#lblKeyword").text();
var replaceD = "<span class='highlight'>" + keyWord + "</span>";
$(".system, .filename, .content").each(function() {
var text = $(this).text();
text = text.replace(keyWord, replaceD);
$(this).html(text);
});
});
CSS的
.highlight {
background-color: yellow;
}
您可以使用以下函数突出显示文本中的任何单词。
function color_word(text_id, word, color) {
words = $('#' + text_id).text().split(' ');
words = words.map(function(item) { return item == word ? "<span style='color: " + color + "'>" + word + '</span>' : item });
new_words = words.join(' ');
$('#' + text_id).html(new_words);
}
只需定位包含文本的元素,选择要着色的单词和选择的颜色即可。
下面是一个示例:
<div id='my_words'>
This is some text to show that it is possible to color a specific word inside a body of text. The idea is to convert the text into an array using the split function, then iterate over each word until the word of interest is identified. Once found, the word of interest can be colored by replacing that element with a span around the word. Finally, replacing the text with jQuery's html() function will produce the desired result.
</div>
用法,
color_word('my_words', 'possible', 'hotpink')
评论
这是@bjarlestam的修改版本。
这将仅搜索文本。
jQuery.fn.highlight = function(str) {
var regex = new RegExp(str, "gi");
return this.each(function() {
this.innerHTML = this.innerText.replace(regex, function(matched) {
return "<span class='mark'>" + matched + "</span>";
});
});
};
// Mark
jQuery('table tr td').highlight('desh')
.mark {
background: #fde293;
color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>HTML Table</h2>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Sodeshi</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>Bangladesh</td>
</tr>
</table>
用法:jQuery('.selector').highlight('sample text')
评论
<span>
<mark>