How to Choose Standards-Based Techniques

When creating new websites or updating existing ones, we recommend using features defined by stable, widely supported standards instead of relying on proprietary features or features supported by a limited set of browsers.

This article shows how to choose standards-based approaches by showing how the solution to a common problem changes in order to support a standards-based solution, and how good design practices can help you create effective cross-browser solutions that favor standards-based features over proprietary features.

Choosing Standards-Based Techniques

To illustrate, imagine you are creating a webpage to display a greeting when the user clicks a button. To do so, you might create a function to display the greeting and then use the onclick attribute to define that function as an event handler for a button object, as shown in the following code sample.

<!doctype html>
<html>
<head>
  <title>A Simple Greeting</title>
  <script type="text/javascript" src="greeting.js"></script>
</head>
<body>
  <p>Click the button to display a traditional greeting.</p>
  <button onclick="showGreeting()">Show Greeting</button>
</body>
</html>

This example uses the onclick attribute to assign the showGreeting() function as an event handler for the Show Greeting button. (The showGreeting() function itself is declared in the greeting.js library, which is not displayed in the sample.)

You could also separate the definition of the event handler from the presentation of the content, as shown in the following code sample.

<!doctype html>
<html>
<head>
  <title>A Simple Greeting</title>
  <!-- Link to JavaScript libraries containing code -->
  <script type="text/javascript" src="greeting.js"></script>
  <script type="text/javascript" src="register.js"></script>
</head>
<body>
  <p>Click the button to display a traditional greeting.</p>
  <button id="bnGreet">Click me</button>

  <!-- Register event handlers for this page -->
  <script type="text/javascript" >
    registerEvent( "bnGreet", "onclick", showGreeting );
  </script>

</body>
</html>

In this sample, the code for this webpage is stored in separate library files. The registerEvent() function is defined in the register.js library and the showGreeting() function is defined in the greeting.js library. The script block near the bottom of the page defines the event handler for the button object.

The following example shows the register.js library, which uses a commonly used feature to define event handlers for use with Internet Explorer.

// This library (register.js) registers event handlers.
function registerEvent( sTargetID, sEventName, fnHandler ) 
{
  var oTarget = getElementObject( sTargetID );
  if ( oTarget != null ) { 
    if ( oTarget.attachEvent ) { 
      oTarget.attachEvent( sEventName, fnHandler );
    }
  }
}

This example searches the Document Object Model (DOM) for an object with an ID attribute value of "bnGreet " and then uses the attachEvent method to assign the showGreeting() function as the event handler for the onclick event.

As written, this sample works only with Internet Explorer. The attachEvent method is proprietary to Internet Explorer and was added to the browser before relevant standards were clearly defined or widely supported. As a result, the method is not widely supported by other browsers.

However, the Document Object Model (DOM) Level 3 Events standard is supported by many popular browsers, including Internet Explorer 9. This standard defines the addEventListener method as the feature that associates event handlers with DOM objects. In order to create a standards-enabled website, you should use the addEventListener method instead of proprietary features, such as the attachEvent method.

The following code sample shows how to use the addEventListener method to define an event handler for a button.

// This file (register.js) registers event handlers.
function registerEvent( sTargetID, sEventName, fnHandler ) 
{
  var oTarget = getElementObject( sTargetID );
  if ( oTarget != null ) { 
    if ( oTarget.addEventListener ) { 
      oTarget.addEventListener( sEventName, fnHandler, false );
    }
  }
}

This example looks very similar to the earlier attachEvent example and implies that the two methods are similar. However, there are differences between attachEvent and addEventListener, including the following:

  • Each method uses different names for the events. In this example, the attachEvent method uses onclick to define the method whereas the addEventListener method uses click.
  • Each method returns different types of objects. If your code uses the event object passed to an event handler, use care to ensure that the properties and conditions are similar to your previous expectations.
  • Each method interacts with the event model in slightly different ways, especially with regard to keyboard and mouse interaction.

