Script Comparison - Falling Snow

Accessing The BOM

While the functions that I used in the original version of my falling snow script back in 2004 would still work in the new script, I have discovered ways of making that code much shorter since I originally created functions to provide cross browser support for accessing such things as the size of the viewport and the scroll position of the page within the viewport.

In my original falling snow script I used the following four functions to retrieve the width and height of the viewport and the X and Y distances that the page had been scrolled.

function findLivePageWidth() {
  return window.innerWidth != null ? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : 700;
function findLivePageHeight() {
  returnwindow.innerHeight != null ? window.innerHeight : document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body != null ? document.body.clientHeight : 500;
function posX() {
  return typeof window.pageXOffset != 'undefined' ? window.pageXOffset : document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;
function posY() {
  return typeof window.pageYOffset != 'undefined' ? window.pageYOffset : document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;

The new version of my falling snow script provides the same functionality by defining one object and one function that returns an object.

Since alnmost no one actually resizes their browser while viewing a web page, neither version of the script caters for this happening and so the new version of the script can simply create an object having two properties where the width and height of the viewport are set as the object is created. Also by making use of the fact that JavaScript doesn't even try to evaluate what is on the right of an or condition if what is on the left is true and also returns the original value of the field rather than true or false, we can test for the width and height in each of the three possible places by simply separating the three fielod names with or conditions rather than needing to use a string of if statements (even my original code had simplified the if statements by making use of the ternary operator).

If the page is larger than the viewport then it is quite likely that it will get scrolled so simply determining that the page has scrolled a distance of zero in both the X and Y directions at the start is not going to be sufficient. Both versions of the script therefore need to calculate the scroll position dynamically at regular intervals while the script is running. The new version of my code therefore uses one function that can be called to return an object with the two values we need rather than having two separate functions.

As you can see, the code from the new version of the script is much shorter than the code from the old version that is above. Both of these are still doing exactly the same thing but with the new version making use of objects to identify relationships.

viewport = {
      'width': window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
      'height': window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight};
scrollpos = function() {
    return {
      'x': window.pageXOffset ? window.pageXOffset : document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft,
      'y': window.pageYOffset ? window.pageYOffset : document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop};

The amount of code required to actually use the above code to get the width and height of the viewport doesn't need to change much. Instead of the following two lines:

winWidth = findLivePageWidth() - 75;
winHeight = findLivePageHeight() - 50;

we now have the following:

winWidth = viewport.width - 75;
winHeight = viewport.height - 50;

About the only difference this makes is that the new version is slightly more obvious as to exactly what the values are.

The change to the code for handling the scroll position is also not all that great. In this case we do need to add an extra statement that calls our new function and gives a name to the object that is returned so that the properties can be referenced in place of the separate function calls but again the difference isn't all that great. We replace this code from the old script:

objstyle.left = (posX() + posw[i] + movw[i] * move[i]) + 'px'; = (posY() + posh[i] + movh[i] * (Math.abs(Math.cos(move[i]) + move[i]))) + 'px';

with the following in the new script:

pos = scrollpos();
objstyle.left = (pos.x + posw[i] + movw[i] * move[i]) + 'px'; = (pos.y + posh[i] + movh[i] * (Math.abs(Math.cos(move[i]) + move[i]))) + 'px';

None of these changes were strictly necessary as the functions in the old script for accessing the browser object model but when we are updating our scripts to replace the code we needed for older browsers with the more efficient code that newer browsers will allow us to use, we may as well replace any functions that we are using from our function library with the latest versions that we have.

Next: Defining Variables And Starting The Script.


This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow