使用 jQuery 突出显示单词

Highlight a word with jQuery

提问人:nickf 提问时间:9/23/2008 最后编辑:arhaknickf 更新时间:7/29/2022 访问量:197136

问:

我基本上需要突出显示文本块中的特定单词。例如,假设我想在这段文字中突出显示“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中会让事情变得更整洁一些。

javascript jquery html

评论

1赞 Jose Rui Santos 3/6/2012
与其用 a 突出显示单词,不如从语义上讲使用 更正确。<span><mark>
0赞 Jaspreet Chahal 6/27/2012
嗨,我上船晚了,但这是另一个代码片段,有助于根据标签突出显示和过滤文本。希望这能帮助某人 jQuery 插件用于文本突出显示和过滤
3赞 Marcel Stör 3/8/2011
如果您需要 jQuery 突出显示插件的宽松版本:http://www.frightanic.com/2011/02/27/lenient-jquery-highlight-plugin-javascript/
0赞 7/1/2009
嘿,我写了一个插件来做这件事——它就像 Johann Burkard 发布的插件 mlarsen 一样,但使用正则表达式而不是字符串。在 github 上查看,如果您需要其他功能,请告诉我。
0赞 dude 9/24/2015
您可能对这个插件感兴趣: github.com/julmot/jmHighlight .它可以单独突出显示关键字或作为术语突出显示,可以突出显示与您的自定义元素和类名的匹配项,还可以搜索变音符号。在顶部,它允许您过滤搜索匹配项的上下文

答:

1赞 Sebastian Hoitz 9/23/2008 #1

您需要获取 p 标签的内容,并将其中的所有 dolors 替换为突出显示的版本。

你甚至不需要有jQuery。:-)

评论

9赞 ehm 9/23/2008
但是使用jQuery更容易,不是吗?;)
9赞 okliv 10/21/2014
它可以用诺基亚 6310 完成,你甚至不需要为此安装 PC :-)
87赞 mlarsen 9/23/2008 #2

尝试突出显示: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);
    });
};

评论

0赞 Erick Robertson 4/22/2014
有两种解决方案,它们分别包含在一个文件中。我在上面添加了它们。至少,在最坏的情况下,它们将始终在编辑历史记录中可用。
0赞 Lerin Sonberg 1/24/2015
Highlight v4 有点问题。Burkard 的主页上有一个修复程序:johannburkard.de/blog/programming/javascript/...在这种情况下,在这里复制代码不是一个好主意;该链接指向最新版本(现在:))。
0赞 unitario 5/20/2015
顺便说一句,这里的 <mark>-tag 可能比 <span> 标签更好。
1赞 Greg 7/8/2016
如果你正在寻找小巧轻量级的产品,那么 highlight jquery 插件确实是你的最佳选择。它非常适合突出显示和删除与给定文本匹配的突出显示。如果您需要正则表达式或其他支持;但是,请查看 Mark.js 或从突出显示页面链接到的任何扩展和分支。我使用突出自己而不是其他人,因为轻量级受到高度赞赏。
5赞 Lukars 3/12/2018
重要提示:Johann Burkard 在其网站上提供的源代码中包含了一个挖掘脚本!!!!!
42赞 Andrew Hedges 9/23/2008 #3
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');

评论

2赞 Stephan Kristyn 8/23/2012
你不想使用innerHTML,因为它是Microsoft在80年代推出的,后来又像往常一样被Microsoft放弃了。尽管大多数浏览器都支持它,但它是 W3C 标准之外的一切。
22赞 Kebman 5/3/2013
你应该用什么来代替innerHTML?
15赞 Jay Dansand 7/23/2014
@Sir Ben Benji:我认为你把innerHTML和innerText混淆了(Microsoft开发的textContent的替代品,这确实是规范的诅咒)。innerHTML 可能最初是作为 Microsoft 扩展开始的,但绝没有被“删除”;自 2000 年代初以来,它一直受到所有主要浏览器的支持,并且是 HTML5 的一部分(早在 2008 年): w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml 它仍然存在于 w3.org/TR/DOM-Parsing 的最新版本中。另请参阅 w3.org/TR/html5/references.html#refsDOMPARSING
1赞 Richard Lindhout 6/1/2016
这不是一个非常好的解决方案。我刚刚使用了这个,但是如果我搜索例如“person”,它也会将所有类和 html 元素替换为“person”。而且小写和大写也没有集成。var rgxp = new RegExp(“(\\b” + word + “\\b)”, “gim”);修复了这个问题,但我认为代码不应该替换 html 元素。
-2赞 Fredrik Söderstr 1/2/2009 #4

