Section 12.2. Cross-Browser Component


12.2. Cross-Browser Component

Agnostic, Common, Component, CrossBrowser, Independent, Portable

Figure 12-4. Cross-Browser Component


12.2.1. Developer Story

Dave has developed a cross-browser sprite engine, allowing users to easily drag a sprite around the screen. The library provides a browser-independent interface, taking into account browser incompatibilities regarding detection of mouse position and positioning of icons. When a new drag-and-drop requirement comes along, programmers can code to Dave's library in blissful ignorance of the underlying browser incompatibilities.

12.2.2. Problem

How can you manage cross-browser incompatibilities?

12.2.3. Forces

  • A major selling point of Ajax is portabilitythe ability to run an application on any platform with a modern browser.

  • There are numerous browsers on the market, and while IE still dominates, the market is becoming increasingly fragmented. IE currently has around 85-90 percent share on average web sites, but within certain user groups, Mozilla is actually far more popular. A recent survey of AjaxPatterns.org traffic showed 47.5 percent hits from Firefox, 30.1 percent from IE, and 2.7 percent from Safari.

  • Browsers vary from each other in subtle and not-so-subtle ways. Sometimes, a browser simply doesn't support certain functionality. Other times, two browsers offer the same functionality, but it must be accessed in different ways. While the W3C (http://www.w3c.org) establishes standards for browsers, not all are followed.

  • When creating a web program, you want to focus on business and application logic, without being distracted by idiosyncrasies of underlying browsers. Cross-browser compatibility is a cross-cutting concern, best dealt with as a separate task at a separate time.

12.2.4. Solution

Create Cross-Browser Components, allowing programmers to reuse them without regard for browser idiosyncrasies. A Cross-Browser Component abstracts away from underlying browser issues, offering a single API that can be used on any supported browser.

Following are a couple of examples of cross-browser incompatibilities. For simplicity, only the two most popular browsers are discussed: IE and Firefox. Other browsers are also important, and not surprisingly, introduce further incompatibility issues. The following are two examples:


XMLHttpRequest

XMLHttpRequest, a critical Ajax component, is constructed in a browser-specific way, as established in XMLHttpRequest Call (Chapter 6). Most browsers include a specific XMLHttpRequest class, but with IE prior to version 7, it's created as an ActiveX component instead. Furthermore, there are some subtle behavior differences. For example, XMLHttpRequest on Opera lagged behind in terms of support for features like authentication (http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/). An even greater problem is that many older browsers simply don't support this object, even though similar functionality can nonetheless be achieved using IFrames.


opacity

opacityor transparency is becoming important in Ajax applications, as discussed in Popup (Chapter 15) and in One-Second Spotlight (Chapter 16). However, portability is poor (http://www.sitepoint.com/newsletter/viewissue.php?id=3&issue=102&format=html). Recent versions of Firefox, Opera, and Safari allow for the CSS3 opacity style, older versions use their own different names, and IE uses a completely different approach based on a DirectX filter.

Any application using the features above must take into account cross-browser portability. Business and application logic is complex enough, without tangling it further with if-then portability statements. A better solution, and a common approach in the general area of portability, is to isolate cross-browser concerns.

Some browsers are available in multiple operating systemsFirefox, for example, runs in MS-Windows, Apple, Linux, and many other operating systems. It would be nice to assume a given browser was identical across all operating systems, but that's not the case. Some aspects of browsers rely on OS-specific features, which is where further incompatibilities arise. For example, IE's drag-and-drop capability not only depends on which version of IE is being used, but also on whether it's running on Apple or MS-Windows.

As a simple example, many libraries exist to make XMLHttpRequest calls portable. These libraries are examples of Cross-Browser Components, because the user doesn't have to worry about the browser being used. Most of these libraries internally use another form of Cross-Browser Componenta factory function that retrieves a suitable XMLHttpRequest object.

ajaxCaller (http://ajaxify.com/run/testAjaxCaller/), for example, contains the following factory function:

   createXMLHttpRequest: function( ) {     try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}     try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}     try { return new XMLHttpRequest( ); } catch(e) {}     alert("XMLHttpRequest not supported");     return null;   } 

The function allows any code to create a new XMLHttpRequest object without worrying about browser specifics. The returned object is a Cross-Browser Component.

Note that this pattern applies as much to server-side code as to browser-side JavaScript. Whatever HTML comes from the server also needs to be portable. For that reason, you can also create server-side components that will generate portable HTML. So if you create custom JSP tags for your project, the JSP coder should be able to use them without having to make any browser-specific checks.

12.2.5. Decisions

12.2.5.1. What browser-specific criteria is used to create the Cross-Browser Component?

What criteria do you use to decide on a creation strategy? There are, broadly speaking, two approaches:


Version-dependent

Behavior is based on the browser version.


Feature-dependent

Behavior is based on checking for the existence of specific featuresspecifically whether a property or method exists.

The XMLHttpRequest example in the earlier "Solution" is an example of feature-driven behavior. Before trying to create a new window.XMLHttpRequest, we check if window.XMLHttpRequest exists. An equivalent version-dependent check would do something like this:

   /* Version-Dependent Check (Unadvisable!!!) */   return determineIfCurrentBrowserIsIE( ) ?     new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest( ); 

