March 14, 2011, 11:38 p.m.
posted by idm
Object Detection, Encapsulation, and Cross-Browser Objects
With the release of CSS and Netscape's Navigator 4.x, as well as Microsoft's Internet Explorer 4.x, web-page developers could finally create sophisticated page effects such as animated page contents, collapsing menus, and in-page notifications. The only problem was that not all of the browsers used the same object model when providing this capability.
if (document.layers) ...
Luckily, all modern browsers support a fairly consistent model. All support the document.getElementById, which is critical for accessing specific elements. All support the style property (covered in the next chapter), which allows you to change the CSS style properties of an element.
An element's transparency is determined by the percentage of its opacity. Microsoft was the first to provide a way to change an element's opacity dynamically, through a proprietary filter called the alpha filter. Later, the Mozilla group created a variation of the filter, called the moz-opacity. At about the same time, the KHTML effort (represented by the Safari browser and Konquerer on Linux) derived a property called khtml-opacity. With the release of CSS 3.0, a universal property was defined for opacity, simply named opacity.
The Mozilla line of browsers has moved to the new CSS3 standard, as has Safari. Oddly enough, Microsoft has decided not to support this property and still persists in using the alpha filter, even with the new IE 7. Object detection is necessary, then, to create an effect that works with IE as well as the other browsers that support the CSS3 opacity property.
In Figure, object detection is used to determine which approach to usethe alpha filter or setting the CSS opacity. The target is an image embedded in the page. Its opacity is decreased 10 percent each time the page is clicked. Because the Microsoft alpha filter uses a percentage rather than a digital value, the variable used to hold the current opacity is multiplied by 100 when used with IE.
Using object detection to determine how to adjust the opacity style
In Mozilla, Navigator, Camino, Firefox, Safari, and IE, the image loses opacity with each click, fading away until it's completely transparent. With Opera, which doesn't support opacity, the message is given instead.
Earlier I touched on being able to pass page objects in as a parameter when constructing a new object. The custom object then wraps, or encapsulates, the page object, allowing you to create a set of functionality that hides most of the implementation details. When using a library that has this capability, instead of having to provide all of the JS yourself to change an object's opacity, you can just call a method that changes it for you.
If the underlying implementation changes because of what the browser supports, object encapsulation can hide all of the details for managing this alteration. The applications don't have to change because the underlying implementations have. This makes sophisticated interactive and dynamic applications so much easier to develop. If the browser's implementation is modified, you no longer have to worry about changing multiple applications.
Additionally, you no longer have to run a continuous set of operations that check whether the browser supports this functionality. Your code, or the JS library you're using, checks it up front when the objects are created (usually when the page loads).
In the example, rather than implementing the methods directly in the object, they're implemented outside as separate functions. You can use this approach if you're creating cross-browser objects where all versions of the objects can use some of the methods, such as the getOpacity function (which uses object detection each time it's called), but some methods are specific to types of support (such as the two methods for changing the opacity of the object, set by object detection when the object is created). It also, in my opinion, can make the code a little easier to read as you document each function, and you don't have an excessive amount of nesting.
The use of object detection, custom objects, and encapsulation is not as important today as it was in the past when browser DHTML support varied rather significantly. However, it's still a great way to hide browser differences, not to mention enforce the old "code once, use many times" philosophy of application development.
Note the DOM Level 2 functionality of getElementsByTagName to access all DIV elements, which are then passed to the custom-object constructor to be wrapped in all that cross-browser goodness. For allover page effects, wrapping the page elements in DIV elements and then encapsulating each as a custom object is an approach that simplifies the development of more sophisticated functionality. We'll look at this in more detail in the next two chapters.