04.11.2015 Views

javascript

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 9: Client Detection<br />

230<br />

For example, the DOM method document.getElementById() didn ’ t exist in Internet Explorer (IE)<br />

prior to version 5.0. This method simply didn ’ t exist in earlier versions, although the same functionality<br />

could be achieved using the nonstandard document.all property. This led to a capability detection fork<br />

such as the following:<br />

function getElement(id){<br />

if (document.getElementById){<br />

return document.getElementById(id);<br />

} else if (document.all){<br />

return document.all[id];<br />

} else {<br />

throw new Error(“No way to retrieve element!”);<br />

}<br />

}<br />

The purpose of the getElement() function is to return an element with the given ID. Since<br />

document.getElementById() is the standard way of achieving this, it is tested for first. If the function<br />

exists (it isn ’ t undefined), then it is used. Otherwise, a check is done to determine if document.all is<br />

available, and if so, that is used. If neither method is available (which is highly unlikely), an error is<br />

thrown to indicate that the function won ’ t work.<br />

There are two important concepts to understand in capability detection. As just mentioned, the most<br />

common way to achieve the result should be tested for first. In the previous example, this meant testing<br />

for document.getElementById() before document.all . Testing for the most common solution<br />

ensures optimal code execution by avoiding multiple - condition testing in the common case.<br />

The second important concept is that you must test for exactly what you want to use. Just because one<br />

capability exists doesn ’ t necessarily mean another exists. Consider the following example:<br />

function getWindowWidth(){<br />

if (document.all){ //assumes IE<br />

return document.documentElement.clientWidth; //INCORRECT USAGE!!!<br />

} else {<br />

return window.innerWidth;<br />

}<br />

}<br />

This example shows an incorrect usage of capability detection. The getWindowWidth() function<br />

first checks to see if document.all exists. It does, so the function then returns document<br />

.documentElement.clientWidth . As discussed in Chapter 8 , IE does not support the window.<br />

innerWidth property. The problem in this code is that a test for document.all does not necessarily<br />

indicate that the browser is IE. It could, in fact, be Opera, which supports document.all as well as<br />

window.innerWidth .<br />

Detecting a particular capability or set of capabilities does not necessarily indicate the browser in use.<br />

The following “ browser detection ” code, or something similar, can be found on numerous web sites and<br />

is an example of improper capability detection:<br />

//AVOID! Not specific enough<br />

var isFirefox = !!(navigator.vendor & & navigator.vendorSub);<br />

//AVOID! Makes too many assumptions<br />

var isIE = !!(document.all & & document.uniqueID);

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!