使用 jQuery 突出显示 html 中的文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9167855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Highlight text inside html with jQuery
提问by Mike
I am looking to do something similar to this plugin http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
我希望做一些类似于这个插件http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
But the problem I am facing is that the above plugin does not allow you to highlight words within html.
但是我面临的问题是上述插件不允许您突出显示 html 中的单词。
So if you are looking for my text
所以如果你正在寻找 my text
inside html like
里面的 html 喜欢
this is <a href="#">my</a> text that needs highlighting
You will not get any highlighting.
你不会得到任何突出显示。
Is there a way to highlight text while ignoring any html tags in between?
有没有办法在忽略中间的任何 html 标签的同时突出显示文本?
采纳答案by Julien Schmidt
I fiddled some RegEx which allows HTML tags at the position of whitespace chars:
我摆弄了一些 RegEx,它允许在空白字符的位置使用 HTML 标签:
<div id="test">this is <a href="#">my</a> text that needs highlighting</div>
JavaScript:
JavaScript:
var src_str = $("#test").html();
var term = "my text";
term = term.replace(/(\s+)/,"(<[^>]+>)*(<[^>]+>)*");
var pattern = new RegExp("("+term+")", "i");
src_str = src_str.replace(pattern, "<mark></mark>");
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"</mark><mark>");
$("#test").html(src_str);
Try it here: http://jsfiddle.net/UPs3V/
在这里试试:http: //jsfiddle.net/UPs3V/
回答by HMR
I would like to leave a comment but stack doesn't allow me or I can't seem to find a button for it so have to do it in an answer. There is a problem with the script. for example: Highlighting fox in the following string:
我想发表评论,但堆栈不允许我或我似乎找不到它的按钮,所以必须在答案中做。脚本有问题。例如:在以下字符串中突出显示 Fox:
<img src="brown fox.jpg" title="The brown fox" /><p>some text containing fox.</p>
Would break the img tag:
会破坏 img 标签:
var term = "fox";
term = term.replace(/(\s+)/,"(<[^>]+>)*(<[^>]+>)*");
var pattern = new RegExp("("+term+")", "i");
src_str ='<img src="brown fox.jpg" title="The brown fox" />'
+'<p>some text containing fox.</p>'
src_str = src_str.replace(pattern, "<mark></mark>");
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"</mark><mark>");
src_str
I was working on a highlight script and solved that problem not realizing the script might have to highlight over multiple tags. Here is how I got it not to destroy tags by trying to highlight content within tags, this script highlights multiple instances within content as well but not over multiple tags:
我正在编写一个高亮脚本并解决了这个问题,但没有意识到脚本可能必须在多个标签上高亮显示。这是我如何通过尝试突出显示标签中的内容来不破坏标签,这个脚本也突出显示了内容中的多个实例,但不是在多个标签上:
str='<img src="brown fox.jpg" title="The brown fox" />'
+'<p>some text containing fox. And onother fox.</p>'
var word="fox";
word="(\b"+
word.replace(/([{}()[\]\.?*+^$|=!:~-])/g, "\")
+ "\b)";
var r = new RegExp(word,"igm")
str.replace(/(>[^<]+)/igm,function(a){
return a.replace(r,"<span class='hl'></span>");
})
Not sure how to combine these scripts and make a highlight over multiple tags work but will keep my eye on this thread.
不确定如何组合这些脚本并突出显示多个标签的工作,但我会密切关注这个线程。
回答by podperson
I tried the accepted solution and it seems to break on complex pages such as this one (infinite recursion). Also, I don't really see the benefit of relying on jQuery, so I rewrote the code to be independent of jQuery (it's also substantially shorter and doesn't support the fancy options).
我尝试了公认的解决方案,它似乎在复杂的页面上崩溃了,比如这个(无限递归)。此外,我并没有真正看到依赖 jQuery 的好处,所以我重写了代码以独立于 jQuery(它也大大缩短了并且不支持花哨的选项)。
It's easy enough to add the options back in and use classes if you like.
如果您愿意,可以很容易地重新添加选项并使用类。
function highlight(re, node, depth, maxdepth){
node = node || document.body;
depth = depth || 0;
maxdepth = maxdepth || 10;
if( node.nodeType === 3 ){
var match = node.data.match(re);
if(match){
var span = document.createElement('span');
span.style.backgroundColor = '#ffa';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
span.appendChild(wordClone);
wordNode.parentNode.replaceChild(span, wordNode);
return 1;
}
} else if( depth === maxdepth ){
console.log( 'Reached max recursion depth!', node );
} else if( (node.nodeType === 1 && node.childNodes) && !/(script|style)/i.test(node.tagName) ) {
for( var i = 0; i < node.childNodes.length; i++ ){
i += highlight(re, node.childNodes[i], depth + 1, maxdepth);
}
}
return 0;
}