December 3, 1999 - Preserving Scrollbar Positions | WebReference

December 3, 1999 - Preserving Scrollbar Positions

Yehuda Shiran December 3, 1999
Preserving Scrollbar Positions
Tips: December 1999

Yehuda Shiran, Ph.D.
Doc JavaScript

If you've written an extremely long or wide page, you may want the page to "remember" the position of the window's scrollbars. We'll use cookies to keep track of the last position:

function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
    ((expires) ? "; expires=" + expires.toGMTString() : "") +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else {
    begin += 2;
  }
  var end = document.cookie.indexOf(";", begin);
  if (end == -1) end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

Before starting, we need some object detection routines:

var db = (document.body) ? 1 : 0;
var scroll = (window.scrollTo) ? 1 : 0;

The first variable holds a true value if document.body exists. In other words, it is 1 (same as true) if the browser is Internet Explorer. On the other hand, the variable scroll holds a true value if the browser supports the scrollTo() method (a fourth-generation browser).

When the page loads, we need to read the relevant cookies to find out if previous scroll values were saved. When the user leaves the page, we must save the current position of the scrollbars. Therefore, we need two event handlers:

<BODY onLoad="loadScroll()" onUnload="saveScroll()">

Take a look at the loadScroll() and saveScroll() functions:

function saveScroll() {
  if (!scroll) return;
  var now = new Date();
  now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
  var x = (db) ? document.body.scrollLeft : pageXOffset;
  var y = (db) ? document.body.scrollTop : pageYOffset;
  setCookie("xy", x + "_" + y, now);
}
function loadScroll() {
  if (!scroll) return;
  var xy = getCookie("xy");
  if (!xy) return;
  var ar = xy.split("_");
  if (ar.length == 2) scrollTo(parseInt(ar[0]), parseInt(ar[1]));
}

As you can see, both functions are immediately terminated if the user isn't running a fourth-generation browser. The offset coordinates in Internet Explorer are stored in document.body.scrollLeft and document.body.scrollTop, while the corresponding Navigator properties are window.pageXOffset and window.pageYOffset. Note that window is the default object, so we don't need to explicitly specify it.

The cookie-handling statements are explained in Creating Message Loops (December 1, 1999). However, bear in mind that you must use a different cookie name for each page on which you are implementing this technique. In our example, the name of the cookie is xy, and its value is a string (e.g., "215_23").

The window.scrollTo() method is supported by both browsers (4 and above). It scrolls the viewing area of the window so that the specified point becomes the top-left corner. Its general syntax is:

window.scrollTo(x, y);

or in short:

scrollTo(x, y);

x is an integer that specifies the horizontal scroll offset, in pixels, where y is an integer that specifies the vertical scroll offset, in pixels. For your reference, here is the entire script (don't forget the event handlers in the <BODY> tag):

<SCRIPT LANGUAGE="JavaScript">
<!--
var db = (document.body) ? 1 : 0;
var scroll = (window.scrollTo) ? 1 : 0;
function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
    ((expires) ? "; expires=" + expires.toGMTString() : "") +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else {
    begin += 2;
  }
  var end = document.cookie.indexOf(";", begin);
  if (end == -1) end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}
function saveScroll() {
  if (!scroll) return;
  var now = new Date();
  now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
  var x = (db) ? document.body.scrollLeft : pageXOffset;
  var y = (db) ? document.body.scrollTop : pageYOffset;
  setCookie("xy", x + "_" + y, now);
}
function loadScroll() {
  if (!scroll) return;
  var xy = getCookie("xy");
  if (!xy) return;
  var ar = xy.split("_");
  if (ar.length == 2) scrollTo(parseInt(ar[0]), parseInt(ar[1]));
}
// -->
</SCRIPT>