Full version: jsB@nk » Utility » Search-code » Search the Page
URL: https://www.javascriptbank.com/search-the-page.html
This JavaScript will allow your visitors to search a Web page for any matching characters. It can be set for the entire page or within a specific ID attribute. Simple to use and heavily annotated.
Full version: jsB@nk » Utility » Search-code » Search the Page
URL: https://www.javascriptbank.com/search-the-page.html
<script type="text/javascript">// Created by: Robin Winslow | http://www.robinwinslow.me.uk// Find and select all text in the document that matches the "value" of the element passed// If no element if passed, it will attempt to use the value of "this"// Only works in a browser that supports the "window.getSelection" method, as other selection methods don't support multiple selectionszfunction performMultiSearch(elem,searchElem) { // set up variables var searchString; // Will hold the text to search for var theSelection; // Will hold the document's selection object var textNodes; // Will hold all the text nodes in the document // Set it to search the entire document if we haven't been given an element to search if(!searchElem || typeof(searchElem) == 'undefined') searchElem = document.body; // Get the string to search for if(elem && elem.value) searchString = elem.value; else if(this && this.value) searchString = this.value; // Get all the text nodes in the document textNodes = findTypeNodes(searchElem,3); // Get the selection object if(window.getSelection) theSelection = window.getSelection(); // firefox else { // some other browser - doesn't support multiple selections at once alert("sorry this searching method isn't supported by your browser"); return; } // Empty the selection theSelection.removeAllRanges(); // We want to empty the selection regardless of whether we're selecting anything if(searchString.length > 0) { // make sure the string isn't empty, or it'll crash. // Search all text nodes for(var i = 0; i < textNodes.length; i++) { // Create a regular expression object to do the searching var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive var stringToSearch = textNodes[i].textContent; while(reSearch(stringToSearch)) { // While there are occurrences of the searchString // Add the new selection range var thisRange = document.createRange(); thisRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range thisRange.setEnd(textNodes[i],reSearch.lastIndex); // End node and index of the selection theSelection.addRange(thisRange); // Add the node to the document's current selection } } } return;}// Will find and select the first instance of the value of the passed element, then when called again will moves on to the next instance// If no element passed it will try to get the value from "this"function performSingleSearch(elem,searchElem) { // set up variables var searchString; // Will hold the text to search for var theSelection; // Will hold the document's selection object var textNodes; // Will hold all the text nodes in the document // Set it to search the entire document if we haven't been given an element to search if(!searchElem || typeof(searchElem) == 'undefined') searchElem = document.body; // Get the string to search for if(elem && elem.value) searchString = elem.value; else if(this && this.value) searchString = this.value; if(searchString && searchString.length > 0) { // make sure the string isn't empty, or it'll crash. if(window.getSelection) { // Firefox // Get the selection theSelection = window.getSelection(); // Get all the text nodes in the document textNodes = findTypeNodes(searchElem,3); // If there's already a selection, and it's the string we're searching for var searchMatch = new RegExp(searchString,'i'); if(theSelection.rangeCount == 1 && searchMatch(theSelection.getRangeAt(0).toString())) { var currentRange = theSelection.getRangeAt(0); theSelection.removeAllRanges(); var newRange = null; // Move on to the next occurrence of it by iterating through text nodes...: for(var i = 0; i < textNodes.length; i++) { // If this text node is before the currentRange, ignore it and carry on to the next one if(currentRange.comparePoint(textNodes[i],0) == -1 && currentRange.startContainer != textNodes[i]) continue; // If this text node is the same as the currentRange, find the point in the currentRange else if((currentRange.comparePoint(textNodes[i],0) == -1 && currentRange.startContainer == textNodes[i]) || (currentRange.comparePoint(textNodes[i],0) == 0)) { // Create a regular expression object to do the searching var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive var stringToSearch = textNodes[i].textContent; while(reSearch(stringToSearch)) { // While there are occurrences of the searchString // Test if the index is after the currentRange's position if(reSearch.lastIndex - searchString.length > currentRange.startOffset) { // This is the new search position - empty the old selection and add the new selection range theSelection.removeAllRanges(); newRange = document.createRange(); newRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range newRange.setEnd(textNodes[i],reSearch.lastIndex); // End node and index of the selection break; // We're not interested in the other results, so break out of this while loop. } } if(newRange) break; // If we found a new range, break out of this for loop, cos there's nothing more to do. else continue; // Otherwise continue } // If this text node is after the current one, search to see if it has any occurrences of the searchString else if(currentRange.comparePoint(textNodes[i],0) == 1) { // Create a regular expression object to do the searching var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive var stringToSearch = textNodes[i].textContent; // If we had a find, use it if(reSearch(stringToSearch)) { // This is the new search position - empty the old selection and add the new selection range theSelection.removeAllRanges(); newRange = document.createRange(); newRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range newRange.setEnd(textNodes[i],reSearch.lastIndex); // End node and index of the selection break; // We're not interested in the other results, so break out of this while loop. } else continue; } } if(newRange) { theSelection.addRange(newRange); // Add the node to the document's current selection // Make the new range visible newRange.startContainer.parentNode.scrollIntoView(false); return; } else performSingleSearch(elem,searchElem); } // If we don't already have a selection, just find the first instance else { // Search all text nodes for(var i = 0; i < textNodes.length; i++) { // Create a regular expression object to do the searching var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive var stringToSearch = textNodes[i].textContent; if(reSearch(stringToSearch)) { // If there are occurrences of the searchString // This is the new search position - empty the old selection and add the new selection range theSelection.removeAllRanges(); // Add the new selection range var thisRange = document.createRange(); thisRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range thisRange.setEnd(textNodes[i],reSearch.lastIndex); // End node and index of the selection theSelection.addRange(thisRange); // Add the node to the document's current selection thisRange.startContainer.parentNode.scrollIntoView(false); break; // We're done } } } } else if(document.selection) { // Internet Explorer theSelection = document.selection; var currentRange = theSelection.createRange(); // Create text range to cover the whole of the searchElem var searchRange = document.body.createTextRange(); searchRange.moveToElementText(searchElem); // Empty the current selection theSelection.empty(); // If this text is already selected, find the next selection if(currentRange && currentRange.text && currentRange.text.match(eval('/'+searchString+'/i'))) { // Move start position of range past this word currentRange.moveStart('character'); // Move end position to end of the search element currentRange.setEndPoint('EndToEnd',searchRange); // Search again if(currentRange.findText(searchString)) { // We have found another instance currentRange.select(); // Set the key press event, keeping the functionality of the old one as well // This is so that IE will cycle on to the next search result when you press enter, something that Firefox did already var currentkeypress = document.body.onkeypress; window.setTimeout(function() { document.body.onkeypress = function(evt) { if(!evt) evt = window.event; // for internet explorer // If the selection is still what we thought it was var nowRange = document.selection.createRange(); if(nowRange.htmlText == currentRange.htmlText) { if(evt.keyCode == 13) { // If enter key pressed // Set the onkeypress back to what it was document.body.onkeypress = currentkeypress; // Perform the search performSingleSearch(elem,searchElem); } } else { // If the selection isn't what we though, set the onkeypress back to what it was document.body.onkeypress = currentkeypress; } // Either way, perform old onkeypress event as well if(currentkeypress) currentkeypress(evt); } },30); return true; } else performSingleSearch(elem,searchElem); } else { // Find the first occurrence of the searchString if(searchRange.findText(searchString)) { // If we've found something, select it searchRange.select(); // Set the key press event, keeping the functionality of the old one as well // This is so that IE will cycle on to the next search result when you press enter, something that Firefox did already var currentkeypress = document.body.onkeypress; window.setTimeout(function() { document.body.onkeypress = function(evt) { if(!evt) evt = window.event; // for internet explorer // If the selection is still what we thought it was var nowRange = document.selection.createRange(); if(nowRange.htmlText == searchRange.htmlText) { if(evt.keyCode == 13) { // If enter key pressed // Set the onkeypress back to what it was document.body.onkeypress = currentkeypress; // Perform the search performSingleSearch(elem,searchElem); } } else { // If the selection isn't what we though, set the onkeypress back to what it was document.body.onkeypress = currentkeypress; } // Either way, perform old onkeypress event as well if(currentkeypress) currentkeypress(evt); } },30); return true; } else { return false; } } } else alert("Sorry your browser doesn't support a supported selection object"); }}// Recursively find all text nodes within an elementfunction findTypeNodes(elem,type) { // Remove superfluous text nodes and merge adjacent text nodes elem.normalize(); var typeNodes = new Array(); // Search all children of this element to see which ones are the right type of node for(var nodeI = 0; nodeI < elem.childNodes.length; nodeI++) { if(elem.childNodes[nodeI].nodeType == type) typeNodes.push(elem.childNodes[nodeI]); // If it is a the right type of node, add it to the array else { // If not a the right type of node, search it in turn typeNodes = typeNodes.concat(findTypeNodes(elem.childNodes[nodeI],type)); } } return typeNodes; // return the array}// Multiple onload function created by: Simon Willison// http://simon.incutio.com/archive/2004/05/26/addLoadEventfunction addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } }}addLoadEvent(function() { // Create a button var theInput = document.getElementById('searchInput'); var theButton = document.getElementById('performSearch'); var elementToSearch = document.body; // Use getElementById('yourIDName') to only allow search for a specific id. theButton.onclick = function() { // Set the onclick function performSingleSearch(theInput,elementToSearch); } // Also perform search on enter press theInput.onkeypress = function(evt) { if(!evt) evt = window.event; // for internet explorer if(evt.keyCode == 13) performSingleSearch(theInput,elementToSearch); }});</script><!-- This script downloaded from www.JavaScriptBank.com Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->
<fieldset style="width: 240px;"> <legend>Search the page</legend> <input type="text" id="searchInput"><button id="performSearch">search</button></fieldset><!-- This script downloaded from www.JavaScriptBank.com Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->