on-page text highlighting Search with jQuery
Websites often have search boxes to allow users to find content from their archives. But what if you want to find content on the given page? Information Architects had on-page text search that provides a great user experience. Let’s recreate this using jQuery.
Mark-Up and Interaction
First let’s build an input box for the search:
<input type="text" id="text-search" />
Next we’ll need jQuery to attach a listener to track changes to the input box:
$(function() { $('#text-search').bind('keyup change', function(ev) { // pull in the new value var searchTerm = $(this).val(); )}; });
Here we bound our function to both the keyup
and change
events. This ensures that our operation fires regardless of whether the user types or pastes the text.
Now, let’s turn to Highlight, a useful and lightweight jQuery plug-in that handles text highlighting. After including the plug-in source, let’s add a highlight()
call to our [removed]
$(function() { $('#text-search').bind('keyup change', function(ev) { // pull in the new value var searchTerm = $(this).val(); // disable highlighting if empty if ( searchTerm ) { // highlight the new term $('body').highlight( searchTerm ); } }); });
In addition to highlighting the given text, we’ve also added a check to make sure the search term isn’t empty (which causes an infinite loop).
This snippet highlights the search query throughout the page, but we can also limit the scope to a given id
:
$('#myId').highlight( searchTerm );
Or we can search only within a certain element:
$('p').highlight( searchTerm );
This text highlighting by default is case insensitive. If you’d prefer case-sensitive highlighting, remove the .toUpperCase()
on both lines 21 and 41 of the Highlight plug-in.
Styling the Highlighted Text
Now that the JavaScript is attached, we’ll need to style our highlighted items. The Highlight plug-in wraps the highlighted terms in <span class="highlight"></span>
, which we can style with CSS.
First, let’s change the background color and then add rounded corners and a drop-shadow for all browsers except IE:
.highlight { background-color: #fff34d; -moz-border-radius: 5px; /* FF1+ */ -webkit-border-radius: 5px; /* Saf3-4 */ border-radius: 5px; /* Opera 10.5, IE 9, Saf5, Chrome */ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); /* FF3.5+ */ -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); /* Saf3.0+, Chrome */ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); /* Opera 10.5+, IE 9.0 */ }
Although the highlighting is now visible, it still appears a bit tight around the text and could use some padding. But we’ll have to be careful not to adjust the layout of text. These span
s are inline elements, and if we simply add padding, the text will shift around on the page. So, let’s include padding with a negative margin to compensate:
.highlight { padding:1px 4px; margin:0 -4px; }
Finishing the Interaction
Last but not least, let’s make sure to remove the highlighted text whenever the user edits text in the input box:
$(function() { $('#text-search').bind('keyup change', function(ev) { // pull in the new value var searchTerm = $(this).val(); // remove any old highlighted terms $('body').removeHighlight(); // disable highlighting if empty if ( searchTerm ) { // highlight the new term $('body').highlight( searchTerm ); } }); });
Here we added a call to remove any text highlighting, which is performed outside of the empty field check. This ensures that the highlight is also removed if the user clears the field.
Although removeHighlight()
works well in most browsers, it will crash IE6. This is due to an IE6 bug with node.normalize()
.
We can get the Highlight plug-in working in IE6 by rewriting this function. Simply replace lines 45-53 of highlight.js
with the following:
jQuery.fn.removeHighlight = function() { function newNormalize(node) { for (var i = 0, children = node.childNodes, nodeCount = children.length; i < nodeCount; i++) { var child = children[i]; if (child.nodeType == 1) { newNormalize(child); continue; } if (child.nodeType != 3) { continue; } var next = child.nextSibling; if (next == null || next.nodeType != 3) { continue; } var combined_text = child.nodeValue + next.nodeValue; new_node = node.ownerDocument.createTextNode(combined_text); node.insertBefore(new_node, child); node.removeChild(child); node.removeChild(next); i--; nodeCount--; } } return this.find("span.highlight").each(function() { var thisParent = this[removed]; thisParent.replaceChild(this.firstChild, this); newNormalize(thisParent); }).end(); };
his new function replaces the standard Javascript normalize()
with a custom function that works in all browsers.
You might also like
Tags
accordion accordion menu animation navigation animation navigation menu carousel checkbox inputs css3 css3 menu css3 navigation date picker dialog drag drop drop down menu drop down navigation menu elastic navigation form form validation gallery glide navigation horizontal navigation menu hover effect image gallery image hover image lightbox image scroller image slideshow multi-level navigation menus rating select dependent select list slide image slider menu stylish form table tabs text effect text scroller tooltips tree menu vertical navigation menu