Searching Body Text with textRange: Enter the Gecko

This article focuses on turning the IE only body-text searching JavaScript file from the previous article into something that is supported and works on browsers using the Gecko layout engine. The conversion is surprisingly simple, and due to the advanced window.find() method compatible with Gecko, the script is actually smaller, with fewer moving parts!

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 41
July 07, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Calling this article "Using the textRange Object to Search Body Text" is actually a bit of a misnomer, because there is no textRange object in the gecko DOM.  However, as the script provides the same function as the scripts in the previous articles, it follows on to a sensible conclusion to what has been discussed already.

There is no textRange simply because one is not needed in browsers such as Mozilla, FireFox or Netscape. The find() method of the window object is advanced enough to be able to search through the text in the body of a document without even needing to capture the text using the textRange object. Ranges of any kind just don’t need to be used.

The script used here was written by myself but inspired by a script created by Jason Karl Davis (http://www.jasonkarldavis.com/) that uses DOM treewalking methods to traverse the text nodes of the document and match search words against their contents. DOM scripting has not been used in this example at all, simply because the power provided by it is not required in a search script of the same scope as the one discussed in parts one and two.

The script I will discuss has been tested on Mozilla 1.7.6 and 1.7.8, Firefox 1.0 and 1.0.4 and Netscape versions 7.2 and 8, and has been found to work as intended on all of them. To create a test version of this script, create a new js file. The variables can still be defined at the top of the file, but the range variable will not be needed:

var searchWord

var match

var button1clicked

The first function

Again, you’ll need two functions, each mapped to its respective button in the HTML file. The first function does the searching:  

function textSearch() {

  button1clicked = 1

  searchWord = prompt("Please enter a word to search for", "", "Search");

  if (searchWord == "") || (searchWord == null)) {

    return false

  }

 

  match = window.find(searchWord, false, false, false, true, false, false);

 

  if (match == false) {

    window.alert("Couldn't find '" + searchWord + "'");

  }

}

As you can see, the button1clicked flag is still set, which enables us to handle the second button being clicked prior to the first button. A variable is then set to hold the input captured by a prompt box. The first of the prompt objects takes a descriptive string, the second parameter is a value that can be placed in the input box on the prompt by default, but is not needed in this example. The final parameter specifies the prompt box title. When you run the script, you’ll see that the title of the prompt box will also contain the text [JavaScript application] which is part of the chrome architecture (also a core part of Mozilla based browsers) and therefore cannot be removed. 

The first if statement checks that an empty string hasn’t been retuned for a value of ‘null’, which would occur if the cancel button on the prompt was selected, and alerts the user as necessary. The second if statement produces an appropriate alert if match is equal to false, meaning that the body text did not contain an instance of the search word.

Sandwiched comfortably between the if staments, the match variable is set to true or false depending on the result of the find method that is applied to the window object. This method is intelligent enough to know that you are searching for text within the text of the window. This method takes a hefty seven parameters, which control how the search is performed; the first parameter is the string to search for. The rest are as follows: caseSensitive, searchBackwards, wrapAround, wholeWord, searchInFrames, and showDialog, the functions of which, I’m sure, are fairly obvious. The last parameter there, the showDialog boolean value, actually controls a built-in text finder/replacer; if you set this to true, however, the rest of your code will still execute and the built-in text dialog will remain hanging around after ours has finished.

As you can see, there are no references to ranges of any kind and no code which controls the highlighting of words matched against the search word. This is handled automatically by the browser. All in all, this is a lot simpler than the IE specific code.

The second function

The second function can be added with the following code:

function searchNext() {

  if (button1clicked != 1) {

    window.alert("No search word entered!");

  } else {

    If (searchWord == null) {

      Window.alert("No search word entered!");

    return false

    }

    match = window.find(searchWord, false, false, false, true, false, false);

    if (match == false) {

      window.alert("No more matches");

    }

  }

}

