fluidmind
Star God: Fu Star God: Lu Star God: Shou

Class Action: Assigning JavaScript Events to CSS Classes

I wrote this little tutorial back in 2005 as part of a series of training sessions for the developers who worked under me.

CSS classes are perfect for applying distinct visual styles to HTML elements. Unlike printed materials, however, web pages are not only about looks—action plays an equal role. With a little JavaScript you can use CSS classes to add action as well as visual style to your pages, while eliminating all those cumbersome 'onclick' and 'onmouseover' attributes that clutter your markup.

By now anyone interested in Web Standards has grown accustomed to including at least one link tag in the head of every page to apply a common stylesheets file throughout the site. You should also use a script tag, such as the following, to include a common set of JavaScript functions.

<script type="text/javascript"
    src="/lib/includes/javascript_global.js"></script>

This tag, placed in the head section of every page on your site, will allow you to control the actions on every page from a single JavaScript file, just as you control the look of every page from a single stylesheets file.

In this example we'll instruct the browser to open a new window for all links assigned the "Offsite" class. Thus the class will be used to both apply a unique look to offsite links and a unique action. Since JavaScript allows you to assign events dynamically, all you have to do is loop through all of the links on a page, check for the class to which you want to assign an event, and set it's event handler (onclick, onmouseover, etc.) to execute a function for the action.

The site-wide JavaScript file should include the following:

function offsitePopup(url) {
    var offsitePopup = window.open(url, 'offSiteWindow',
         'width=750,height=500,scrollbars=yes,resizable=yes,menubar=yes,toolbar=yes,location=yes');
    if (typeof offsitePopup == 'object') {
        offsitePopup.focus();
    }
    return false;
}


function globalOnLoad() {
    // Assign link events
    for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].className.match('Offsite')) {
            document.links[i].onclick =
                function() { offsitePopup(this.href); return false; }
        }
    }
    // Run page onLoad function, if it exists
    if (typeof onLoad != 'undefined') {
        onLoad();
    }
}

// Every page should execute the global onload function
window.onload = globalOnLoad;

The first function produces the popup window for the offsite link. It includes all of the standard window components (toolbar, location, scrollbars, etc.) and sets a reasonable size (adjust to taste). If the window already exists (from a previous offsite link), it brings that window to the front with a call to its focus method.

The second function contains anything that you want to occur whenever a page is loaded on your site. In this case we simply apply an "onclick" event to every link that has the "Offsite" class applied to it to make it open its href with the offsitePopup function. It then checks to see if an onLoad function has been defined on that page, so that each page can have it's own actions to occur when it loads.

The last line assigns the window's onload event to execute the globalOnLoad function. This is the same as putting onload='globalOnLoad();' in the body tag of every page.

Compare the following two links, the first done the old way, the second using the technique describd above:

<a href="JavaScript: ;" title="Web Standards Project"
    onclick="offsitePopup('http://webstandards.org');"
    class="Offsite">

<a href="http://webstandards.org"
    title="Web Standards Project" class="Offsite">

The latter is much cleaner and easier for content editors (who typically know little about HTML and less about JavaScript) to remember and type. It has other advantages as well: when the user mouses over the link it will show the destination in the status bar, and it will work as a standard link if the user's browser doesn't support JavaScript or CSS.