Free Web tutorials covering HTML, CSS, JavaScript, and DHTML from beginner to advanced. Free downloads and developer resources. Personalized help via email, form, and chat.

free, web, tutorials, HTML, html, CSS, css, stylesheet, cascading stylesheet, Javascript, javascript, JavaScript, DHTML, dhtml, beginner, advanced, web development, web page, web site, free web tutorial, free HTML tutorial, free CSS tutorial, free css tutorial, free cascading stylesheet tutorial, free stylesheet tutorial, free javascript tutorial, free DHTML tutorial, free HTML class, free CSS class, free stylesheet class, free cascading stylesheet class, free javascript class, free DHTML class">

Free Web tutorials covering HTML, CSS, JavaScript, and DHTML from beginner to advanced. Free downloads and developer resources. Personalized help via email, form, and chat. free, web, tutorials, HTML, html, CSS, css, stylesheet, cascading stylesheet, Javascript, javascript, JavaScript, DHTML, dhtml, beginner, advanced, web development, web page, web site, free web tutorial, free HTML tutorial, free CSS tutorial, free css tutorial, free cascading stylesheet tutorial, free stylesheet tutorial, free javascript tutorial, free DHTML tutorial, free HTML class, free CSS class, free stylesheet class, free cascading stylesheet class, free javascript class, free DHTML class

<Code_Punk>'s

Advanced JavaScript
Scrolling Detection

Code Tutorials



Site Development



Downloads



Help!!



Home

Explanation & Uses

This tutorial will show you how to detect how far down or across a page a viewer has scrolled. This can be handy in a variety of situations.

The first time I coded scrolling detection was for a large image map. I had a large image map that had to be scrolled both vertically and horizontally. The links in the image opened pages in the same window. I needed some way to reset the map back to the viewer's previous position when they returned to the image map.

I used the position scrolled to before the image map unloaded (onUnload) and put a cookie on the viewer's machine to store scrollbar positions. When they hit the "Back" button to return to the image map, I read the cookie and automatically scrolled to the last position they were at in the image map (scrollTo()).

I recently coded scrolling detection for someone wanting a <div> box to pop up when a page had been scrolled so far down. The box was to be a review of important parts of the previous section of content. It disappeared as scrolling continued.

This tutorial will present the fundamentals of scrolling detection with some simpler effects than the ones above. From there you can do about anything you want. Here is an example of the page we'll be coding in this tutorial. It changes background color as the viewer scrolls down it.

There is one major problem in detecting scrolling. There is no "onScroll" event (as of this writing). We'll have to make one. To help us detect when the viewer scrolls our pages, we have two powerful tools. We can detect the pixel value of the scrollbar's position and we can "poll" or test for this value at frequent (millisecond) intervals.

The Properties

Both browsers store the current position of both the vertical and horizontal scrollbars in JavaScript properties. We can access these properties to retrieve the pixel values and determine where our viewer's have scrolled to on our pages.

Internet Explorer stores the value of the vertical scrollbar in a property called "document.body.scrollTop". This represents the number of pixels the viewer has scrolled down from the top of the page.

Internet Explorer stores the value of the horizontal scrollbar in "document.body.scrollLeft". This represents the number of pixels from the left of the page that the viewer has scrolled. If one or the other scrollbars doesn't exist for a particular page, the returned value is 0 (the number zero).

Netscape stores the vertical scrollbar data in a property referred to as "window.pageYOffset". This is the same pixel value as in IE's "scrollTop", just a different JavaScript reference. Netscape uses "window.pageXOffset" to find the position of the horizontal scrollbar. Pay particular attention to the capitalization of the Netscape offsets. Netscape, too, returns a 0 for a scrollbar that does not exist on a particular page.

A Simple Example

Now that we know how to access the pixel values of the scrollbars in both browsers, let's make a page with links on it that will tell us how far down we've scrolled. Here's an example.

First, make a page with links leading to the JavaScript function that will display the alert box. Copy and paste helps here. Put lots of <br>s between the links so they'll be plenty of scrolling space between them. Here's the link I coded in the example:

<a href="javascript:scrollingDetector()">
Click To Check Scrolling Position</a>

I also centered the links with <div align="center"> and used a lot of <br>s in between the links.

Now lets code the function "scrollingDetector()" between the <script> tags in our <head> or external JavaScript:

function scrollingDetector(){

alert("You are at " + document.body.scrollTop + " pixels.");
}

The code above works in Internet Explorer only. We'll code for both IE and Netscape next. Notice that we just added "document.body.scrollTop" where we wanted the number of pixels displayed. That's all there is to it.

To get this to work in both browsers, we need to employ a "browser detection" scheme. I'll be using the browsers "navigator.appName" to see which browser the viewer is using:

function scrollingDetector(){

if (navigator.appName == "Microsoft Internet Explorer")
{alert("You're at " + document.body.scrollTop + " pixels.");}

else{alert("You're at " + window.pageYOffset + " pixels.");}

What we've done here is to pick out Internet Explorer and direct that browser to the alert box displaying IE's "document.body.scrollTop" value. All other browsers, including Netscape and Opera, will display the value of "window.pageYOffset". Now our page will work with all of the major browsers.

Using setInterval()

The "setInterval()" method of the "window" object is an extremely handy one to learn. It's a distant relative of setTimeout(). The setInterval() method runs and repeats a function at a set interval, or frequency.

The syntax is similar to setTimeout()'s. Here's an example:

setInterval("scrollingDetector()", 250);

You begin coding the method by typing in "setInterval" and making a set of parentheses. Pay attention to the capital "I". Next put in the name of the function you want to run inside the parentheses surrounded by double quotes. Follow this with a comma and the number of milliseconds that setInterval should wait before repeating the specified function.

The above example would run the function "scrollingDetector()" every quarter-second (250 milliseconds). Each time it runs, scrollingDetector() could be coded to return the current scrollbar values. When run together, we can now determine if and how far a viewer has scrolled.

The big difference between setInterval() and setTimeout() is that setInterval keeps repeating the function at a specified interval. The setTimeout() method runs a function only once after a specified interval.

Checking for a viewer action like this is called "polling". We're polling for viewer scrolling. As a matter of fact, all of the events in JavaScript work because the browser is constantly polling for them at a frequent interval. Fortunately, we don't have to go through all of the above for regular JavaScript events.

Let's use setInterval() in a simple example like this one.

Start by making a page with a enough content on it so it can be scrolled over a fairly broad range. We want the "polling" to start automatically as soon as the page loads, so lets use an onLoad event coded in the <body> tag.

We'll need two functions. The first will hold the "setInterval()" method that determines what other function will be run and how often. The second function will return the actual scrollbar values we need to work with.

Here's the onLoad event in the <body> tag:

<body onLoad="startScrollingDetector()">

The "startScrollingDetector()" isn't the function that actually tells us where the scrollbars are, it's the function that sets the interval. It's coded between <script> tags:

function startScrollingDetector(){
setInterval("scrollingDetector()", 5000);
}

Make note that there are two functions here: startScrollingDetector() and scrollingDetector(). We've just coded the first function. All this function does is set an interval using setInterval(). This setInterval() tells the browser to run the second function, scrollingDetector(), every five seconds (5000 milliseconds). We haven't coded the scrollingDetector() function yet. Here it is:

function scrollingDetector(){
if (navigator.appName == "Microsoft Internet Explorer")
{alert ("You're at " + document.body.scrollTop + " pixels.");}

else{alert ("You're at " + window.pageYOffset + " pixels.");}
}

You should be able to recognize the above. It's the same code we used in our previous example. Now, however, it is automatically run by the startScrollingDetector() function every five seconds instead of having to click links.

Using Scrolling Ranges

Now we have the tools needed to make our final sample page that changes background color as the viewer scrolls down the page. Start out by making a page with plenty of content so the page will scroll. Make sure the background is visible so you can see the effect.

What we need to do is to poll for scrolling. When the viewer enters a particular "range" of pixel values as they scroll down the page, we want to change the background. We want to begin scrolling as soon as the page loads, so code an onLoad event calling a function that uses setInterval() just like we did in our previous example.

I'm calling my main function "poll()" and the setInterval() function "startPolling()". Here's the startPolling() function.

function startPolling(){
setInterval("poll()", 500);}

This will run the function poll() every half-second (500 milliseconds).

Now lets code the poll() function. I'll be using two major sections of code in this function. One to determine which browser is being used and where the vertical scrollbar is , and another to determine which range the scrollbar is currently in and what background color to assign.

Now we need to determine the ranges and background colors to use. I began the effect when the viewer scrolled down 50 pixels and made each range 200 pixels. So the background changes with every 200 pixels of scrolling after the first 50 pixels. You can use any colors. I used hex values to represent the colors.

//declaring global variables

var position = 0;
var color = "#ffffff";

function poll(){

//browser and scrollbar position detection

if (navigator.appName == "Microsoft Internet Explorer")
{position = document.body.scrollTop;}
else {position = window.pageYOffset;}

//determining range

if (position > 50 && position < 250){color = "#ff0000";}

if (position > 250 && position < 450){color = "#00ff00";}

if (position > 450 && position < 650){color = "#0000ff";}

if (position > 650 && position < 850){color = "#ffff00";}

if (position > 850 && position < 1050){color = "#c0c0c0";}

if (position > 1050 || position < 50){color = "#ffffff"}

//displaying the background color

document.bgColor = color;
return true;
}

Quite a bit to talk about here. At the top of the code, notice that I've declared two variables. These variables are used by more than one function, so they need to be declared before any functions run. This means they need to be declared and set to defaults outside any functions, usually right after the opening <script> tag.

Variables declared outside of any function are called "global variables". They can be used globally by any function. Variables declared inside a function are called "local". They are used only in the particular function in which they are declared.

Anytime you need to declare variables either inside or outside functions, it's best to group them together at the top of the code. This makes your code easier for someone else to understand.

Next, notice how I managed the browser detection. I knew I was going to be using the scrollbar position in several IF statements, so I decided to get the scrollbar positions for either browser and put it in a variable called "position".

The variable "position" will store the current vertical scrollbar position for both browsers each time the poll() function is run by the setInterval() -- every 500 milliseconds.

The next series of IF statements checks to see what range the scrollbar is in. I've made my ranges 200 pixels long beginning at 50 pixels. I used two ampersands (&&) to test for two condidtions - a top and bottom for each range. You can use "&&" to add as many conditions as you'd like to an IF statement. All of the conditions would have to be true before the IF statements would be run.

Note that I didn't use an ELSE statement. If I had, the program would have jumped to it from the first IF before the other IFs had been analyzed. Instead, I used a final IF statement to set defaults -- If the range was less than the first 50 pixels or higher than 1050 pixels down, a default white background will be displayed.

Now the function has all it needs to display the proper color. I used "document.bgColor" to change the background color.

Now when the page loads, poll() will run every half second and return the number of pixels the viewer has scrolled down from the top of the page. This value will be analyzed by IF statements to determine a value for "color". The variable "color" will be used as a value for the "document.bgColor" property to change the background color.

You may have to go over the code a few times before you get the hang of what's going on. Take your time. You might even find a more efficient way to code this effect. Hint: Loop through ranges using an array and FOR statement.

Flicker

If you view this page with an older version browser or slower computer, you may notice the browser screen flicker. This is caused by the frequency of the polling in setInterval(). You can increase the interval (slow it down) to reduce flicker. If you set your interval low enough, you might get even fast machines to flicker.

It's important to keep this in mind when determining setInterval()'s frequency. You should go for the highest value that will reliably get the job done. The interval value should be low enough so that viewer actions are not missed, or ignored. The interval should be high enough to prevent (or, at least reduce) flicker.

Using clearInterval()

In our examples, we kept polling for scrollbar position every half second as long as the page was loaded. You can stop, or "clear", the setInterval() method by using "clearInterval(name)".

To use clearInterval(), we must first "name" our setInterval(). That just means we set a name equal to it. This name is not a variable and should not be preceded by "var". You can use whatever name you want, but avoid JavaScript reserved words. This is just like when you name a pop up window.:

my_polling_prog = setInterval("my_function()", 500);

Now that the setInterval() is named -- "my_polling_prog" in this case -- we can close it like this:

closeInterval(my_polling_prog);

The name is not put in quotes because it is an object name and not a string. This will stop the polling process begun by setInterval(). You can use this in any function triggered by any event you'd like.

Summary & Exercises

You can make your own custom "events" by polling for a change in any JavaScript property. We've been using scrollbar positions.

IE stores the current vertical scrollbar position in a property called "document.body.scrollTop". The horizontal scrollbar position is in "document.body.scrollLeft". This is a pixel value.

Netscape stores the same values in "window.pageYOffset" (for the vertical scrollbar) and "window.pageXOffset" (for the horizontal scrollbar). If a scrollbar doesn't exist in a window, both browsers return a 0 (zero) for its position's value.

To continually poll for a property change, like scrollbar positions, we use the "window" object's "setInterval()" method. This method contains a function to run and repeat, and the frequency of repetition in milliseconds: setInterval("poll()",500).

Using a function employing setInterval() with a second function to run repeatedly can detect changes in properties and act much like a regular JavaScript event.

When using several IF statements for analysis, do not use and ELSE statement. The ELSE statement will be activated if the first IF statement is false. (It usually will be.) The other IFs will be ignored. This is rarely a desired effect. Use a series of IFs with one of the IFs setting default conditions.

It's important to note that you can use a form of IF/ELSE statements where every IF has an ELSE and the ELSEs contain nested IFs to cope with the problem of multiple IF analysis. This may be formal, proper coding, but it's a pain in the neck to keep up with. Try the method used on this page first (without ELSEs). I've yet to see it fail where nested IF/ELSEs succeed.

Make the last example from scratch at least three times. Think of other effects, like changing fgColor. Play around with different intervals, pixel ranges, and analysis schemes.

Make a giant image rollover using scrollbar position to control which image is displayed. The images used must be big enough to require scrolling.



To Next Advanced JavaScript Lesson

Back To Advanced JavaScript Index