Internet Explorer 5.0, Part III: Favorites Persistence - Doc JavaScript | WebReference

Internet Explorer 5.0, Part III: Favorites Persistence - Doc JavaScript

Favorites Persistence

Internet Explorer 5.0 introduces saveFavorite, a Behavior that enables persistent Favorites. This Behavior enables you to add a Web page to your Favorites list and load it back in the exact same shape. Let's practice it a little so you understand the power behind it.

Let's try adding the game board to your Favorites. After you have taken 3-4 turns in the Connect Three game, choose the Add to Favorites option from the game window's Favorites menu. Make sure you have some "o" and "x" pieces positioned on the board. Internet Explorer will add the page (favoritecallee.html) to your list of favorites. Now try selecting the page (favoritecallee.html) from the list of favorites. All "o" and "x" pieces are intact. The game board comes back in the exact same form it was left in the Favorites list. You have just witnessed the power of the saveFavorite Behavior. We explain next how to implement it.

There are a few changes you have to make in your Web page to be able to use the persistence Behaviors. First, you have to add the following META tag:

<META NAME="save" CONTENT="favorite">

Secondly, you need to define the saveFavorite Behavior as a built-in one:


Now we need to decide which elements we want to persist. We chose to persist the whole game board. A different decision could have been to persist, for example, just the three top boxes of the Connect Three board (don't know why would someone want to do it, though). The whole game board will persist by persisting the BODY tag. In order to enable a persistent element, you need to specify its Behavior via the CLASS attribute, assign an ID to the element, and define its onload() and onsave() event handlers. In our case of the BODY tag, the HTML statement looks like this:

<BODY CLASS="saveFavorite" ID="game"
 onload="handleBodyLoad()" onsave="handleBodySave()">

The onsave() event handler defines attributes that store whatever information you need to persist. In our Connect Three game, we save the gif file name of every box and the grid array holding the game piece in every box. We could have deducted the gif file names from the grid array, but we wanted to emphasize the way we persist both graphic and scalar information.

For each one of the nine boxes we save two attributes: one for its src property (gif file name), and the other one for its entry in the grid array. The name of the first attribute is a concatenation of the string box, the i and j indices of the box, and the string "srcPersistAttr." The right top box, for example, is positioned in i = 3 and j = 1, and hence its attribute name will be box31srcPersistAttr. Similarly, the grid array entry will be saved in grid31PersistAttr. As shown below, we use the setAttribute() method to create the attributes. We use a double loop, one for each index, to scan through all boxes:

function handleBodySave() {
  for( var i = 1; i <= 3; i++)
    for( var j = 1; j <= 3; j++) {
      game.setAttribute("box" + i + j + "srcPersistAttr",
        eval("box" + i + j + ".src")); // join with previous line
      game.setAttribute("grid" + i + j + "PersistAttr", grid[i][j]);

The onload() event handler is the handleBodyLoad() function. It decipher the attributes set by the handleBodySave() function. As shown below, we use the getAttribute() method to access the attributes saved in Favorites. Assembling the attribute names and box IDs is the same as in the handleBodySave() function:

function handleBodyLoad() {
  for( var i = 1; i <= 3; i++)
    for( var j = 1; j <= 3; j++) {
      if (game.getAttribute("box" + i + j + "srcPersistAttr"))
        eval("box" + i + j + ".src = game.getAttribute('box" + i + j +
          "srcPersistAttr')"); // join with previous line
      if (game.getAttribute("grid" + i + j + "PersistAttr"))
        grid[i][j] = game.getAttribute("grid" + i + j + "PersistAttr");

Notice that we have to check for the existence of the attributes before we assign them to box properties. Had we not checked it, the box properties would have been assigned NULL values.

It's important to understand that we could not have persisted an individual IMG element's gif file. The reason is that if we assign the gif file upon loading of the IMG element (as opposed to the BODY element), a load event would be triggered, causing the script to go into an infinite loop.

Created: August 28, 1998
Revised: August 28, 1998