In the above example, a function determines if the current browser is IE. Based on that knowledge, the right mechanism can be used to create an XMLHttpRequest object. How might the version be determined? There are a few ways. First, the navigator object reports directly on this information. Useful properties include (http://www.javascriptkit.com/jsref/navigator.shtml):


navigator.appName

Browser name; e.g. "Netscape"


navigator.appVersion

Browser version; e.g., "5.0 (X11; en-US)"


navigator.UserAgent

Detailed browser and platform details; e.g., "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.9) Gecko/20050711 Firefox/1.0.5"

Ironically, the navigator object's behavior is itself somewhat inconsistent across versions, so you need to handle strings like the userAgent differently. If you go this route, consider a browser detection library like TechPatterns' JavaScript Browser & OS Detection (http://techpatterns.com/downloads/javascript_browser_detection.php) or Webreference's JavaScript Browser Sniffer (http://webreference.com/tools/browser/javascript.html). Portability aside, the problem with direct interrogation is that the browser sometimes tells fibsOpera, for example, lets users manually choose which browser to self-identify as, because some sites refuse to support browsers reporting as Opera.

An alternative way to detect browser version is to rely on a distinctive feature. For example, many scripts use document.all as a simple check for Internet Explorer (http://weblogs.asp.net/jgalloway/archive/2005/08/07/421798.aspx):

   isIE=document.all; 

Version-dependent behavior is feasible, quite common, and often recommended as the appropriate solution. One benefit over feature-dependent behavior is that you have only one or two variables to deal with; with feature-dependent behavior, you have to consider many combinationswhat if the browser supports X but not Y?

However, there do remain some fundamental problems with any feature-dependent behavior. First, it's cumbersome to track all the browser versions that support a particular feature. In many cases, you risk ruling out other browsers that may well support the feature. Also, version checks are often used in a binary way: either your browser's supported and you can run the app, or it's not supported and you're out of luck. But if you focus on specific features, you can support progressive degradation: have a basic application that works for all browsers, with certain additional features available only to those browsers that support them.

12.2.5.2. What if a feature isn't supported by the current browser?

Sometimes, a browser simply doesn't support a feature. What does a cross-browser API do when asked for functionality the browser doesn't provide? There are a couple of options:


Do nothing

Throw an exception or return null to indicate the object couldn't be created.


Provide a custom version

The browser may not support an object natively, but you might be able to create a custom version from other supported objects.

12.2.6. Real-World Examples

This section contains one example that showcases a particularly interesting type of cross-browser compatibility. For more examples of Cross-Browser Components, refer to Appendix A. Many of the JavaScript libraries mentioned there, like Dojo and Scriptaculous, aim to provide components that work on all major browsers.

12.2.6.1. HTMLHttpRequest library

Angus Turnbull's HTMLHttpRequest (http://www.twinhelix.com/javascript/htmlhttprequest/) is a cross-browser library for Web Remoting (Chapter 6). Unlike many of the recent Ajax libraries, it's able to gracefully degrade to IFrame usage when executed on older browsers. The API's still the same, so a programmer can access web remoting in the same way, regardless of the browser in question.

12.2.7. Code Example: HTMLHttpRequest Library

HTMLHttpRequest (http://www.twinhelix.com/javascript/htmlhttprequest/) is a cross-browser remoting component. It works by wrapping around a real, concrete remoting objecteither an XMLHttpRequest object or an IFrame, only one of which will be set. The construction code below makes extensive use of feature-dependent behavior to decide, at each stage, whether to proceed with a particular strategy. There is also some use of feature-dependent behavior to ensure that Opera and IE5 don't follow a particular path.

   function HTMLHttpRequest(myName,callback){     this.myName=myName;     this.callback=callback;     this.xmlhttp=null;     this.iframe=null;     ...     if(window.XMLHttpRequest){       xmlhttp=new XMLHttpRequest( );       if(xmlhttp.overrideMimeType)         xmlhttp.overrideMimeType('text/xml')     }     if(!xmlhttp) {      if(   document.createElement && document.documentElement           && (window.opera||navigator.userAgent.indexOf('MSIE 5.0')==-1)) {           ...       } else if (document.body && document.body.insertAdjacentHTML) {           ...       }       ...     }     return this;   } 

12.2.8. Related Patterns

12.2.8.1. Server-Side Code Generation

Server-Side Code Generation (see earlier) is often a convenient way to generate Cross-Browser Components, allowing you to perform all the abstraction logic server side.

12.2.8.2. On-Demand JavaScript

If you design carefully, you can separate out the implementations for each platform. Use the Lazy Loading technique of On-Demand JavaScript (Chapter 6) to ensure that only code required for the user's own platform is downloaded.

12.2.9. Metaphor

Using a Cross-Browser Component is like working with a certified professional. The professional may have gained their certification in different ways and might offer different services, but there remains a basic set of services that you can expect to be carried out adequately.

12.2.10. Want to Know More?

  • Good discussion on cross-browser issues and specifically enhancing IE applications to support Mozilla by Doron Rosenberg (http://www-128.ibm.com/developerworks/web/library/wa-ie2mozgd/)

  • Quirksmode, by Peter-Paul Koch, is a web site providing comprehensive compatibility resources (http://quirksmode.com)




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net