It first checks that the flag is set to one and produces an appropriate message if not. Providing the flag is set, it simply calls the find method of the window object again. Not only is this method smart enough to do the searching and highlighting on its own, it is able to keep track of words it has found already and automatically move on to and highlight the next occurrence of the specified search word! Again, this cuts down considerably on our code. The script will continue highlighting matches until it finds no more and produces the final alert to say that no more instances of the word exist.

That’s it. Save the file as behaviour(moz).js and amend the HTML file to link to the new one. Open the HTML page in any of the supported Gecko based browsers and see it in action.

Create a master script file

The next logical thing to do is to create a master script file that contains both versions of each of the functions, and includes an additional function that directs the flow of the script towards whichever version of the functions will work on the browser that the visitor to the page is using. This way, separate versions of the script, tailored toward different browsers, do not need to exist for different pages of your site.  

This can be done fairly easily with the addition of another function at the top of the page that is tied to the onload event, which as you know, is fired when the page has loaded. For the sake of simplicity, create a new js file now called behaviour(all).js and add all of the variables from both functions at the top, with a new variable called ieyes beneath them:

var searchWord

var range

var match

var button1clicked

var ieyes

The new variable also needs to be global because it will be accessed by both of the searching functions tied to the buttons. Now add a function directly below this called browserTest() and add the following code to it:

function browserTest() {

  if (document.body.createTextRange() != 'undefined') {

    ieyes = 1

  }

}

All this does, is try to create a text range from the body text. If it can’t do this, the browser that is being used is not IE, because we know that IE does support this method, therefore ieyes is not set. If the browser does support it, the variable is set to 1 and this variable acts as a flag for use later on in the script. This function should be called, as stated above, by adding a function call to the body tags’ onload event. 

Next, the textSearch() function should be added as follows:

function textSearch() {

  button1clicked = 1

  if (ieyes==1) {

    //ie specific code here…

  } else {

    //Gecko specific code here…

  }

}

Similarly, the searchNext() function is laid out thus:

function searchNext() {

  if (ieyes==1) {

    //ie specific code here…

  } else {

    //Gecko specific code here…

  }

}

Now, each of the functions retain the same name and can therefore be called from the same buttons, whether those buttons are rendered in a Gecko or non-Gecko environment. Each section contains each of the browser specific sections of code that will work under whichever browser the user is viewing the page with. Testing the browser for the feature that you want to make use of in this way is better than using the useragent variable of the browser object, because it ensures that the feature that we want to use exists and doesn’t make assumptions about the features of a browser based on its often misleading useragent variable.

Once the above file is saved, remember to link it to the HTML page and then test it to your heart's content using Internet Explorer, Mozilla, Netscape or Firefox. You should find that this one script file works under all of these browsers and everything works in the desired way.  There is still room for improvement. You may have noticed that, when searching for words that appear near the bottom of the page, the buttons move out of view when the word has been found. This may or may not affect the usability of the script, depending on how you implement the script and on which pages. One thing that you could do is place the buttons on a free-floating frame that moves down the page automatically as the page moves down. 

Nevertheless, many pages, especially those with a lot of textual information on them, will benefit greatly from this in-page searching method that is a working remnant of the pre-DOM DHTML era.    

blog comments powered by Disqus
CODE EXAMPLES ARTICLES

- Bipartite Graphs
- Connectivity in Graphs
- The Ford-Fulkerson Algorithm
- Critical Paths
- The Bellman-Ford and Roy-Floyd Algorithms
- Shortest Path Algorithms in Graphs
- Minimum Spanning Tree
- Articulation Edges and Vertexes
- Circles and Connectivity in Graphs
- Depth-First Search in Graphs
- Breadth-First Search in Graphs
- The Prufer Code and the Floyd-Warshall Algor...
- An Insight into Graphs
- Coding a Custom Object with WSC
- Creating a Custom Object with WSC

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 10 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials