How it works
A regular expression looks for text outside HTML tags. It uses a callback function to perform replacements to simulate native lookahead support.
When is this sort of replacement suitable ?
- Remote HTML responses (ajax) highlighting
- Autocompleters suggestion highlighting
- User-typed HTML, WYSIWIGs, etc.
Generally speaking, the only downside of this method, since it deals with the innerHTML, is that all attached events and properties are lost when the replacement is performed.
Note: this code is designed to match only beginning of words. If you want to match anywhere, remove \\b from the regular expression. And if you expect <script> tags, definitely don’t use it.
MooTools version (demo)
Element.implement({
highlight: function(search, insensitive, klass){
var regex = new RegExp('(<[^>]*>)|(\\b'+ search.escapeRegExp() +')', insensitive ? 'ig' : 'g');
return this.set('html', this.get('html').replace(regex, function(a, b, c){
return (a.charAt(0) == '<') ? a : '' + c + '';
}));
}
});
jQuery version (demo)
jQuery.fn.extend({
highlight: function(search, insensitive, klass){
var regex = new RegExp('(<[^>]*>)|(\\b'+ search.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1") +')', insensitive ? 'ig' : 'g');
return this.html(this.html().replace(regex, function(a, b, c){
return (a.charAt(0) == '<') ? a : '' + c + '';
}));
}
});
10 Comments
Cool Guillermo!
I had the need to develop this one before, never released though, ouch!
Very clean code ;)
Thanks for sharing!
I was using this regex so far in my autocomplete plugin, I’m now trying to figure out the differences and which version is more effective:
return value.replace(new RegExp(“(?![^&;]+;)(?!<[^]*)(” + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, “\\$1″) + “)(?![^]*>)(?![^&;]+;)”, “gi”), “$1“);
The term-replace seems to be very similar, still not the same. The value-replace is quite different. Your version is certainly easier to understand…
I tried something like this a while ago (http://james.padolsey.com/javascript/highlighting-text-with-javascript/), but, as evident from one of the comments, using regular expressions + innerHTML is not a good idea. Not only is malformed HTML an issue, but, as you’ve said, it can mess up events and properties of elements within. The only solid way to achieve this it to walk the DOM and look for text nodes. (node.nodeType === 3)
Malformed HTML is not an issue. Plus, the only way to reliably walk the DOM is with well formed XML is in the first place :)
This is not the definite highlighting solution, but it’s good for many purposes.
Pingback: How to Highlight Search Terms with jQuery | Weblog Tools Collection
Pingback: Highlight Your Searches « Rohit Singh Sengar
Pingback: Kune.fr » Blog Archive » WP Serie: Les meilleurs hacks wordpress #1
Is there any way to highlight sentences which have links in them? in the demo, if you select a sentence which has a link like “A selector is a chain of one or more sequences of simple selectors separated by combinators.”
then the text is not selected.