JavaScript Tip of the Week for October 7, 1996: History Tracker | WebReference

JavaScript Tip of the Week for October 7, 1996: History Tracker

JavaScript Tip of the Weekfor October 7, 1996: History Tracker

Maybe its just me but I don't like the way Netscape keeps track of the history of pages you visited, so I created an alternative for JavaScript Tip of the Week. It's logically named the History Tracker, and it will track every page on your web site. It doesn't track any pages that do not exist on your server for security reasons. It not only records the URL and title of a page, but it also allows you to replay your browsing activites in chronological order. This is just one of its features; more will be added in the future.
Modifiying this to work on your own site is very simple, it takes only the changing of three variables.
    bmDomain     = "C|/";    <-- domain where tracker works
    bmReal       = new Array();   
    bmName       = "jtotw";  <-- name of history object 
    bmTotal      = 0;             
    bmTotalallow = 20;       <-- the total number of pages allowed
    bmReplayIP   = false;
    urlLast      = "";  
The first variable, bmDomain, is used by the tracker to determine whether or not the browser is on a page in your site. If you are on a page that is not on your server, the remote will not record anything. This is important because if the tracker tries to grab the title of a document not on your server it will get a security access error. The next variable, bmName, is not all that important but is needed for a future version of this app that will store the history to the cookie (a version of this is already working but is very slow). The last variable you need the modify, bmTotalallow, tells the tracker how many pages it should keep track of. I chose twenty-five, but you can even go up to 200 without much trouble.

This whole app is based on an aspect of JavaScript called user-defined objects. For the sake of this tip, here's an explanation of what an object is. Essentialy a user-defined object is a group of variables that all travel together and are related.

In the case of the History Tracker, the main object is the page object, which is reffered to in the code as bmReal[x]. The page object is indexed as an array, starting at zero and ending at one minus the total number of stored pages (the array starts at zero, not one). Every page object has two main properties: description and URL or desc and url. The description property stores the title of the page. The URL property stores the URL of the page. As with all objects, these properties can be accessed using this syntax:

    myvalue = objectname.propertyname;
Where myvalue would give you the value of the specified property. Now back to the Tracker... To load the tracker, a simple remote like function is used in the main page where you want to launch the Tracker [see Remotes]. This code does not need to be changed, just know that the Tracker program is in "tracker.html":
    var remoteWin = null;
    function remoteStart() {
    remoteWin ='','htRemote',
        if (remoteWin != null) {
                if (remoteWin.opener == null) {
                remoteWin.opener = self;
        remoteWin.location.href = "tracker.html";
When the tracker is first loaded, it creates an array of empty page objects, or bms (short for bookmarks). Then, it starts a setTimeout loop that checks if the location of the main browser window has changed. If it has, then the Tracker records the title and URL of the page, then creates a page object for it:
    function createBm(ncur, ndesc, nurl) { = bmName + ncur;      
    this.desc = ndesc;                             
    this.url = nurl;                
    this.comb = ndesc + "!~" + nurl; 
    function loadBm() {
    curTab = 0;
    bmTotal = 0;
    bmRealdone = false;
        for (curTab = 0; curTab 
Just so you know, all of these four functions, including the aforementioned variables, must be in the head of the "tracker.html" file. The first function, createBm(), is what is used to create a page object. The next function, loadBm, simply uses createBm() to create an array of the page objects. The last two functions aid each other in the process of adding new pages to the history. The first, addBm(), actually creates the new page object. Then if there are more than the total number of pages in history than you specified, shiftBm() deletes the oldest and shifts the rest down by one.
    function showBm() {
        if (bmTotal > 0) {
            if (bmReal[bmTotal - 1].url != "empty") {
            with (document.bmForm.bmSelect) {
            revBm = bmTotal - 1; 
                for (i = bmTotal - 1; i >= 0; i--) options[i] = null;
                for (i = 0; i 
This function, showBm, is used to display all of the pages' titles in the select menu. It runs through every page object that is not labeled as "empty" and displays them starting with the most recent. The last eight functions simply aid the tracker is replaying, changing, and jumping to pages that it has indexed. More will be added to these in the future, but all of these must be included for the Tracker to work:
    function replayChange() {
        if (opener.location != null) {
            if (repBm if (bmPlace != -1) = bmReal[bmPlace].url;
} If you take a moment to look at these functions, you'll see all they really do is manipulate the page object. For instance, changePage() just looks at the url property of the page object, then uses that property to go to the selected page in the Tracker's history. The replay functions take advantage of the fact that the page object is an array to jump from one to another. Finally, you need to display the Tracker in the "tracker.html" document:
        with (document) {
        writeln('<FORM NAME = "bmForm">');
        writeln('<SELECT NAME = "bmSelect">');
                for (i = 0; i < bmTotalallow; i++)
                writeln('<OPTION>You have No History as of Yet');
        writeln('<INPUT TYPE = BUTTON VALUE = "Jump!" onClick = "changePage(this.form)">');
        writeln('<INPUT TYPE = BUTTON VALUE = "Clear" onClick = "clearBm()">');
        writeln('<INPUT TYPE = BUTTON VALUE = "Replay" onClick = "replayBm(this.form)">');
        writeln('<INPUT TYPE = BUTTON VALUE = "Stop" onClick = "replayStop()">');
        for (i = bmTotalallow; i > 0; i--) 
        document.bmForm.bmSelect.options[i] = null;
I hope even if you didn't find the Tracker useful this tip has given you some knowledge of user-defined objects and how to use them.