是否有可能得到上面的例子:

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 标签中的文本,否则会破坏页面。

13赞 bjarlestam 4/20/2010 #5

下面是一个忽略并保留大小写的变体:

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>";});
    });
};

评论

6赞 Jonathan 3/2/2012
这适用于纯文本,但似乎不排除标签和属性。即,当您在 innerHTML 中的 div 上有 class 属性时,搜索“lass”。
0赞 jiy 2/28/2015
如何调用此函数?
0赞 dude 5/20/2016
innerHTML是邪恶的,请看我的答案。此外,不适用于 unicode 字符。此外,此函数几乎会遗漏任何内容,例如在嵌套子项中搜索。\\b
1赞 Hawkee 2/22/2013 #6

我编写了一个非常简单的函数,它使用 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/

评论

2赞 dude 5/1/2016
它不会在嵌套元素中搜索,没有删除突出显示的功能,也没有许可证信息。
0赞 vuquanghoang 4/25/2019
你介意向我解释一下“new RegExp(term, ”gi“)”中的“gi”是什么吗?
2赞 iamawebgeek 6/1/2015 #7

您可以使用我的高亮插件 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]+/));

更高级的用法在这里

评论

0赞 iamawebgeek 3/27/2016
@user3631654不,这是一个不同的插件。我的插件可以与正则表达式一起使用,并具有智能突出显示功能。如果你已经包含了你在这个插件之前提到的插件,你可以使用它var oldMark = $.fn.mark.noConflict()
0赞 user3631654 3/31/2016
似乎 jquery.mark 有一个方法也可以突出显示自定义正则表达式。所以这不应该是一个争论。markRegExp()
0赞 user3631654 3/31/2016
@zazu,你说的“智能突出显示”是什么意思?
0赞 iamawebgeek 3/31/2016
@user3631654,如果您打开智能突出显示并传递单词“consequnce”,它也会突出显示单词“consequences”及其其他形式,但如果您传递“the”或“bla”,则不会采用“theme”或“black”
42赞 dude 9/24/2015 #8

为什么使用自制的突出显示功能是个坏主意

从头开始构建自己的高亮功能可能是一个坏主意的原因是因为您肯定会遇到其他人已经解决的问题。挑战:

  • 您需要删除带有 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 上开源开发(项目参考)。

评论

0赞 Mizok.H 7/18/2022
但就我而言,我发现这个插件有点慢,有时需要 300 毫秒的延迟,我不知道为什么。mark.js
-2赞 L.Grillo 11/5/2015 #9
$(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在这里

评论

1赞 user3631654 3/26/2016
hilight没有有效的 HTML 元素
0赞 L.Grillo 3/28/2016
忽略此警告,<hilight>是您的自定义元素,您可以编写任何您想要的内容。你见过小提琴吗?
0赞 L.Grillo 3/28/2016
@nickf我的脚本执行与已接受的答案完全相同的事情
-1赞 abe312 10/13/2016 #10

我创建了一个类似概念的存储库,该存储库更改了 html5 识别其颜色的文本的颜色(我们不必使用实际的 #rrggbb 值,并且可以仅使用名称作为 html5 标准化的大约 140 个)

颜色:.js 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>

3赞 Van Peer 6/25/2017 #11

JSFiddle

使用。使用 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;
}
2赞 Cybernetic 3/1/2018 #12

您可以使用以下函数突出显示文本中的任何单词。

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')

enter image description here

评论

0赞 Muneeb Mirza 9/8/2020
该问题包含 html 标签,此代码将删除生成的 div 中的所有 html 标签。
0赞 Akhtarujjaman Shuvo 7/29/2022 #13

这是@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')