For more information, see DOM Level 3 Events in Internet Explorer 9.

Because the addEventListener method is more widely supported than the attachEvent method, this example works in browsers that support the feature. This makes this sample more useful for modern browsers; however, it does so at the expense of earlier versions of Internet Explorer, which do not support the addEventListener method.

The best practice is to create a fallback strategy that combines both features to create a solution that uses the standards-based technique when supported and falls back to an alternate technique when the preferred feature is not supported by a browser, as shown in the following code sample.

function registerEvent( sTargetID, sEventName, fnHandler ) 
{
   var oTarget = document.getElementById( sTargetID );
   if ( oTarget != null ) 
   {
      if ( oTarget.addEventListener ) {   
         oTarget.addEventListener( sEventName, fnToBeRun, false );
      } else {
        var sOnEvent = "on" + sEventName; 
        if ( oTarget.attachEvent ) 
        {
           oTarget.attachEvent( sOnEvent, fnHandler );
        }
      }
   }
}

For more information, see How to Create Effective Fallback Strategies.

Updating Existing Site Designs

Although it is tempting to think of a website design as being finished at some point, it is likely that you will need to modify the design in order to remain current with modern standards and practices. Web standards evolve over time. New standards can clarify details, add features, promote new ideas, and discourage previous practices. As a result, you may find that you need to update the design of your websites more frequently than you originally anticipated.

When you update the design of a website, you should review the techniques that it uses to see whether new approaches would provide a better experience.

As you do this, consider the following questions:

  • Does the existing design use proprietary or legacy features that can be rewritten using standards-based techniques? For example, earlier versions of Internet Explorer used the attachEvent method to define event handlers. Because Internet Explorer 9 supports the Document Object Model (DOM) Level 3 Events standard, sites should be updated to use the addEventListener method.
  • Are previously supported techniques supported in the current version of the standard? The HTML5 standard marks several HTML elements and attributes as no longer supported. If your current design incorporates these elements or attributes, it should be modified to use more modern approaches, such as new Cascading Style Sheets (CSS) properties.

The following table lists features supported by earlier versions of Windows Internet Explorer that should no longer be used in public websites. If you are updating an existing website, use this table to identify elements of the site that should be changed. When available, standards-based alternatives are suggested.

Legacy Feature Modern Alternative
Vector Markup Language (VML) Scalable Vector Graphics (SVG)
Behaviors, Filters, and HTML+Time Cascading Style Sheets, Level 3 (CSS3) properties, animations, and transformations, such as opacity or linear-gradient().
Dynamic HTML (DHTML) events (attachEvent) Document Object Model (DOM) Level 3 Events (addEventListener)
TextRange/ControlRange Range and Selection
HTML Components (HTC's) Frames and JavaScript
Databinding JavaScript
Dynamic properties and CSS expressions JavaScript alternatives

 

If your websites incorporate these features, you should update these sites to favor standards-based techniques. By doing so, you make it easier for your site to display properly on a wider range of devices and browsers; you also reduce the long-term maintenance needed for your site. For more information, see Internet Explorer 9 Compatibility Cookbook.

In addition, if your website relies on third party JavaScript frameworks, such as jQuery, Dojo, or Modernizr, regularly check for updated versions of the framework, especially after new versions of different browsers are released. This will help users of newer browsers as they use your site. For more information, see the support resources for the framework in question.

Note  The mention of third-party frameworks in this article is illustrative and does not imply recommendation or endorsement of any kind.

 

Summary

When designing a standards-based website, keep the following guidelines in mind:

  • Separate content from presentation whenever possible.
  • Choose standards-based features over proprietary features whenever possible.
  • Use features defined by standards that are widely supported and that are at or are near recommendation status.
  • Review the latest versions of the standards that you rely on to see whether new features are designed to replace older techniques.

In the long run, public websites will function more reliably on a wider variety of browsers if you incorporate features defined in stable, widely supported standards. Choose implementation features carefully to reduce the long-term maintenance of your site.