LA.NET [EN]

Aug 07

Today we’re going to start looking at the JQuery utilities function. The utilities function include several low level helper methods used on JQuery’s core. The good news is that you can also reuse them in your own code. In this post we’re going to take a look at the browser detection helper functions.

Before v1.3, JQuery had several helper objects for getting info about the the browser where your pages were loaded. These objects were called browser, boxModel and styleFloat and they can (still) be accessed through properties on the jquery object ($.browser, $.boxModel and $.styleFloat). With v1.3, these old objects have been deprecated by a new property called support which contains most of the information you had in the previous properties. The advantage of the new support object is that it relies on feature detection instead of browser sniffering.

Here is a quick preview of the properties you’ll find in the support object:

  • boxModel: returns true if the page renders the box model according to the W3C Spec;
  • cssFloat: true if style.cssFloat gives you access to the current CSS float value of an element;
  • hrefNormalized: returns true when the browsed does not normalize href attribute values;
  • htmlSerialize: true when the browser serializes link elements when innerHTML is used;
  • leadingWhitespace: true if the browser preserves leading whitespace when innerHTML is used;
  • noCloneEvent: true if the browser does not clone event handlers when elements are cloned;
  • objectAll: equal to true when getElementsByTagName(“*”) returns all descendants;
  • opacity: true if a browser can properly interpret the opacity style property (IE still relies on alpha filters);
  • scriptEval: true when appendChild or createTextNode executes injected inline scripts;
  • style: returns true only when getAttribute(“style”) returns the inline style specified on an element;
  • tbody: true when browsers allow tables without tbody elements (IE adds the tbody element if you don’t explicitly add one to your HTML).

As you can see, many of these features won’t be used on day to day programming. However, if you’re a plug-in writer or if you intend to write Javascript code that isn’t browser specific, then these methods might help you in a couple of more uncommon scenarios.

I guess that one of things that might have bitten you in the past is the box model. Currently, you can resume the problem to IE being able to render HTML element’s boxes in a standard way or in the quirks mode way (so that it is compatible with previous versions of the browser). With the W3C box model, the width/height defines the width/height of the content while IE’s quirk mode uses the width/height values for defining the total size of the element’s box.

You’ll see no difference on sizes until you start using padding, margins or border widths. When you do that, you’ll notice that the in quirks mode the box will be fixed to the initial size specified through the width and height values,,). If you want to do your own calculations regarding the correct width and height and you need to make it work across several browsers, you can rely on this property for using the correct values.

cssFloat might also be useful when you need to know how to get to the float style of a specific element. Take a look at the next example:

<div>
    <div id="left">left</div>
    <div id="right">right</div>
</div>
<input type="button" id="change" value="Swap" />
<script type="text/javascript">
    $(function() {
        $("#change").click(function(evt) {
            var lft = $("#left")[0];
            var rgt = $("#right")[0];
            if ($.support.cssFloat) {
                lft.style.cssFloat = "right";
                rgt.style.cssFloat = "left";
            }
            else {
                lft.style.styleFloat = "right";
                rgt.style.styleFloat = "left";
            }
        });
    });
</script>

The code shows how you can use the cssFloat property to change the initial floating applied to the element. Notice that I’m doing this only for demonstrating purposes because if this was a real app, I’d really use the css method (it would reduce the number of lines of code needed, which is always a good thing, right?).

Getting the href url is generally done through the href property. However, we’ve already seen in a previous post that most properties get their values from an attribute bag. In most cases, properties can be seen as a shortcut. However, that’s not the case of the href property. When you access the href property, you’ll  always get the complete url. That might not happen if you access the value through the attribute bag. Take a look at the following snippet:

<a href="another.html">Another page</a>
<input type="button" id="show" value="show" />
<script type="text/javascript">
    $(function() {
        $("#show").click(function(evt) {
            var a = $("a")[0];
            alert($.support.hrefNormalized + " - " + a.getAttribute("href"));
        });
    });
</script>

If you run this code in a IE 7 or below, you’ll notice that the browser normalizes the url you’ve passed to the href attribute. That doesn’t happen when you’re using IE8 or any of the other main browsers (I haven’t tested it in safari).

leadingWhitespace still produces different results when you compare IE with the other browsers. What this means is that IE8 still doesn’t respect leading whitespaces when you add content through the innerHTML property. Object cloning is also different in IE. The noCloneEvent property shows us that IE will clone event handlers when you clone an element (in other words, it returns false). That doesn’t happen in most of the other browsers. And the same thing happens for most of the remaining properties presented on the previous list (and that’s why I won’t go into details on all those properties).

At the beginning of this post I said that the great advantage of the support object was that it relied on feature detection. In practice, this means that the code won’t use the traditional navigator object for getting information about the browser. If you look at JQuery’s code, you’ll notice that it creates several dumb elements in order to initialize the properties of the support object. This is great because the results returned from this detection process are way more accurate than the ones you’ll get with the navigator object (just remember that most browsers allow you to set a custom user agent string!). If you’re interested in seeing how it’s done,then you’ll have to scroll until line 3114 of the JQuery’s JS file.

And that’s it for today. Keep tuned for more on JQuery.

1 comment so far

  1. Cat Chen
    9:28 am - 8-8-2009

    I think it should be content box model and border box model, instead of the W3C box model and something non-standard. Since you can use CSS3 box-sizing property to define which box model you choose, they”re both part of the W3C standards now.

    http://www.w3.org/TR/css3-ui/#box-sizing0