IT IS HERE! Get Smashing Node.JS on Amazon Kindle today!
Show Posts
← Back to homepage

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 + '';
		}));
	}

});

11 Comments

Rendez said

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…

James said

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)

    Guillermo Rauch said

    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.

Dewang said

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.

Reshma said

The search term is getting hilighted but for next search value,old hilight does not vanishes.so thats problem.

Your thoughts?

About Guillermo Rauch:

CTO and co-founder of LearnBoost / Cloudup (acquired by Automattic in 2013). Argentine living in SF.