用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?
编辑 :正如塞巴斯蒂安 指出 ,这是很有可能没有jQuery – 但我希望可能有一个特殊的jQuery方法,它会让你做文本本身的select器。 我已经在这个网站上大量使用了jQuery,所以把所有东西封装在jQuery中会让事情变得更加整洁。
尝试突出显示:JavaScript文本higlighting 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:jb@eaio.com> */ 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');
为什么使用自制的突出显示function是一个坏主意
从零开始构build自己的突出显示function可能是一个糟糕的主意,因为您肯定会遇到其他人已经解决的问题。 挑战:
- 您将需要使用HTML元素删除文本节点,以突出显示您的匹配,而不会破坏DOM事件并一次又一次地触发DOM重新生成(例如,对于如
innerHTML
) - 如果你想删除突出显示的元素,你将不得不删除HTML元素与他们的内容,也必须结合拆分文本节点进一步search。 这是必要的,因为每个荧光笔插件search文本节点内匹配,如果您的关键字将被拆分成几个文本节点,他们将不会被发现。
- 您还需要构buildtesting以确保您的插件能够在您没有想到的情况下工作。 而我正在谈论跨浏览器testing!
听起来很复杂? 如果您想要某些function忽略突出显示的某些元素,变音符映射,同义词映射,内部iframesearch,分词search等,这变得越来越复杂。
使用现有的插件
当使用现有的,很好实施的插件,你不必担心上述命名的事情。 第10条jQuery文字荧光笔插件 Sitepoint比较stream行的荧光笔插件。 这包括这个问题的答案的插件。
看看mark.js
mark.js是一个用纯JavaScript编写的插件,也可以作为jQuery插件使用。 它的开发提供了更多的机会比其他插件与选项:
- 单独search关键字而不是完整的术语
- 地图变音符号(例如,如果“justo”也应该匹配“justò”)
- 忽略自定义元素内的匹配
- 使用自定义高亮元素
- 使用自定义高亮类
- 映射自定义同义词
- 也search内部框架
- 收不到条款
DEMO
或者你可以看到这个小提琴 。
用法示例 :
// Highlight "keyword" in the specified context $(".context").mark("keyword"); // Highlight the custom regular expression in the specified context $(".context").markRegExp(/Lorem/gmi);
它是免费的,在GitHub上开发开源( 项目参考 )。
这是一个忽略和保留情况的变化:
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>";}); }); };
您需要获取p标签的内容,并用高亮显示的版本replace所有的标签。
你甚至不需要有这个jQuery。 🙂
你可以使用我的高亮插件jQuiteLight ,也可以使用正则expression式。
使用npmtypes进行安装:
npm install jquitelight --save
要使用凉亭types安装:
bower install jquitelight
用法:
// for strings $(".element").mark("query here"); // for RegExp $(".element").mark(new RegExp(/query h[az]+/));
更高级的用法在这里
我写了一个非常简单的函数,它使用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); }); }); } }
更多信息:
的jsfiddle
使用.each(),.replace(),.html()。 使用jQuery 1.11和3.2进行testing。
在上面的例子中,读取'关键字'来突出显示,并将'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; }
我创build了一个类似概念的存储库 ,它改变了HTML5识别颜色的文本的颜色(我们不必使用实际的#rrggbb值,只能使用名称为html5的标准化约140个标准)
colors.js
$( 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>
如果你真的是游戏,你可以通过StackOverflow的源代码来查看代码块的语法突出显示方式;)
基本上,你将不得不dynamic插入HTML(跨度将是最好的),在你需要他们的地方。
是否有可能得到这个上面的例子:
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标签内部replace文本一样,否则会破坏页面。
$(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在这里