<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web 3.0, 6 Bladed Razors, 7 Minute Abs &#187; JavaScript</title>
	<atom:link href="http://www.zachleat.com/web/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zachleat.com/web</link>
	<description></description>
	<lastBuildDate>Mon, 06 Feb 2012 17:09:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Placeholder Title for Article about HTML5 Placeholders</title>
		<link>http://www.zachleat.com/web/placeholder/</link>
		<comments>http://www.zachleat.com/web/placeholder/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 04:52:29 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Compatibility Tests]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1188</guid>
		<description><![CDATA[When I&#8217;m not out fighting crime, I spend my days developing reusable components for the web. One of those reusable components I wrote was an implementation of a placeholder plugin. For the sake of privacy, all component names have been anonymized so I&#8217;ll refer to this home-grown implementation as The Mankini (if for no other [...]]]></description>
			<content:encoded><![CDATA[<p>When I&#8217;m not out fighting crime, I spend my days developing reusable components for the web. One of those reusable components I wrote was an implementation of a placeholder plugin. For the sake of privacy, all component names have been anonymized so I&#8217;ll refer to this home-grown implementation as The Mankini (if for no other reason than to drive some swimwear shopping traffic to my blog).</p>
<p>The Mankini&#8217;s development predated the HTML5 specification but the end result was functionally similar. The difference being that in addition to operating on text inputs and textareas, it also worked with <def title="Line Feed/Carriage Return">LF/CR</def> and selects (injects an option with an empty value).  The HTML5 specification requires that <def title="Line Feed/Carriage Return">LF/CR</def> be stripped from the placeholder value.</p>
<p>One of the most important design considerations our interaction design team specified for The Mankini was that it was not to be used as a replacement for a form label. It was a complement to the form label and nothing more.  The <a href="http://dev.w3.org/html5/spec/Overview.html#the-placeholder-attribute">HTML5 specification came to the same conclusion</a>: <em>&#8220;The placeholder attribute should not be used as an alternative to a label.&#8221;</em>  The reasoning is obvious: if the form field has a non-empty value, you need to be able to easily identify the value&#8217;s semantic meaning.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2012/02/Screen-Shot-2012-02-05-at-12.12.09-AM.png" alt="" title="An example of misused placeholders" width="364" height="115" class="aligncenter size-full wp-image-1189" /><br />
Instead of putting the label text into the placeholder, use the placeholder to supplement the labels with an example e-mail and URL to provide more of a hint to the user for proper formatting.  This example isn&#8217;t a huge usability issue since the three fields&#8217; values would be easily identifiable, but it&#8217;s important to keep in mind.</p>
<h2>Placeholder Testing</h2>
<p>I decided to run a <a href="/test/placeholder.html">few compatibility tests</a> on the placeholder attribute to see where I could reuse the HTML5 placeholder inside of The Mankini (the test results are also available on <a href="https://github.com/zachleat/Compatibility-Tests/blob/master/placeholder.html">GitHub</a>). This yielded a few interesting things about some consistent and inconsistent cross-browser incompatibilities with the specification that I thought were worth sharing.</p>
<ol>
<li>The HTML5 spec states that the placeholder should be visible when <em>&#8220;element&#8217;s value is the empty string and/or the control is not focused.&#8221;</em> The and/or presents the implementor with a decision. Do they keep the placeholder text visible when the field is focused but the value is still empty? Or do I remove the placeholder when focusing into an empty field?<br/><br />
My personal preference is that the text remains until the user starts to type. Safari 5.1, iOS 5, and Chrome 17+ were the only browser implementations to agree with this as of time of writing.</li>
<li>The HTML5 spec has suggested (not required) that placeholders <em>only</em> apply to <code>&lt;input type="text|search|password|tel|url|email|number"&gt;</code> and <code>&lt;textarea&gt;</code>. For some input types such as <code>hidden</code>, <code>radio</code>, or <code>checkbox</code> this limitation makes sense, the placeholder would add nothing to these elements. But for others like <code>datetime</code>, <code>date</code>, <code>month</code>, <code>week</code>, <code>time</code>, <code>datetime-local</code>, <code>color</code>, or <code>file</code> the argument can be made that it would be useful.</li>
<li>There is <a href="https://bugs.webkit.org/show_bug.cgi?id=21286">an open WebKit issue</a> to add placeholder support to contenteditable. Hopefully the specification gets modified and this gets added, as it would have been useful for my <a href="http://www.zachleat.com/web/bigtext-makes-text-big/">BigText Demo Wizard</a> which manually implemented that same feature.</li>
<li><code>&lt;input type="number"&gt;</code> support is broken in Safari and it&#8217;s already been <a href="https://bugs.webkit.org/show_bug.cgi?id=61095">reported and fixed</a>. &#8220;The future is here, just not evenly distributed.&#8221;</li>
</ol>
<p>As a side note, it should be said that both Opera and iOS both have comprehensively badass support of the new HTML5 form element types.</p>
<h2>Overlooked Polyfill Considerations</h2>
<ul>
<li>For those browsers that did implement the placeholder, it was well supported in password fields, showing as plaintext and then converting to masked input when the user started to enter data. This was a nice surprise, but polyfilling that behavior in old Internet Explorers will require additional lifting since dynamically changing the type attribute is not permitted.</li>
<li>Placeholder text should not be included with form submit.</li>
<li>Placeholder text should reinitialize on form reset (note: there is no <code>delegate</code> event for <code>reset</code> in jQuery)</li>
<li>Performance. Is the component required to iterate over all elements and add a class to initialize each one individually? For best performance, use CSS attribute selectors (<code>input[type="text"][placeholder]</code>) for the default style and iterate only to remove the light gray color on form elements with non-empty values. This only requires a className modification for a much smaller set of elements, only the ones with non-empty values. Remember that the browsers we polyfill are often the slowest.<br/><br />
Does the component modify the <code>className</code> property on <code>focus</code> and <code>blur</code>? I found this to be a huge performance issue for the Mankini in IE7 and IE8 on pages with large DOM trees and was a lot faster if the Mankini only modified one element&#8217;s style (think jQuery&#8217;s <code>$(this).css('color', '#000')</code>).</li>
<li>Clear the values on page unload. After page refresh, some browsers will attempt to save unsubmitted form values and re-enter the values when the page reloads (added after reviewing <a href="https://github.com/mathiasbynens/jquery-placeholder">Mathias Bynen&#8217;s jQuery-placeholder</a>).</li>
</ul>
<h2>Bathwater, No Babies</h2>
<p><a href="http://html5please.us/#placeholder">HTML5 Please</a> recommends that we use the new and shiny responsibly and gives the go-ahead to use the placeholder polyfill on our pages. I humbly disagree. This seems to be the same trap we fell into for rounded corners and box shadows. We put extra effort into trying to get our sites to render and behave identically cross-browser, when we should have just let them render in old browsers without rounded corners or box-shadows at all. To test whether or not a polyfill is necessary, I created a super complex decision workflow called <strong>The Polyfill Test</strong>. It consists of 2 steps:</p>
<ol>
<li>Look at your own browser statistics. If the feature is at >50%, continue to Step 2.</li>
<li>Determine if the user be able to complete their task without the feature. If the task is still completable without significant impairment, the polyfill isn&#8217;t necessary.</li>
</ol>
<p>Globally, placeholder support is sitting at 60% and growing. This particular feature has passed the tipping point.  If your audience isn&#8217;t a representative sample of the global web browser statistics (big enterprise intranets with 97% Internet Explorer), your mileage may vary.</p>
<p>If you&#8217;re already using validation on the form fields (client and/or server side) and you&#8217;re correctly using the placeholder to supplement (not replace) the field labels, I would argue that the polyfill isn&#8217;t needed. It&#8217;s an implementation nice-to-have, not a requirement.</p>
<p><em>Update: Added note about Chrome 17+ support for placeholder text remaining on focus per Mathias&#8217; feedback below.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/placeholder/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Deferreds and a Better Geolocation API</title>
		<link>http://www.zachleat.com/web/deferred-geolocation/</link>
		<comments>http://www.zachleat.com/web/deferred-geolocation/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 04:54:04 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1159</guid>
		<description><![CDATA[Warning, this article is intended for Deferred unbelievers to convince them that Deferred objects are both easy and useful. If you&#8217;re already a Deferred object expert, you might want to skip this one. Earlier this year I was given the opportunity to attend the jQuery Conference in San Francisco. I was delighted to go, able [...]]]></description>
			<content:encoded><![CDATA[<p><em style="font-size: 90%">Warning, this article is intended for Deferred unbelievers to convince them that Deferred objects are both easy and useful.  If you&#8217;re already a Deferred object expert, you might want to skip this one.</em></p>
<p>Earlier this year I was given the opportunity to attend the jQuery Conference in San Francisco. I was delighted to go, able to finally meet some of the JavaScript greats I&#8217;d been <del datetime="2011-11-05T22:11:29+00:00">stalking</del> following online for years.</p>
<p>Looking back on the conference, the one presentation that had the <strong>biggest impact on the way that I code</strong> had to have been <a href="https://twitter.com/danheberden">Dan Heberden</a>&#8216;s &#8220;<a href="http://danheberden.com/presentations/deferreds-putting-laziness-to-work/">Deferreds, Putting Laziness to Work.</a>&#8221;  (I would be remiss if I didn&#8217;t also mention inspiration from a <a href="http://speakerdeck.com/u/eliperelman/p/jquery-deferreds-and-promises">recent presentation</a> by <a href="https://twitter.com/eliperelman">Eli Perelman</a> at the <a href="http://www.meetup.com/jquery-omaha/">Omaha jQuery Meetup</a>.)</p>
<p>At first, Deferred objects sound scary.  I can assure you that they&#8217;re actually incredibly easy and incredibly useful. Today we&#8217;ll go through the simple task of <strong>reworking the <a href="http://www.w3.org/TR/geolocation-API/">Geolocation API</a> to use jQuery Deferred objects</strong>.</p>
<p>Here is the standard Geolocation API to retrieve the user&#8217;s current position:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">navigator.geolocation.getCurrentPosition(function(position) {
  // success
}, function(error) {
  // failure
}, {
  // options
  enableHighAccuracy: true
});</pre></div></div>

<p>When the above API is called, a prompt is shown to the user asking if they want to divulge their location information to the domain of the currently active web site.  Typically this prompt is a non-blocking asynchronous operation (although not explicitly defined in the specification).</p>
<p>Let&#8217;s go ahead and change it to use a jQuery Deferred object:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">function getCurrentPositionDeferred(options) {
  var deferred = $.Deferred();
&nbsp;
  navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, options);
&nbsp;
  return deferred.promise();
};</pre></div></div>

<p>Notice that the success callback is replaced by the deferred object&#8217;s resolve method and the error callback is replaced by the reject method.  All of our function arguments are removed from the API. We&#8217;re left with one simple options argument.</p>
<p>This allows us to do things like:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">getCurrentPositionDeferred({
  enableHighAccuracy: true
}).done(function() {
  // success
}).fail(function() {
  // failure
}).always(function() {
  // executes no matter what happens. I've used this to hide loading messages.
});
// You can add an arbitrary number of callbacks using done, fail, or always.</pre></div></div>

<p>We could also use <code>$.when</code> to run code upon completion of two arbitrary and contrived operations like a Geolocation call and an Ajax request. Awesome.</p>
<p>To coordinate between multiple Deferred objects, use $.when:</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">$.when(getCurrentPositionDeferred(), $.ajax(&quot;/someUrl&quot;)).done(function() {
  // both the ajax call and the geolocation call have finished successfully.
});</pre></div></div>

<p>I wonder what other browser native APIs could be better served by using Deferred objects instead of function arguments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/deferred-geolocation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FitText + BigText: A Tale of Two Plugins</title>
		<link>http://www.zachleat.com/web/fittext-and-bigtext/</link>
		<comments>http://www.zachleat.com/web/fittext-and-bigtext/#comments</comments>
		<pubDate>Fri, 13 May 2011 04:40:20 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=1014</guid>
		<description><![CDATA[Earlier this week, @TrentWalton tweeted: We at @paravelinc happily present to you FitText—a jQuery plugin for inflating web type: http://t.co/1NuQg5z Naturally, I wondered how it compared to BigText, a plugin of my own creation to Make Text Big. Trent continued: It&#8217;s in the GitHub readme, but I want to recognize BigText from @zachleat as another [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, <a href="http://twitter.com/trentwalton">@TrentWalton</a> <a href="http://twitter.com/TrentWalton/status/67972022776508416">tweeted</a>:</p>
<blockquote><p>We at <a href="http://twitter.com/paravelinc">@paravelinc</a> happily present to you FitText—a jQuery plugin for inflating web type: <a href="http://t.co/1NuQg5z">http://t.co/1NuQg5z</a></p></blockquote>
<p>Naturally, I wondered how it compared to BigText, a plugin of my own creation to Make Text Big.  Trent <a href="http://twitter.com/TrentWalton/status/67989004427079682">continued</a>:</p>
<blockquote><p>It&#8217;s in the GitHub readme, but I want to recognize BigText from <a href="http://twitter.com/zachleat">@zachleat</a> as another font sizer for non-fluid sites: <a href="http://t.co/dXw607P">http://t.co/dXw607P</a></p></blockquote>
<p>I was delighted to get some attribution from Trent, and even more delighted to see their plugin. It&#8217;s really a great piece of work.  However, his statement that BigText is just for non-fluid sites is not quite accurate. Let&#8217;s dive in.</p>
<p><a href="http://www.zachleat.com/web/bigtext-makes-text-big/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/05/Screen-shot-2011-05-12-at-11.05.26-PM.png" alt="" title="BigText" width="300" height="205" class="size-full wp-image-1052" /></a></p>
<p><a href="http://fittextjs.com/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/05/Screen-shot-2011-05-12-at-11.10.01-PM.png" alt="" title="FitText" width="300" height="199" class="size-full wp-image-1053" /></a></p>
<p>On the surface, BigText and FitText might seem very similar. In fact, they are quite different and approach what might seem to be a similar problem (resizing text to fit a container) in very different ways.</p>
<p>At its simplest, we can boil it down like this: If you&#8217;re crafting a specific design with <strong>copy that is not going to change</strong>, use FitText. If your <strong>text is dynamic</strong> (maybe user generated), use BigText.</p>
<p>Here&#8217;s more detail:</p>
<table>
<thead>
<tr>
<th>&#160;</th>
<th>BigText</th>
<th>FitText</th>
</tr>
</thead>
<tbody>
<tr>
<td>Demos</td>
<td><a href="http://jsfiddle.net/zachleat/anJpE/">BigText Fiddle</a></td>
<td><a href="http://jsfiddle.net/zachleat/ExhDC/">FitText Fiddle</a></td>
</tr>
<tr>
<td>&#160;</td>
<td colspan="2"><em>Try resizing the demo windows above.</em></td>
</tr>
<tr>
<td>Algorithm</td>
<td><strong>Sizes text automatically</strong> from a base up to fit the element width, regardless of initial font size.</td>
<td>Uses the width of the element and a configurable JavaScript argument (the ratio) to <strong>scale text down</strong> to smaller widths. This ratio argument must be set manually.</td>
</tr>
<tr>
<td>Responsive Design</td>
<td colspan="2">Both plugins work with <strong>responsive design techniques</strong>, operating correctly with media queries, fluid designs, and window resizing.</td>
</tr>
<tr>
<td>Speed</td>
<td>Fast</td>
<td>Faster</td>
</tr>
<tr>
<td>Text</td>
<td>Works with user generated text, or any text isn&#8217;t cemented at design time. See the <a href="http://www.zachleat.com/bigtext/demo/">BigText Demo Wizard</a>.</td>
<td>Requires up front configuration to specific text.</td>
</tr>
<tr>
<td>Resize Event</td>
<td>Works with existing debounced resize libraries, if they exist on the page.</td>
<td>Does not use a debounced resize event.</td>
</tr>
<tr>
<td>Unobtrusive</td>
<td>CSS and BigText font-sizes are independent of each other.</td>
<td>FitText uses your CSS font-size as a maximum font size.</td>
</tr>
<tr>
<td>&#160;</td>
<td colspan="2"><em>Don&#8217;t forget to set sane CSS font-size defaults when JavaScript isn&#8217;t available.</em></td>
</tr>
<tr>
<td>Unit Tested</td>
<td>Full Test Suite</td>
<td>-</td>
</tr>
</tbody>
</table>
<p><strong>FitText is very lightweight and fast</strong>, even considering it doesn&#8217;t yet use a debounced resize event. The <a href="https://github.com/davatron5000/FitText.js/blob/master/jquery.fittext.js">FitText algorithm</a> is <strong>quite beautiful</strong>.  A huge well done to <a href="http://paravelinc.com/">Paravel</a>.</p>
<p>FitText relies on the fact that there is a <strong>linear relationship between font-sizes and element widths</strong>.  Once you&#8217;ve established the ratio between the two, it&#8217;s off to the races. In fact, it would probably be technically possible to determine the ratio solely on the initial inner-width of the text and the initial font-size.  I&#8217;ll have to play around with that approach but if it works it would give an amazing speed improvement to BigText.</p>
<div style="text-align: center; font-size: 160%; margin-bottom: 1em"><code>font-size = outer-width / configurable-ratio</code></div>
<p>In a perfect world, BigText and FitText could be combined, to create a <em>mutant auto-text-sizing plugin baby</em> that gives the best of both worlds.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/fittext-and-bigtext/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The JavaScript Testing Challenge Winner</title>
		<link>http://www.zachleat.com/web/javascript-tdd-winner/</link>
		<comments>http://www.zachleat.com/web/javascript-tdd-winner/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 03:58:34 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Contests]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JsTestDriver]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=923</guid>
		<description><![CDATA[Congratulations to Steve Love, who was the first to complete The JavaScript Testing Challenge. He wins a copy of Christian Johansen&#8216;s book, Test-Driven JavaScript Development. If you code for a living, testing will make your life easier. Even though the contest is over, I encourage you to go through the steps and complete the original [...]]]></description>
			<content:encoded><![CDATA[<p>Congratulations to <a href="http://twitter.com/stevelove">Steve Love</a>, who was the first to complete <a href="/web/2010/11/13/javascript-tdd/">The JavaScript Testing Challenge</a>.</p>
<p><a href="http://tddjs.com/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/ttdjs.png" alt="" title="ttdjs" width="300" height="386" class="alignright size-full wp-image-925" /></a>He wins a copy of <a href="http://twitter.com/cjno">Christian Johansen</a>&#8216;s book, <a href="http://tddjs.com/">Test-Driven JavaScript Development</a>.</p>
<p>If you code for a living, testing will make your life easier.  Even though the contest is over, I encourage you to go through the steps and complete the original challenge, if for no other reason than to see how easy it is to get a simple testing environment set up with JsTestDriver.</p>
<p>Stay tuned for more coding challenges!</p>
<div style="clear: both"></div>
<p>Related: <a href="/web/2011/01/09/javascript-tdd-update/">An Update to The JavaScript Testing Challenge</a></p>
<p>Here&#8217;s Steve&#8217;s screencast (using, I assume, a mechanical keyboard?):<br />
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' ></param><param name='flashvars' value='i=170158' ></param><param name='allowFullScreen' value='true' ></param><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=170158' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer' ></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-tdd-winner/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Et tu, X-UA-Compatible?</title>
		<link>http://www.zachleat.com/web/et-tu-x-ua-compatible/</link>
		<comments>http://www.zachleat.com/web/et-tu-x-ua-compatible/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 05:34:14 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[User Agent Sniffing]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=889</guid>
		<description><![CDATA[Or, the story of how I learned that the X-UA-Compatible header/meta tag is NOT the same as the Internet Explorer 8+ Compatibility View button. Please note that the following information may be common knowledge, as this behavior is as described in the pre-requisite Microsoft documentation on the subject. However, I feel this behavior to be [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/jedibfa/5067647765/"><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/juliusceasar.jpg" alt="" title="Julius Ceasar" style="width: 300px" class="alignright size-full wp-image-899" /></a>Or, the story of how I learned that <strong>the X-UA-Compatible header/meta tag is NOT the same as the Internet Explorer 8+ Compatibility View button</strong>.</p>
<p><em>Please note that the following information may be common knowledge, as this behavior is as described in the pre-requisite <a href="http://blogs.msdn.com/b/ie/archive/2010/10/19/testing-sites-with-browser-mode-vs-doc-mode.aspx">Microsoft documentation</a> on the subject. However, I feel this behavior to be unintuitive and requiring more explicit communication.</em></p>
<div style="clear: both"></div>
<p>Library developers live in a much different world from full stack developers.  If you&#8217;re supplying code that will be used by others, you&#8217;re faced with a different set of priorities.  As such, the library I manage provides certain user agent sniffing conveniences, namely classes to replace CSS Hacks (similar to the approach used in HTML Boilerplate to provide ie6 through ie9 classes on the <code>&lt;html&gt;</code> tag) and JavaScript booleans (similar to <a href="http://api.jquery.com/jQuery.browser"><code>jQuery.browser</code></a>).  Much like jQuery, <a href="http://docs.jquery.com/Release:jQuery_1.3#No_More_Browser_Sniffing">these conveniences remain</a> for backwards compatibility.</p>
<p>The purpose of this post is in fact not to convince you whether or not User Agent Sniffing is a <a href="http://infrequently.org/2011/01/cutting-the-interrogation-short/">good tradeoff for performance</a> (even though, in some cases I believe it is), but instead to provide further evidence that using the User Agent alone is an unreliable method to determine the rendering engine of the web browser, and must be complemented with other approaches.  <strong>If you&#8217;re going to sniff, you have to sniff harder.</strong></p>
<h2>X-UA-Compatible Breaks navigator.userAgent</h2>
<p>Microsoft defines two terms to help communicate how new versions of Internet Explorer render a page: Browser Mode and Document Mode.  Browser Modes are determined prior to any request made to the server (and cannot be changed by web developers).  If the user triggers an IE7 Browser Mode using the Compatibility View Button, a new request is made to the server.  Document Modes are determined in the page response.</p>
<h3>Compatibility View Button Flow</h3>
<ol>
<li>User presses the Compatibility View button. This changes the Browser Mode.</li>
<li>Request sent (since the Browser Mode has changed, <strong>the User-Agent is also changed</strong> to MSIE 7.0)</li>
<li>Response from Server</li>
<li>Document Mode determined</li>
</ol>
<h3>X-UA-Compatible Flow</h3>
<ol>
<li>Internet Explorer uses the default Browser Mode (newest available in the browser)</li>
<li>Request sent (Browser Mode determines User-Agent to send, probably MSIE 8.0 or MSIE 9.0)</li>
<li>Response from Server.  Content may include X-UA-Compatible <code>&lt;meta&gt;</code> tag and/or Response HTTP headers such as X-UA-Compatible).</li>
<li>Document Mode determined, using X-UA-Compatible and the DocType</li>
</ol>
<p>If a X-UA-Compatible header is sent back in the Compatibility View flow, it will take precedence but obviously will not change the request User-Agent HTTP header.</p>
<p>It&#8217;s important to note that since the request has already gone before the Document Mode is determined, the Document Mode has no bearing on the request User-Agent HTTP header.  <del datetime="2011-11-05T19:40:06+00:00">While Microsoft probably could have changed <code>navigator.userAgent</code> to be different than the request User-Agent HTTP header, I feel they made the correct decision is keeping the same value.</del>  <code>navigator.userAgent</code> remains the same value as the request User-Agent HTTP header in IE8, but Microsoft changed this behavior in IE9. In IE9, <code>navigator.userAgent</code> represents the document mode, not the request User-Agent header.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2011/02/Screen-shot-2011-02-06-at-1.27.14-PM.png" alt="" title="Screenshot of Microsoft Documentation" width="379" height="139" class="alignright size-full wp-image-896" />The User Agent isn&#8217;t the only thing being determined. The prerequisite Microsoft documentation states that the Browser Mode determines the User Agent, Default Document Mode, and Conditional Comments.  This is not accurate.  <strong>The Document Mode determines which Conditional Comments execute, not the Browser Mode.</strong></p>
<p>Also note that using IE&#8217;s <strong>Conditional Compilation</strong> feature to return the version of JScript will be the same, independent of Document Mode.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">var ie = /*@cc_on @_jscript_version+@*/0;
// Always returns 5.8 in IE8, independent of Document Mode.</pre></div></div>

<p><em>Example Code from <a href="https://github.com/scottjehl/Respond/blob/aedc482328a4cbd9d74c5de178eb2cb974b67af5/respond.src.js#L171">Scott Jehl&#8217;s respond.js</a></em></p>
<h3>Test Pages</h3>
<p>Try the following tests in Internet Explorer 8+ to test for yourself.</p>
<ul>
<li><a href="/test/x-ua-compatible/index.html">Stock Page</a></li>
<li><a href="/test/x-ua-compatible/ie7.html">Setting X-UA-Compatible IE=7 using a Meta Tag</a> (or <a href="/test/x-ua-compatible/emulateie7.html">IE=EmulateIE7</a>)</li>
<li><a href="/test/x-ua-compatible/header-ie7/ie7.html">Setting X-UA-Compatible IE=7 using an HTTP Header</a> (or <a href="/test/x-ua-compatible/header-emulateie7/emulateie7.html">IE=EmulateIE7</a>)</li>
</ul>
<h2>What Does This Mean?</h2>
<p>If you use X-UA-Compatible to change the Document Mode/IE Trident rendering engine, any client side code relying on <code>navigator.userAgent</code> (such as jQuery.browser) or server side code relying on the User-Agent HTTP Header will be incorrect.  Since we can&#8217;t rely on the User Agent, what can we use?  Microsoft does provide a <code>document.documentMode</code> integer we could use, pretty easily.  But, I think there is a better approach.</p>
<p>Consider <a href="https://gist.github.com/527683">a great piece of JavaScript written by James Padosley</a> to find Internet Explorer version numbers using Conditional Comments.  His code seemed to meld perfectly with the above realization that the Document Mode determines Conditional Comment execution.  We can use this to fix <code>jQuery.browser</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Place this script after jQuery, but before any code that uses jQuery.browser
// Modified to only test for IE 6+, since jQuery only supports 6+
(function($)
{
    if(!$.browser.msie) {
        return;
    }
&nbsp;
    var v = 5,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');
&nbsp;
    while (
        div.innerHTML = '&lt;!--[if gt IE ' + (++v) + ']&gt;&lt;i&gt;&lt;/i&gt;&lt;![endif]--&gt;',
        all[0]
    );
&nbsp;
    $.browser.version = v;
})(jQuery);</pre></div></div>

<p>Now, of course, since we&#8217;re creating nodes there is a small performance penalty in using the above script over Regular Expressions and document.documentMode.  I feel this to be worthwhile, given that I&#8217;ve been <a href="/web/2008/10/19/jquery-bug-ie-reports-incorrect-browserversion/">burned by Internet Explorer&#8217;s version number before</a>.  But next time, I reserve the right to choose performance over simplicity.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/et-tu-x-ua-compatible/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>BigText Makes Text Big</title>
		<link>http://www.zachleat.com/web/bigtext-makes-text-big/</link>
		<comments>http://www.zachleat.com/web/bigtext-makes-text-big/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 02:49:35 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Typography]]></category>
		<category><![CDATA[3D Transforms]]></category>
		<category><![CDATA[BigText]]></category>
		<category><![CDATA[contenteditable]]></category>
		<category><![CDATA[Flexbox]]></category>
		<category><![CDATA[font-face]]></category>
		<category><![CDATA[jQuery UI]]></category>
		<category><![CDATA[Throttle]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=838</guid>
		<description><![CDATA[I like shortcuts:]]></description>
			<content:encoded><![CDATA[<p><em style="font-size: 90%">I like shortcuts: <a href="https://github.com/zachleat/BigText"">Fork BigText on Github</a> or <a href="/bigtext/demo/">Check out the BigText Demo Wizard</a></em></p>
<p>It all began with a simple web foray to <a href="http://designingmonsters.com/">Designing Monsters</a>.  Their simple, typographic design was beautiful. But why? Their combination of the beautiful League Gothic font, use of <a href="http://letteringjs.com/">Lettering.JS</a>, and some simple font scaling gave the page a wonderful consistent vertical alignment. Like the Million Dollar Homepage, I wanted to rebuild it &#8212; but I didn&#8217;t want to spend a lot of time manually adjusting font sizes. So I did what any programmer with the jQuery Golden Hammer would do, I turned my problem into a nail.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2011/01/Screen-shot-2011-01-11-at-7.37.54-PM.png" alt="" title="The elusive BIGTEXT plugin exclusively caputured on film" width="287" height="332" class="alignright size-full wp-image-843" /><br />
At it&#8217;s simplest, the BigText jQuery plugin takes a single element and <strong>sizes the text inside of its child <code>&lt;div&gt;</code>s to fit the width of the parent elemen</strong>t.  Gives the text that lovely vertical alignment.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div id=&quot;bigtext&quot; style=&quot;width: 300px&quot;&gt;
    &lt;div&gt;The elusive&lt;/div&gt;
    &lt;div&gt;BIGTEXT&lt;/div&gt;
    &lt;div&gt;plugin exclusively&lt;/div&gt;
    &lt;div&gt;captured on film&lt;/div&gt;
&lt;/div&gt;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">$('#bigtext').bigtext();</pre></div></div>

<p>See <a href="http://jsfiddle.net/zachleat/WzN6d/">the above at JSFiddle</a>.</p>
<h3>Implementation Details</h3>
<p>The plugin itself is more than just a simple font-size incrementer.  I wasn&#8217;t happy with the performance of simply iterating through font sizes with a single fixed interval.  I decided it would be better to test multiple decreasing intervals.  For each line, it increments first by 16em until it detects a line break, backs off an interval then increments by <code>8em</code>. It continues with <code>4em</code>, <code>2em</code>, <code>1em</code>, <code>0.1em</code>, until it finds the correct <code>font-size</code> to the nearest hundredth of an em.  It&#8217;s noteworthy that Webkit does not respect font-sizes to the nearest hundredth, it&#8217;s precision is maxed out at tenths.  This algorithm results in fewer tests in most cases, especially where the resulting font-size will be very large. Performance is always important. After font-size, it moves to word-spacing as a backup for extra precision, especially needed on Webkit.</p>
<h2><em>The BigText Demo Wizard</em></h2>
<h3 style="text-align: center"><a href="/bigtext/demo/">Check out the Demo</a></h3>
<p>This is where the magic happens.</p>
<ul>
<li>Editable text (<code>contenteditable</code>), and BigText will run on every keyup event to resize what you&#8217;re typing.</li>
<li>Dynamic horizontal and vertical centering using <a href="http://infrequently.org/2009/08/css-3-progress/">Alex Russell&#8217;s Flex Box CSS classes</a> (This is easy now, hooray!)</li>
<li>3D transforms (browser support checked using <a href="http://www.modernizr.com/">Modernizr</a>, currently only available in Safari. Note: Chrome flattens to 2D space)</li>
<li>Custom fonts are loaded using <a href="http://code.google.com/apis/webfonts/docs/webfont_loader.html">Google&#8217;s Font Loader JavaScript API</a></li>
<li><a href="http://benalman.com/projects/jquery-throttle-debounce-plugin/">Ben Alman&#8217;s Throttle Plugin</a></li>
<li>The rest is mostly jQuery UI with the <a href="http://taitems.tumblr.com/post/482577430/introducing-aristo-a-jquery-ui-theme">Aristo theme</a></li>
</ul>
<p>Turns out, the <em>BigText Demo Wizard</em> makes for really easy <a href="http://vimeo.com/channels/kinetictypography">Kinetic Typography</a> screencasts (not amazing, but surely easy):</p>
<p><iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/OuqB6e6NPRM" frameborder="0"><br />
</iframe></p>
<p>The above is simply the manual process of typing lyrics into the <em>BigText Demo Wizard</em>.  You can easily make one of these too, with the help of the following keyboard shortcuts:</p>
<ul style="font-size: 90%">
<li>CTRL + ALT + X: Set the text to a random 3D transform angle.</li>
<li>CTRL + ALT + C: Toggles between white and black background.</li>
<li>CTRL + ALT + R: Reset 3D to default state.</li>
<li><strong>CTRL + ALT + SPACE: Fade out current text, clears the text, sets a random 3D transform angle, ready to type!</strong></li>
<li>CTRL + ALT + ENTER: Same as CTRL + ALT + SPACE, but keeps the same 3D transform angle.</li>
</ul>
<p>The fun part about the <em>BigText Demo Wizard</em> for me was that it almost turned into a non-musical instrument when I used it real-time to complement music.  Feel free to cruise Pandora and type lyrics to the music until your wrists get sore. <strong>What can you make with it?</strong></p>
<p><em>The BigText Demo Wizard was tested manually in Safari 5, Chrome 8, Opera 11, Firefox 3.6, and Internet Explorer 8.  The BigText jQuery plugin has a full JsTestDriver suite, available on <a href="https://github.com/zachleat/BigText">GitHub</a>.  Just run <code>./test.sh</code> or <code>test.bat</code></em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/bigtext-makes-text-big/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
		<item>
		<title>An Update to The JavaScript Testing Challenge</title>
		<link>http://www.zachleat.com/web/javascript-tdd-update/</link>
		<comments>http://www.zachleat.com/web/javascript-tdd-update/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 02:48:12 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Contests]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JsTestDriver]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=832</guid>
		<description><![CDATA[Update: The JavaScript Testing Challenge Winner In The JavaScript Testing Challenge, I asked JavaScript developers of the world to change their heathen ways and embrace the future of automated testing for a healthier and brighter tomorrow. However, due to seasonal timing or otherwise real life related reasons, the challenge was greeted with a worldwide chorus [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Update</strong>: <a href="/web/2011/02/14/javascript-tdd-winner/">The JavaScript Testing Challenge Winner</a></em></p>
<p>In <a href="/web/2010/11/13/javascript-tdd/">The JavaScript Testing Challenge</a>, I asked JavaScript developers of the world to change their heathen ways and embrace the future of automated testing for a healthier and brighter tomorrow.</p>
<p>However, due to seasonal timing or otherwise real life related reasons, the challenge was greeted with a worldwide chorus of universally blank stares.  So, in the true spirit of Christmas, I&#8217;m removing the deadline and <strong>will award the grand prize to the developer with the first correct and complete PrimeFactors code kata screencast</strong>.  That&#8217;s right, be the first to answer the challenge will win a copy of Test-Driven JavaScript Development by Christian Johansen (PDF or Print version, your choice).</p>
<p>If you have any questions or need help getting started, let me know! I&#8217;d be glad to help. Good luck!</p>
<div style="font-size: 90%"><em>Time of entry will be based on the twitter at message sent to @zachleat.  Full restrictions and rules posted <a href="/web/2010/11/13/javascript-tdd/">here</a>.</em></div>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-tdd-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The JavaScript Testing Challenge</title>
		<link>http://www.zachleat.com/web/javascript-tdd/</link>
		<comments>http://www.zachleat.com/web/javascript-tdd/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 21:10:16 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Contests]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Code Kata]]></category>
		<category><![CDATA[JsTestDriver]]></category>
		<category><![CDATA[QUnit]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=773</guid>
		<description><![CDATA[Update 2: The JavaScript Testing Challenge Winner Update: An Update to The JavaScript Testing Challenge Think back to the last time you wrote new code from scratch. Not autogenerated Dreamweaver image hovers or a pasted script from Dynamic Drive, but pure unadulterated new code. What was your process? I&#8217;m betting it&#8217;s probably similar to: (1) [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Update 2</strong>: <a href="/web/2011/02/14/javascript-tdd-winner/">The JavaScript Testing Challenge Winner</a></em></p>
<p><em><strong>Update</strong>: <a href="/web/2011/01/09/javascript-tdd-update/">An Update to The JavaScript Testing Challenge</a></em></p>
<p>Think back to the last time you wrote new code from scratch. Not autogenerated Dreamweaver image hovers or a pasted script from Dynamic Drive, but pure unadulterated new code. What was your process? I&#8217;m betting it&#8217;s probably similar to: (1) code, (2) switch to a browser, (3) confirm desired behavior for the change you&#8217;ve made, and (4) repeat.</p>
<p>Comrades, let me assure you that there is a better way, and it starts with writing unit tests. As a Front End Engineer that&#8217;s been doing it bareback without tests since I started in 1997, let me assure you that adopting automated testing strategies is one of the <strong>single best changes I&#8217;ve made to my development cycle</strong> to make myself more productive. Enough fluff. Let&#8217;s get started!</p>
<h2>Testing Environment Setup in 3 Steps</h2>
<p>Prerequisite: Java on the classpath</p>
<ol>
<li>Download the <a href="https://github.com/zachleat/JavaScript-Code-Katas/zipball/master">JavaScript-Code-Katas Source (ZIP)</a> (or checkout the code from the <a href="https://github.com/zachleat/JavaScript-Code-Katas">Github Repository</a>, if you have git available)</li>
<li>Extract and browse to it using your operating system&#8217;s command line.</li>
<li>Run (Windows)<br />
<code>&gt; JsTestDriver.bat Template</code></p>
<p>Run (MacOS)<br />
<code>$ ./JsTestDriver.sh Template</code><br />
<em>This script will close Safari (be careful if you&#8217;re using Safari in other windows)</em>
</li>
</ol>
<p>If a web browser popped up on your screen, congratulations! You have an automated testing environment set up and running.  Easy, right?</p>
<h2>Writing a Test</h2>
<p>Now, let&#8217;s write our first test!</p>
<ol>
<li>Open up <code>templateTest.js</code> in your favorite IDE.</li>
<li>Add the following:

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">TemplateTest = TestCase('TemplateTest');
TemplateTest.prototype.testSample = function()
{
    assertTrue(true);
    assertFalse(false);
    assertEquals(true, true);
};</pre></div></div>

</li>
<li>Re-run the JsTestDriver shell script from Step #3 above.</li>
</ol>
<p>Now you should see something like the following:</p>
<pre>
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (2.00 ms)
  Safari 533.18.5 Mac OS: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (2.00 ms)
</pre>
<p><strong>Notice how you didn&#8217;t have to touch any HTML boilerplate code or manually bring up a web browser?</strong> Productivity ensues! You&#8217;ve made it this far, are you brave enough to dive into a Code Kata?</p>
<h2>Prime Factors Code Kata</h2>
<p>Code Katas are just small programs used as practice.  They&#8217;re a great way to introduce Test Driven Development and improve proficiency with your IDE.</p>
<p>The Prime Factors Code Kata requires a function that takes a single integer argument and returns an array of prime factors of that argument in ascending numerical order.  For example, passing in <code>8</code> should return <code>2, 2, 2</code>.</p>
<ul>
<li><a href="https://docs.google.com/present/edit?id=0AVz1CG9ZSGbWZG5iajc4c18zN2R2NzJnZmRq&#038;hl=en&#038;authkey=CO38t6gL">Original Java version by Uncle Bob Martin</a> (see <a href="http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata">original post</a>).</li>
<li><a href="https://github.com/zachleat/JavaScript-Code-Katas/blob/master/PrimeFactors/primeFactors.js">JavaScript implementation of the Prime Factors algorithm</a></li>
</ul>
<p>I&#8217;ve recorded an unmodified single-take screencast of myself performing the kata below. I&#8217;m using the same source code I provided above, but with the <a href="http://code.google.com/p/js-test-driver/wiki/UsingTheEclipsePlugin">JsTestDriver Eclipse plugin</a> instead of using the command line to run the tests.  The plugin is great for the screencast, because it very easily shows when the tests are failing or passing. You might also notice that it reruns the tests automatically every time I save.</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/zsCYkmAJBAY?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/zsCYkmAJBAY?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
<h2>JsTestDriver</h2>
<p>If you want to learn more a about JsTestDriver, check out their <a href="http://code.google.com/p/js-test-driver/">Google Code</a> page.  &#8220;But I use QUnit!&#8221; you say. That&#8217;s fine, <a href="http://code.google.com/p/js-test-driver/wiki/QUnitAdapter">there is an adaptor for that</a>.  Using both tools together, you won&#8217;t need to launch each individual browser manually and trigger the tests to start.  It will save you time.</p>
<div style="font-size: 90%">
In the interest of full disclosure, here are the issues I&#8217;ve ran into so far using JsTestDriver:</p>
<ul>
<li>Doesn&#8217;t apply CSS in some browsers. <a href="http://code.google.com/p/js-test-driver/issues/detail?id=81">Issue #81</a></li>
<li>Defaults to quirks mode. <a href="http://code.google.com/p/js-test-driver/issues/detail?id=79">Issue #79</a></li>
</ul>
</div>
<h2 id="challenge">Challenge</h2>
<p>Testing will help you. It will improve your the quality of your code and your productivity. I challenge you to practice the JavaScript Prime Factors Code Kata in your own IDE with your own automated testing process. Send a link to  me on Twitter (<a href="http://twitter.com/zachleat">@zachleat</a>) with an unmodified single-take screencast of you performing the kata (in JavaScript) by December 25, 2010 and <strong>the fastest kata screencast will win a copy of <a href="http://tddjs.com/">Test-Driven JavaScript Development</a></strong> by <a href="http://twitter.com/cjno/">Christian Johansen</a> (PDF or Print version, your choice*).</p>
<p><a href="http://screenr.com/">Screenr</a> is a great tool for recording screencasts, if you need one.</p>
<p>Good luck!</p>
<div style="font-size: 90%"><em>Coding must follow every step performed by myself in the above version. Templates and keyboard shortcuts can be used at your leisure, but no code can be generated specific to the kata itself (it must be a generic).  Use your best judgement here, I reserve the right to disqualify any entries submitted that don&#8217;t follow the true spirit of the competition.</p>
<p>Don&#8217;t fuck with the speed of the video. I&#8217;m spending my own money on this, so if you&#8217;re cheating then you&#8217;re just stealing from me. Just be cool about it, okay?</p>
<p>* The Print version of the prize is restricted to USA or Canada, PDF version is available internationally (unless you want to work something out for shipping costs).</em></div>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-tdd/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Faking Onload for Link Elements</title>
		<link>http://www.zachleat.com/web/load-css-dynamically/</link>
		<comments>http://www.zachleat.com/web/load-css-dynamically/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 01:50:24 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=733</guid>
		<description><![CDATA[Updated 2011/09/27: Rejoice! This issue has now been fixed in Firefox. Or, I Am Dynamically Loaded CSS (and So Can You!) Dynamic resource loading is one of the keys to have a performance happy web application. There are generally three different criteria we must address when making a request: cross domain security policies, asynchronous/synchronous (will [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Updated 2011/09/27: Rejoice! This issue has now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=185236">been fixed in Firefox</a>.</strong></p>
<hr/>
<p>Or, <strong>I Am Dynamically Loaded CSS (and So Can You!)</strong></p>
<p>Dynamic resource loading is one of the keys to have a performance happy web application.  There are generally three different criteria we must address when making a request: cross domain security policies, asynchronous/synchronous (will it block the host page while loading), and whether or not events are triggered when the request completes.</p>
<p>If the resource and host page are on the same domain, obviously <code>XMLHttpRequest</code> works the best.  We can control whether or not the resource is loaded asynchronously or synchronously, and we know exactly when it gets done.</p>
<p>If the resource and host page are on different domains (increasingly more common with CDN&#8217;s), our options narrow. Loading the JavaScript is a solved problem, just use the <code>onload</code> event on the <code>&lt;script&gt;</code> tag and you&#8217;re good to go (<code>onreadystatechange</code> for IE).  But CSS is more complicated.</p>
<table>
<thead>
<tr>
<th>Resource</th>
<th>Method</th>
<th>Option for (a)synchronous</th>
<th>Event</th>
</tr>
</thead>
<tbody>
<tr>
<td>JavaScript/CSS Same Domain</td>
<td><code>XMLHttpRequest</code></td>
<td>Both</td>
<td><code>onreadystatechange</code></td>
</tr>
<tr>
<td>JavaScript Different Domain</td>
<td><code>&lt;script&gt;</code></td>
<td>Synchronous (Asynchronous where <a href="https://developer.mozilla.org/en/html/element/script">async property</a> is supported)</td>
<td><code>onload</code><br />
<code>onreadystatechange</code> for IE</td>
</tr>
<tr>
<td>CSS  Different Domain</td>
<td><code>&lt;link&gt;</code></td>
<td>Asynchronous</td>
<td><em>What this blog post is about.</em></td>
</tr>
</tbody>
</table>
<h2>Existing Solutions</h2>
<p>In all of the library source code I evaluated, Internet Explorer didn&#8217;t cause any issues.  It fires both the <code>onload</code> and <code>onreadystatechange</code> events for <code>&lt;link&gt;</code> nodes.  Obviously this is ideal behavior, and IE got it right. But what about Firefox and Safari/Chrome?</p>
<h3>YUI 2.8.1 and 3.1.1</h3>
<p><a href="http://github.com/yui/yui3/blob/master/build/yui/get.js#L311">Original Source</a></p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// FireFox does not support the onload event for link nodes, so there is
// no way to make the css requests synchronous. This means that the css 
// rules in multiple files could be applied out of order in this browser
// if a later request returns before an earlier one.  Safari too.
if ((ua.webkit || ua.gecko) &amp;&amp; q.type === &quot;css&quot;) {
    _next(id, url);
}</pre></div></div>

<p>I wouldn&#8217;t be surprised if the commit log there was from Bon Jovi; that code is living on a prayer.</p>
<h3>LazyLoad</h3>
<p><a href="http://github.com/rgrove/lazyload/blob/master/lazyload.js#L283">Original Source</a></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Gecko and WebKit don't support the onload event on link nodes. In</span>
<span style="color: #006600; font-style: italic;">// WebKit, we can poll for changes to document.styleSheets to figure out</span>
<span style="color: #006600; font-style: italic;">// when stylesheets have loaded, but in Gecko we just have to finish</span>
<span style="color: #006600; font-style: italic;">// after a brief delay and hope for the best.</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ua.<span style="color: #660066;">webkit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    p.<span style="color: #660066;">urls</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> node.<span style="color: #660066;">href</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// resolve relative URLs (or polling won't work)</span>
    poll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    setTimeout<span style="color: #009900;">&#40;</span>_finish<span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span> <span style="color: #339933;">*</span> len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Better, closer, warmer.  This includes a nice method for working with webkit browsers.  The poll method compares <code>document.styleSheets</code>, since Webkit has the nice option of only appending to the styleSheets object when the styleSheet has successfully loaded.</p>
<p>So we have working solutions for IE and Safari/Chrome. The only unsolved piece of the puzzle here is Firefox.</p>
<p><a href="http://wonko.com/post/how-to-prevent-yui-get-race-conditions">This post</a> from the same author as LazyLoad also describes another solution which involves modifying the source CSS and polling against it.  But that&#8217;s not really ideal. Can we do better?</p>
<h2>Solution</h2>
<p>Here&#8217;s what I came up with (using jQuery for brevity, note that this solution <strong>only fixes Firefox</strong>, and does not incorporate the above already solved solutions):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'css.php'</span><span style="color: #339933;">,</span>
    id <span style="color: #339933;">=</span> <span style="color: #3366CC;">'dynamicCss'</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;style/&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    id<span style="color: #339933;">:</span> id<span style="color: #339933;">,</span>
    type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'text/css'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'@import url('</span> <span style="color: #339933;">+</span> url <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> poll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> sheets <span style="color: #339933;">=</span> document.<span style="color: #660066;">styleSheets</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> k<span style="color: #339933;">=</span>sheets.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>k<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>sheets<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">ownerNode</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">==</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                sheets<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">cssRules</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #006600; font-style: italic;">// If you made it here, success!</span>
        <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'success!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// Keep polling</span>
        window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>poll<span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
window.<span style="color: #660066;">setTimeout</span><span style="color: #009900;">&#40;</span>poll<span style="color: #339933;">,</span> <span style="color: #CC0000;">50</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3><a href="http://zachleat.com/javascript/loadcss/load.html">See this demo in action.</a> (Firefox only)</h3>
<p><br/><br />
<strong>Update</strong>: After much joy and celebration, I have discovered that an approach similar to the above was written by Oleg Slobodskoi in his <a href="http://plugins.jquery.com/files/jquery.xLazyLoader.js.txt">xLazyLoader</a> plugin for jQuery.  It shouldn&#8217;t be surprising that two independent developers might reach the same solution, and is just more proof that software patents are stupid. :)</p>
<p><strong>Update #2</strong> Added note about HTML5 async property on script tags.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/load-css-dynamically/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Maiden Voyage of the DOM Sailbloat</title>
		<link>http://www.zachleat.com/web/dom-sailbloat/</link>
		<comments>http://www.zachleat.com/web/dom-sailbloat/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 04:09:28 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firebug Lite]]></category>
		<category><![CDATA[log4javascript]]></category>
		<category><![CDATA[YUI Logger]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=698</guid>
		<description><![CDATA[As many of you may already know, my day job includes managing a large and complex enterprise jQuery-based user interface component library. It&#8217;s used by all new web applications at the company, which boasts over an IT department of approximately 1500 people and hundreds of web applications. Needless to say, I get a fair volume [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/07/typhoon-in-macao.jpg" alt="" title="typhoon-in-macao" width="680" height="503" class="aligncenter size-full wp-image-710" /></p>
<p>As many of you may already know, my day job includes managing a large and complex enterprise jQuery-based user interface component library. It&#8217;s used by all new web applications at the company, which boasts over an IT department of approximately 1500 people and hundreds of web applications.  Needless to say, I get a fair volume of interesting support tickets that come my way.  A few weeks ago, I had the pleasure of receiving one such ticket.</p>
<p>The support ticket&#8217;s symptoms included a oft-heard complaint: poor performance.  On the web, poor performance can be attributed to a great many things, but most often can be boiled down to a bottleneck in JavaScript code using the DOM API.  This time, strangely enough, the culprit was something else entirely.</p>
<p>One of the first things I check when an application complains of poor performance is the total size of the document, or how many nodes it has.  One of the best ways to ensure good performance is to keep your document small, especially on projects using heavy dynamic element selection and filtering (think jQuery, Mootools, Prototype, Dojo, or any code using a selector engine like Sizzle).  Any JavaScript library emulating CSS selectors executing over a very large document is going to take quite a bit longer than querying a small document, especially when the user&#8217;s browser doesn&#8217;t support native <code>querySelector</code> or <code>getElementsByClassName</code>.</p>
<p>To get an idea of what the size of a large document is, I usually go to a site with some fairly advanced JavaScript and query their size.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Returns the total number of nodes in the document
document.getElementsByTagName('*').length;
// note: this number will not include any child nodes inside of iframes.</pre></div></div>

<table>
<thead>
<tr>
<th>URL</th>
<th>Total Element Count</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>maps.google.com</code></td>
<td><code>731</code></td>
</tr>
<tr>
<td><code>my.yahoo.com</code></td>
<td><code>1508</code></td>
</tr>
<tr>
<td><code>calendar.google.com (Authenticated)</code></td>
<td><code>681</code></td>
</tr>
<tr>
<td><code>reader.google.com (Authenticated)</code></td>
<td><code>4866</code></td>
</tr>
</tbody>
</table>
<p>Getting back to the support ticket in question.  After querying the document, I quickly found that the page contained over <strong>50000 nodes</strong>.  Wow.  So, we&#8217;ve caught a big one.  You&#8217;re going to be telling your grandkids about this some day.  But, now what?</p>
<p>I decided it would be beneficial to find out where and what all of those nodes were.  After clicking around the live document in the Firebug&#8217;s HTML tab for awhile, looking at View Source, and Ajax requests in the Console, I successfully determined the culprit.  This particular application was using <a href="http://wicket.apache.org/">Wicket</a>, a popular Java library for web applications, which includes its own <em>Ajax Logger</em> component (similar to my favorite <a href="http://log4javascript.org/">log4javascript</a>; or something like the <a href="http://developer.yahoo.com/yui/logger/">YUI Logger</a>), used to keep track of an application&#8217;s Ajax calls and JavaScript page manipulations with an inline GUI embedded in the parent document.  On one page load, this application&#8217;s Ajax logger component had <strong>created 40000 nodes of log content</strong>.</p>
<p>It&#8217;s important to realize that embedding unnecessary content of that magnitude on the page can be very detrimental to performance. <strong>JavaScript loggers should log to a new child window, rather than be embedded in the parent document.</strong>  This way they won&#8217;t bloat the document, but still provide you with much needed logging information.</p>
<p>But, in the future, how might this type of problem be more easily diagnosed and prevented?  Ideally, when confronted with large documents, we want to see where in the document the majority of those nodes are located.  But there isn&#8217;t an easy way to see which portion of the document is using the largest number of nodes, especially if the culprit is deep into the document tree.  We can go through the source code manually, but that isn&#8217;t  very efficient.</p>
<p>So in the spirit of exploratory development to help troubleshoot real-world problems, I decided to make a Firebug Lite plugin.  This would give me an easy cross-browser tool to diagnose my problem in a familiar interface.  Load up Firebug Lite, load the <em>DOM Sailbloat</em> JavaScript file, and easily spot the HTML love handles.</p>
<p>Here&#8217;s what it looks like in action:<br />
<img src="http://www.zachleat.com/web/wp-content/uploads/2010/07/Screen-shot-2010-07-19-at-9.59.49-PM.png" alt="" title="Screen shot of the DOM Sailbloat Firebug Lite plugin" class="aligncenter size-full wp-image-714" /></p>
<h2>Go Forth</h2>
<ol>
<li><a href="http://www.zachleat.com/domsailbloat/">See the demo</a></li>
<li><a href="http://www.zachleat.com/domsailbloat/domsailbloat.js">Download the source</a></li>
<li><a href="http://github.com/zachleat/DOM-Sailbloat">Fork the Sailbloat on GitHub</a></li>
</ol>
<p><em>Note: there is currently an undiagnosed issue with the Sailbloat and it fails to load intermittently.  If you know why, I&#8217;d be happy to put your name in the source code credits.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/dom-sailbloat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Point, Charset, Match: Character Encoding in JavaScript</title>
		<link>http://www.zachleat.com/web/charset/</link>
		<comments>http://www.zachleat.com/web/charset/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 00:16:47 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Character Encoding]]></category>
		<category><![CDATA[Closure Compiler]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=589</guid>
		<description><![CDATA[If you&#8217;re not familiar with the principles of character encoding, read the prerequisite Dive Into HTML 5 section on the subject. When you see issues with Character Encoding, it&#8217;s traditionally in the form of text on your page that looks like this: in Firefox or in IE. Usually, those characters mean that the character encoding [...]]]></description>
			<content:encoded><![CDATA[<p><em>If you&#8217;re not familiar with the principles of <strong>character encoding</strong>, read the prerequisite <a href="http://diveintohtml5.org/semantics.html#encoding">Dive Into HTML 5 section</a> on the subject.</em></p>
<p>When you see issues with Character Encoding, it&#8217;s traditionally in the form of text on your page that looks like this: <img src="http://www.zachleat.com/web/wp-content/uploads/2010/03/unencoded.png" alt="" title="unencoded" width="16" height="19" class="size-full wp-image-593" style="vertical-align: bottom; margin-bottom: 0" /> in Firefox or <img src="http://www.zachleat.com/web/wp-content/uploads/2010/03/unencoded-ie.png" alt="" title="unencoded-ie" width="11" height="14" class="size-full wp-image-592" style="vertical-align: bottom; margin-bottom: 0" /> in IE.</p>
<p>Usually, those characters mean that the character encoding used on the page is either ambiguous (not specified), or incorrect.  We can use Firefox to determine that Character Encoding of a web page (Right Click and go to View Page Info; or use the &#8220;Character Encoding&#8221; entry in the View menu).  Check to make sure that the encoding reported by Firefox is the same encoding used in your IDE.  For example, Eclipse 3.5 has a &#8220;Set Encoding&#8221; option in the Edit menu.</p>
<p>The reason most English alphabetic and numeric characters are consistent independent of character encoding is due to consistency in the lower characters in each encoding.  The characters making up the <a href="http://www.asciitable.com/">ASCII character set</a> (0-127) are the same as the lowest 128 characters of <a href="http://en.wikipedia.org/wiki/ISO/IEC_8859-1#ISO-8859-1">ISO-8859-1</a>, <a href="http://www.utf8-chartable.de/">UTF-8</a>, and others.</p>
<p>Managing your character encodings gets trickier as you add more architectural layers to your application.  For example, character encodings may differ in your database, the properties files used to configure your application (java.util.Properties uses ISO-8859-1 by default), or maybe the XML or JSON file you&#8217;re loading from an external API.</p>
<p>Ever heard of HTML character entities?  That&#8217;s the primary reason they exist &#8212; as a sort of encoding independent reference to a particular character.  So, for example, the Œ character does not exist in the ISO-8859-1 character set.  To display this character in a document with ISO-8859-1 encoding, use the equivalent HTML character entity: <code>&amp;OElig;</code>.  For an easier reference, check out this full table of <a href="http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references">HTML character entities</a>.  If using ISO-8859-1 for your HTML document, any entity above Unicode index 255 will need to be escaped.  If you&#8217;re using UTF-8 encoding, HTML character entities shouldn&#8217;t be required.</p>
<h2>Setting the Character Encoding</h2>
<p>To specify the character encoding for any file, you can set a <code>Content-Type</code> header <a href="http://www.w3.org/International/O-HTTP-charset">by configuring your web server or application</a>.  Apache lets you easily set different default character encodings for each individual file extension (<code>.js</code> for example).  Using the <code>Content-Type</code> header is the most full proof and efficient <sup><a href="#performance">1</a></sup> method to serve content.</p>
<p>But without access to the Apache configuration, how do we specify the character encoding?</p>
<h3>For external JavaScript Files</h3>
<h4>In the HTML File</h4>
<p>Just add the <code>charset</code> attribute.  If not specified, the HTML document&#8217;s character encoding is used by default (specified in the <code>Content-Type</code> header or the appropriate meta tag, for example: <code>&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;</code>).</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot; src=&quot;script.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</pre></div></div>

<h4>In the JavaScript File</h4>
<p>To my knowledge, <strong>there is no way for a JavaScript file to report its own character encoding</strong>.  To me, this seems like an omission.  Each individual document should be able to report its own character encoding without a header.  CSS files can do it (<code>@charset</code> at-rule).  HTML files can do it (<code>&lt;meta&gt;</code> tag).  Why not JavaScript files?</p>
<h4>For Dynamically Created Script Tags</h4>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">var s = document.createElement('script');
s.src = 'script.js';
s.type = 'text/javascript';
s.charset = 'utf-8';</pre></div></div>

<p>If you&#8217;re using <a href="http://api.jquery.com/jQuery.ajax/">jQuery&#8217;s Ajax</a> functions to load external JavaScript files, perhaps you might be inclined to use the <code>script dataType</code>.  jQuery even provides a <code>scriptCharset</code> option for wrapping the above method for changing the charset on a dynamic script tag. <strong>Be warned</strong>, the jQuery Ajax function uses two different methods to load external script files (as of version 1.4.2).  If a same-domain request, it uses an <code>XMLHttpRequest</code>.  If a cross-domain request, it uses a dynamic <code>script</code> tag.  So the <strong><code>scriptCharset</code> jQuery option only applies to cross-domain requests</strong>.  We&#8217;ll need some other method to mitigate our character encoding issues (or just use dynamic script tags).</p>
<h4>For XMLHttpRequest Objects</h4>
<p>Our saving grace would be the <a href="https://developer.mozilla.org/en/XMLHttpRequest#overrideMimeType()"><code>overrideMimeType</code></a> method, if it weren&#8217;t poetically unavailable in Internet Explorer.  Using this method, we can override the mime type and character encoding.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">var xhr = new XMLHttpRequest();
// Not available in Internet Explorer (up to version 8 at time of writing)
if (xhr.overrideMimeType) {
    xhr.overrideMimeType('application/x-javascript; charset=utf-8');
}</pre></div></div>

<h3>Portable non-ASCII JavaScript</h3>
<p>The best way to make non-ASCII characters in JavaScript files portable is to escape the characters properly.  If the character is destined for HTML, use an HTML character entity (if available, not all Unicode or ISO-8559-1 characters have entities).  Or, escape the characters using the proper Latin or <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Unicode">Unicode escape sequence</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Raw characters
var string = &quot;ñó&quot;;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// HTML character entities
var string = &quot;&amp;ntilde;&amp;oacute;&quot;;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Escaped to Latin
var string = &quot;\xf1\xf3&quot;;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="js" style="font-family:monospace;">// Escaped to Unicode
var string = &quot;\u00f1\u00f3&quot;;</pre></div></div>

<p>If you use the Google Closure Compiler, you&#8217;ll get the Unicode escape sequences for free (see issues <a href="http://code.google.com/p/closure-compiler/issues/detail?id=24">24</a> and <a href="http://code.google.com/p/closure-compiler/issues/detail?id=68">68</a>).  Make sure to read the tickets for more benefits of serving your JavaScript files using Unicode escape sequences to output only ASCII characters.</p>
<h2>Summary</h2>
<p>The easiest way to preemptively solve a lot of character encoding issues is to use UTF-8 for everything, and configure your web server/application to serve the UTF-8 <code>Content-Type</code> header. If you&#8217;re writing JavaScript code that you&#8217;re going to distribute to the masses, convert any non-ASCII characters using the proper escape sequences. Your JavaScript will be more portable, and will work out of the box on more server configurations.</p>
<h4>Sources</h4>
<ol>
<li><a id="performance" href="http://www.kylescholz.com/blog/2010/01/performance_implications_of_charset.html">Performance Implications of Charset, an article by Kyle Scholz</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/charset/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Internet Explorer Array.sort Unreliable</title>
		<link>http://www.zachleat.com/web/array-sort/</link>
		<comments>http://www.zachleat.com/web/array-sort/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 02:09:52 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[JScript]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=568</guid>
		<description><![CDATA[What would you expect to be the result of executing the following code? // Create a medium size array, at least 100 items var obj = &#91;&#93;; for&#40;var j=0, k=150; j&#60;k; j++&#41; &#123; // the value here doesn't matter. obj.push&#40;'ABCD'+j&#41;; &#125; &#160; // Sort the array alphabetically. obj.sort&#40;function&#40;m,p&#41;&#123; m=&#40;''+m&#41;.toLowerCase&#40;&#41;; p=&#40;''+p&#41;.toLowerCase&#40;&#41;; &#160; if&#40;m &#62; p&#41; return [...]]]></description>
			<content:encoded><![CDATA[<p>What would you expect to be the result of executing the following code?</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Create a medium size array, at least 100 items</span>
<span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> k<span style="color: #339933;">=</span><span style="color: #CC0000;">150</span><span style="color: #339933;">;</span> j<span style="color: #339933;">&lt;</span>k<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// the value here doesn't matter.</span>
    obj.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ABCD'</span><span style="color: #339933;">+</span>j<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Sort the array alphabetically.</span>
obj.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #339933;">,</span>p<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    m<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    p<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>p<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&gt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&lt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The <code>obj</code> Array should now be sorted, in alphabetical order based on value.  <strong>BUT, in our best friend Internet Explorer, a <code>Number Expected</code> error may be the result.</strong>  Don&#8217;t be fooled if your test array behaves correctly, it only happens intermittently for arrays of varying size!</p>
<p>So, I <a href="http://www.zachleat.com/test/numberexpected/">whipped up a quick test to check the damage</a>.  Iterating over array sizes from 1 to 150, running the Array sort algorithm.  The following failures resulted:</p>
<table>
<thead>
<tr>
<th>Browser</th>
<th>Failures *</th>
</tr>
</thead>
<tbody>
<tr>
<td>Internet Explorer 6</td>
<td>4 sizes out of 150</td>
</tr>
<tr>
<td>Internet Explorer 7</td>
<td>18 sizes out of 150</td>
</tr>
<tr>
<td>Internet Explorer 8 (and Compatibility Mode)</td>
<td>2 sizes out of 150</td>
</tr>
<tr>
<td>Internet Explorer 9 (and Compatibility Mode)</td>
<td>0 sizes out of 150 (Fixed!)</td>
</tr>
</tbody>
</table>
<p>* Failures may vary to the specifications of the test machine.</p>
<p>Of course, the <code>Number Expected</code> error is going to result whenever your code doesn&#8217;t return a number inside of the function callback.  But the problem here is something deeper than simple application code failure.  The problem is in JScript itself.  Any modification to the sort arguments may result in the <code>Number Expected</code> error.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    m<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>m<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// modifies the argument m and is unreliable.</span></pre></div></div>

<p>This problem will manifest itself more frequently if you use the Google Closure Compiler, which restructures JavaScript to reuse argument variables if possible, probably to save the 4 character penalty of a &#8220;var &#8221; declaration.</p>
<p>Normally, reusing argument variables is a safe practice for primitives, since they are passed by value and not by reference, as is the case in this Array sort example <sup><a href="#by-ref">1</a></sup>.  So, what exactly is going on here?  One commenter at the <a href="http://code.google.com/p/closure-compiler/issues/detail?id=58">Google Closure Compiler bug</a> seems to think that the actual array values are being passed by reference instead of by value.  I&#8217;m not completely convinced that&#8217;s the case.</p>
<h2>The Fix</h2>
<p><strong>Don&#8217;t reuse the argument variables inside of an Array sort function.</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Changing the above example</span>
obj.<span style="color: #660066;">sort</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m1<span style="color: #339933;">,</span>p1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> m<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>m1<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        p<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #339933;">+</span>p1<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&gt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>m <span style="color: #339933;">&lt;</span> p<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>Check the <a href="http://www.zachleat.com/test/numberexpected/">source code of the demo file</a> to see the different methods of modifying the arguments that I attempted.</em></p>
<ol>
<li id="by-ref">If you want to learn more about passing by value or reference, <a href="http://snook.ca/archives/javascript/javascript_pass">Jonathan Snook has a nice explanation</a>.</li>
</ol>
<p><em style="font-size: 80%">Internet Explorer can&#8217;t make you do anything, it can only make you wish you hadn&#8217;t.</em></p>
<p><strong>Updated: Added note about Internet Explorer 9 and its Compatibility View. Looks like it&#8217;s fixed!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/array-sort/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Trash that &#8220;Back to Top&#8221; Link</title>
		<link>http://www.zachleat.com/web/trash-that-back-to-top-link/</link>
		<comments>http://www.zachleat.com/web/trash-that-back-to-top-link/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 01:30:30 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Interface Design]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Page Fold]]></category>
		<category><![CDATA[Scrolling]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=376</guid>
		<description><![CDATA[It would seem that perfection is attained not when no more can be added, but when no more can be removed. - Antoine de Saint Exupéry While most would argue that the principles espoused in the above quote might also be applied to the quote itself, it would serve us better to consider how we [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>It would seem that perfection is attained not when no more can be added, but when no more can be removed.</p>
<div style="text-align: right;">- Antoine de Saint Exupéry</div>
</blockquote>
<p><br/><br />
While most would argue that the principles espoused in the above quote might also be applied to the quote itself, it would serve us better to consider how we can <strong>attempt perfection in our User Interface designs</strong> instead.</p>
<p>The most complete litany of reasons why you should spend your page weight on more useful bytes has been <a href="http://www.cs.tut.fi/~jkorpela/www/totop.html">compiled by Jukka Korpela</a>, although he seems to both confirm that they are harmful and still use them on his site.</p>
<p>The rules of engagement I find useful when dealing with the ill-fated &#8220;Back to Top&#8221; or its ugly stepsister &#8220;Top of Page&#8221; link are as follows:</p>
<ol>
<li><strong>Delete the link.</strong></li>
</ol>
<p>Really, you don&#8217;t need the link. It&#8217;s a <strong>sacred cow remnant</strong> of a time when people believed that all content needed to be positioned <a href="http://iampaddy.com/lifebelow600/">above the page fold</a>.</p>
<p>Guess what?  <strong>People know how to scroll!</strong>  They know how to scroll down, they know how to scroll up.  Considering this prerequisite has been met, it becomes very apparent that the &#8220;Back to Top&#8221; link shares an <strong>unnecessary overlap in functionality with the scrollbar</strong> and is thus, unnecessary itself.</p>
<p>If you have an incredibly long page with a full set of &#8220;Table of Contents&#8221; links, it would be better to position your <a href="http://jqueryfordesigners.com/fixed-floating-elements/">table of contents fixed to the viewport</a>, so as to make it always available to the user.  If the Table of Contents is always available, the user will never have to click a link as a shortcut to find it.</p>
<p>While not a usability epidemic, the &#8220;Back to Top&#8221; link is still widely used.  <a href="http://www.instantshift.com/2009/07/14/90-creative-back-to-top-links-and-best-practices/">Instant Shift</a> and <a href="http://www.smashingmagazine.com/2008/11/27/short-story-about-top-links/">Smashing Magazine</a> both have articles with hundreds of examples of sites with these links.</p>
<p>Don&#8217;t agree? If you&#8217;re stubborn as hell and hate simplicity, you&#8217;re going to keep the link on your page no matter what reasons are presented.  In that case, at the very least follow these two guidelines:</p>
<ol>
<li>Use <strong>progressive enhancement</strong>:

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;back-to-top&quot;</span>&gt;</span>Back to Top<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// jQuery Prerequisite</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#back-to-top'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    window.<span style="color: #660066;">scrollTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// don't change the hash if not needed</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li><strong>Hide the link</strong> if the page doesn&#8217;t have a scrollbar.  If no scrollbar exists, the user will <strong>always be &#8220;at the top.&#8221;</strong>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Continuing with Previous Example</span>
$<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#back-to-top'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// If the page scrolls, we know there is a scrollbar.</span>
$<span style="color: #009900;">&#40;</span>window<span style="color: #009900;">&#41;</span>.<span style="color: #000066;">scroll</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#back-to-top'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// For completeness, you may also want to</span>
<span style="color: #006600; font-style: italic;">//   add logic to the &quot;resize&quot; event.</span></pre></div></div>

</li>
</ol>
<p>Really though, <strong>just delete the link.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/trash-that-back-to-top-link/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Quick Performance Tip: jQuery and addClass</title>
		<link>http://www.zachleat.com/web/quick-performance-tip-jquery-and-addclass/</link>
		<comments>http://www.zachleat.com/web/quick-performance-tip-jquery-and-addclass/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 04:51:01 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=226</guid>
		<description><![CDATA[Abstractions are helpful and dangerous. But the more we know about a library&#8217;s internals, the less danger we&#8217;ll be in later. Here&#8217;s an issue I ran into where I had assumed that jQuery would be optimized for this case, but it wasn&#8217;t. I&#8217;ll go over my bad assumption and how to workaround it. As of [...]]]></description>
			<content:encoded><![CDATA[<p>Abstractions are helpful and dangerous.  But the more we know about a library&#8217;s internals, the less danger we&#8217;ll be in later.  Here&#8217;s an issue I ran into where I had assumed that jQuery would be optimized for this case, but it wasn&#8217;t.  I&#8217;ll go over my bad assumption and how to workaround it.</p>
<p>As of jQuery 1.3.2, adding multiple HTML classes to an element using jQuery&#8217;s addClass method will add them one at a time, modifying the className property of an element for each class.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myElement'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'myFirstClass mySecondClass'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Here&#8217;s the original code inside of jQuery 1.3.2.  Note how the classNames string is split, and elem.className is changed for each split entry.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">add<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> elem<span style="color: #339933;">,</span> classNames <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    jQuery.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>classNames <span style="color: #339933;">||</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\s+/</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> className<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> elem.<span style="color: #660066;">nodeType</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>jQuery.<span style="color: #660066;">className</span>.<span style="color: #660066;">has</span><span style="color: #009900;">&#40;</span> elem.<span style="color: #660066;">className</span><span style="color: #339933;">,</span> className <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
            elem.<span style="color: #660066;">className</span> <span style="color: #339933;">+=</span> <span style="color: #009900;">&#40;</span>elem.<span style="color: #660066;">className</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">&quot; &quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> className<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #006600; font-style: italic;">// ...</span></pre></div></div>

<p>This may cause longer than needed delays, as reflow may occur after every class is added individually.  If absolutely necessary, you can always fall back to modifying the className yourself, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#myElement'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">className</span> <span style="color: #339933;">+=</span> <span style="color: #3366CC;">' myFirstClass mySecondClass'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Most likely, this isn&#8217;t a tip that will be needed, but it is useful to be aware of.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/quick-performance-tip-jquery-and-addclass/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Performance Caveat with jQuery Selectors and Live Events</title>
		<link>http://www.zachleat.com/web/performance-caveat-with-jquery-selectors-and-live-events/</link>
		<comments>http://www.zachleat.com/web/performance-caveat-with-jquery-selectors-and-live-events/#comments</comments>
		<pubDate>Fri, 08 May 2009 13:00:04 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Event Delegation]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=211</guid>
		<description><![CDATA[Prerequisite: Knowledge/Experience with jQuery Live Events (new in jQuery 1.3), and the concept of Event Delegation. When developing on the front end, it&#8217;s easy to prioritize correctness over performance. Performance is the step child that gets lost while you&#8217;re pulling your hair out worrying about cross browser compatibility. It&#8217;s very important to regularly benchmark your [...]]]></description>
			<content:encoded><![CDATA[<p><em>Prerequisite: Knowledge/Experience with <a href="http://docs.jquery.com/Events/live">jQuery Live Events</a> (new in jQuery 1.3), and the concept of <a href="http://icant.co.uk/sandbox/eventdelegation/">Event Delegation</a>.</em></p>
<p>When developing on the front end, it&#8217;s easy to prioritize correctness over performance.  Performance is the step child that gets lost while you&#8217;re pulling your hair out worrying about cross browser compatibility.  It&#8217;s very important to regularly benchmark your JavaScript code, using a <a href="http://getfirebug.com/js.html">profiler</a> or some form of benchmarking code paired with a cross browser logging utility (see <a href="http://getfirebug.com/lite.html">Firebug Lite</a>, <a href="http://developer.yahoo.com/yui/logger/">YUI Logger</a>, or <a href="http://log4javascript.org/">log4javascript</a>).</p>
<p>Event delegation is a great way to program for performance.  The <code>live</code> jQuery method was a great addition to the jQuery core, it makes event delegation really easy (see also the <code>closest</code> method).  Unfortunately, it isn&#8217;t quite what I expected.</p>
<p>For example, say you have a page containing approximately 500 custom tooltip components on it (not typical, but stick with me, this is to prove a point). How might one go about adding a simple live event to activate each tooltip when the user hovers over it?</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span.myTooltip'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mouseover'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// activate tooltip</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>See the problem?  jQuery will actually run the selector on the document, resulting in unnecessary overhead. jQuery is only assigning a single event handler to top level of the document, why does it need to know what nodes it will be binding to before assigning the callback?</p>
<p>What can we do?  Let&#8217;s create a jQuery function, instead of a method, so it won&#8217;t query the document.  Try this on for size:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">live</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>selector<span style="color: #339933;">,</span> type<span style="color: #339933;">,</span> fn<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    r.<span style="color: #660066;">selector</span> <span style="color: #339933;">=</span> selector<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>type <span style="color: #339933;">&amp;&amp;</span> fn<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        r.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span>type<span style="color: #339933;">,</span> fn<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> r<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Usage</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Single event type</span>
$.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span.myTooltip'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'mouseover'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// activate tooltip</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Multiple event types (you can call the jQuery live method on the return value from the function)</span>
$.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span.myTooltip'</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mouseover'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// activate tooltip</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mouseout'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// deactivate tooltip</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Also, as a side note, keep in mind that jQuery <code>live</code> <strong>doesn&#8217;t</strong> support space separated events, like <code>bind</code> does.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Will not work.</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span.myTooltip'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mouseover mouseout'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/performance-caveat-with-jquery-selectors-and-live-events/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Scare Your Visitors with this JavaScript Gravatar Plugin</title>
		<link>http://www.zachleat.com/web/scare-your-visitors-with-this-javascript-gravatar-plugin/</link>
		<comments>http://www.zachleat.com/web/scare-your-visitors-with-this-javascript-gravatar-plugin/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 03:47:43 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Gravatar]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=157</guid>
		<description><![CDATA[Here's a use case.  An unregistered visitor visits your blog, and decides that your <strong>content is so good that it merits a comment</strong>!  Congratulations, you've fooled them!  But since they're leaving a comment, why not show them a preview of their gravatar?]]></description>
			<content:encoded><![CDATA[<h2><a href="/javascript/gravatar/index.html">See the Demo</a></h2>
<h2><a href="/javascript/gravatar/jquery.gravatar.js">Download the Source Code</a></h2>
<p><br/><br />
<br/></p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/01/blog-comment.png" alt="Tournology Blog Comment Form" title="blog-comment" width="484" height="266" class="size-full wp-image-158" /></p>
<p>Here&#8217;s a use case.  An unregistered visitor visits your blog, and decides that your <strong>content is so good that it merits a comment</strong>!  Congratulations, you&#8217;ve fooled them!  Now you can <a href="http://www.centernetworks.com/twply-twitter-replies-auction">twply their account details for $1200 on Sitepoint</a>!  Just kidding.  But generally, when you visit a blog&#8217;s commenting section (such as the <a href="http://www.tournology.com/blog/">Tournology Blog</a> shown above), you&#8217;ll see a simple form to authenticate you&#8217;re not a spammer, generally including (among other things) an e-mail address field.</p>
<p><br/><br />
<br/></p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/01/blog-comment-after.png" alt="Tournology Blog Comment Form With Gravatar" title="blog-comment-after" width="484" height="266" class="size-full wp-image-160" /></p>
<p>Well, since they&#8217;re typing their e-mail address, wouldn&#8217;t it be cool if we could <strong>show them their gravatar</strong> right there, inline with the blog comment form?  Well, that&#8217;s now possible with my new <strong><a href="http://www.zachleat.com/javascript/gravatar/jquery.gravatar.js">JavaScript Gravatar Plugin</a></strong>!  It doesn&#8217;t have any server side language dependencies.</p>
<p><br/><br />
<br/></p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/01/gravatar-signup.png" alt="Gravatar Signup Page" title="gravatar-signup" width="483" height="265" class="size-full wp-image-162" /></p>
<p>Hell, <a href="http://en.gravatar.com/">gravatar.com</a> could even use this to <strong>improve the user experience of registering your e-mail account</strong>.  Right now it does a full page refresh and doesn&#8217;t even show you a preview!</p>
<p><br/></p>
<h2><a href="/javascript/gravatar/index.html">See the Demo</a></h2>
<h2><a href="/javascript/gravatar/jquery.gravatar.js">Download the Source Code</a></h2>
<p><br/></p>
<h2>Licensing</h2>
<p>
Licensed under the <a href="http://sam.zoy.org/wtfpl/">WTFPL</a>, as highly recommended by <a href="http://foohack.com/">Isaac Schleuter</a> (<a href="/web/2007/04/05/google-using-yui-grids-css/">see discussion</a>).
</p>
<p><br/></p>
<h2>JavaScript Dependencies:</h2>
<ul>
<li>Requires <a href="http://jquery.com">jQuery</a> (Feel free to port and post a link!)</li>
<li>Requires <a href="http://pajhome.org.uk/crypt/md5/md5.js">md5.js</a></li>
</ul>
<p><br/></p>
<h2>Example Usage:</h2>
<p>Easiest form, onblur of email text input field:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#emailTextField'</span><span style="color: #009900;">&#41;</span>.<span style="color: #000066;">blur</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">after</span><span style="color: #009900;">&#40;</span>$.<span style="color: #660066;">gravatar</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Showing all options, again onblur of email text input field.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#email'</span><span style="color: #009900;">&#41;</span>.<span style="color: #000066;">blur</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>$.<span style="color: #660066;">gravatar</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// integer size: between 1 and 512, default 80 (in pixels)</span>
        size<span style="color: #339933;">:</span> <span style="color: #CC0000;">200</span><span style="color: #339933;">,</span>
        <span style="color: #006600; font-style: italic;">// maximum rating (in order of raunchiness, least to most): g (default), pg, r, x</span>
        rating<span style="color: #339933;">:</span> <span style="color: #3366CC;">'pg'</span><span style="color: #339933;">,</span>
        <span style="color: #006600; font-style: italic;">// url to define a default image (can also be one of: identicon, monsterid, wavatar)</span>
        image<span style="color: #339933;">:</span> <span style="color: #3366CC;">'identicon'</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>Update:</strong> This script has been moved to <a href="http://github.com/zachleat/jQuery-Gravatar">Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/scare-your-visitors-with-this-javascript-gravatar-plugin/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>DOMContentLoaded Inconsistencies (in Browsers and JavaScript Libraries)</title>
		<link>http://www.zachleat.com/web/domcontentloaded-inconsistencies/</link>
		<comments>http://www.zachleat.com/web/domcontentloaded-inconsistencies/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 04:54:24 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[linkedin]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=153</guid>
		<description><![CDATA[We all know the problem, but we may not all call it the same thing: DOMContentLoaded.  Every popular JavaScript library has its own name for the DOMContentLoaded event, and they're all implemented differently.  This, of course, partly due to the fact that web browsers are also inconsistent in their implementations.  Here's a run-down of those inconsistencies.]]></description>
			<content:encoded><![CDATA[<p><strong>Quick Summary</strong></p>
<ul>
<li><em>Prototype and Dojo are the only major JavaScript frameworks that correctly time the DOMContentLoaded inside of an iframe in Internet Explorer.  MooTools comes close and both YUI and jQuery both exhibit incorrect behavior.</em></li>
<li><em>Usually, browsers that have a native DOMContentLoaded event will fire it after both JavaScript and CSS (external script, link tags) have loaded.  But Opera fires prior to CSS link tags loading.</em></li>
</ul>
<p>We all know the problem, but we may not all call it the same thing.  Every popular JavaScript library has its own name for the DOMContentLoaded event.</p>
<table>
<thead>
<tr>
<th>JavaScript Library</th>
<th>Event Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>YUI</td>
<td><a href="http://developer.yahoo.com/yui/docs/YAHOO.util.Event.html#method_onDOMReady">DOMReady</a></td>
</tr>
<tr>
<td>jQuery</td>
<td><a href="http://docs.jquery.com/Events/ready">ready</a></td>
</tr>
<tr>
<td>MooTools</td>
<td><a href="http://mootools.net/docs/Utilities/DomReady">domready</a></td>
</tr>
<tr>
<td>Prototype</td>
<td><a href="http://www.prototypejs.org/api/document/observe">dom:loaded</a></td>
</tr>
<tr>
<td>Dojo</td>
<td><a href="http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.addOnLoad">addOnLoad</a></td>
</tr>
</tbody>
</table>
<p>But the naming scheme isn&#8217;t the only part about this event that&#8217;s inconsistent.  There are a few hacks strewn around the net that have been bastardized (read: modified to the will of library authors) into each individual framework.  These have been posted time and time again, but for post completeness are the following:</p>
<table>
<thead>
<tr>
<th>IE DOMContentLoaded Hack</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code><a href="http://javascript.nwbox.com/IEContentLoaded/">doScroll</a></code> by Diego Perini</td>
<td>Uses a <code>doScroll</code> method call, which will throw an error if the <code>ondocumentready</code> event hasn&#8217;t fired on the <strong>primary document</strong> (take note of the usage of the word primary).  Once <code>doScroll</code> doesn&#8217;t throw an error, it is assumed the DOM has loaded.</td>
</tr>
<tr>
<td><code><a href="http://msdn.microsoft.com/en-us/library/ms536957(VS.85).aspx">onreadystatechange</a></code> and <code><a href="http://msdn.microsoft.com/en-us/library/ms534359.aspx">readyState</a></code></td>
<td><code>onreadystatechange</code> <em>&#8220;fires when the state of the object has changed,&#8221;</em> and changes the <code>readyState</code> property of the object through the following states (not all apply to every type of element): <code>uninitialized</code>, <code>loading</code>, <code>loaded</code>, <code>interactive</code>, and <code>complete</code>.  (source: MSDN) Usually set on the document object, or a script element (as used in the Script Defer method described next.</td>
</tr>
<tr>
<td><a href="http://dean.edwards.name/weblog/2005/09/busted/">Script Defer</a> by Dean Edwards</td>
<td>document.write&#8217;s a script tag with a <code>defer</code> attribute.  Defer will cause the browser to delay execution of the script until the DOM has successfully loaded (using onreadystatechange on the script tag until its readyState is &#8220;complete&#8221;).  Without defer, the browser would execute any script tag immediately.</td>
</tr>
<tr>
<td><a href="http://dean.edwards.name/weblog/2005/09/busted2/">HTC Behavior</a> by Dean Edwards</td>
<td>Much less popular approach using proprietary HTC Behavior files.  Generally avoided due to the addition of an extra HTTP request to the page in order to download the external .htc file.  As a side note, if using this approach, the <code><a href="http://msdn.microsoft.com/en-us/library/ms531021.aspx">"oncontentready"</a></code> event will work better than the <a href="http://msdn.microsoft.com/en-us/library/ms531024.aspx">&#8220;ondocumentready&#8221;</a> event used by Mr. Edwards.</td>
</tr>
<tr>
<td>Ghetto Method</td>
<td>Of course, the easiest way to do it is to put a script tag right above your ending <code>&lt;/body&gt;</code> tag that triggers the event manually.  This really only works if you have full control of the content, and isn&#8217;t really a library solution.  Worth noting though.</td>
</tr>
</tbody>
</table>
<p><a href='http://zachleat.com/Projects/domcontentloaded/'><img src="http://www.zachleat.com/web/wp-content/uploads/2008/12/domcontentloaded.png" alt="Benchmark for Library DOMContentLoaded Implementations" title="domcontentloaded" width="500" height="224" class="aligncenter size-full wp-image-154" /><br/><br />
<em>Benchmark for Library DOMContentLoaded Implementations</em></a></p>
<p>I created a benchmark trying to answer the simple question: when does the DOMContentLoaded event fire?  Each implementation has different effects, especially in iframes and with stylesheets.</p>
<h1>What Works</h1>
<p>The Internet Explorer hacks presented above are reliable when used on a standalone document (not inside of an iframe).</p>
<p>Mozilla Firefox, Safari, Chrome, and Opera all contain a native DOMContentLoaded event that each framework uses to consistently fire at the correct time.  So, it isn&#8217;t even worth summarizing the results for tests in every browser with a native DOMContentLoaded event, except Opera.  Opera took a different design approach with their DOMContentLoaded event (certainly not wrong, just different), which we&#8217;ll analyze below.</p>
<h1>Internet Explorer inside an Iframe</h1>
<p><em>All libraries below did no branching based on IE versions, all used the same method for IE6, IE7, or IE8.  I performed no tests in IE8, however.</em></p>
<table>
<thead>
<tr>
<th rowspan="2">JavaScript Library</th>
<th rowspan="2">Method</th>
<th colspan="4">Waited for:</th>
</tr>
<tr>
<th>&lt;body&gt; &lt;script&gt;</th>
<th>&lt;head&gt; &lt;script&gt;</th>
<th>&lt;link&gt; CSS</th>
<th>&lt;img&gt;</th>
</tr>
</thead>
<tbody>
<tr>
<td>YUI 2.6.0</td>
<td>doScroll, setTimeout</td>
<td colspan="4">Incorrect: Fires almost immediately (~20ms)</td>
</tr>
<tr>
<td>jQuery 1.2.6</td>
<td>window onload</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td>Prototype 1.6.0.3</td>
<td>Script Defer</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>MooTools 1.2.1</td>
<td>doScroll and set innerHTML, setTimeout</td>
<td>*</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>Dojo 1.2.0</td>
<td>Script Defer</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td><a href="http://javascript.nwbox.com/IEContentLoaded/">IEContentLoaded</a></td>
<td>doScroll, document.onreadystatechange</td>
<td colspan="4">Incorrect: JavaScript error.</td>
</tr>
<tr>
<td><a href="http://www.thefutureoftheweb.com/blog/adddomloadevent">addDOMLoadEvent</a></td>
<td>Script Defer</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
</tbody>
</table>
<p>* <em>For some reason, not only did the MooTools library not wait for the body script to trigger DOMContentLoaded, the body script never executed at all.</em></p>
<p>The <strong>most important takeaway</strong> from this blog post are the successful methods of faking DOMContentLoaded in Internet Explorer.  The obvious <strong>library winners here are Prototype and Dojo</strong>, with the addDOMLoadEvent script also exhibiting correct behavior.  MooTools is a close runner up, and I would be interested to find out why it didn&#8217;t execute the body script (that&#8217;s left for another day, or perhaps a generous commenter).</p>
<h1>Opera 9.6</h1>
<table>
<thead>
<tr>
<th rowspan="2">JavaScript Library</th>
<th rowspan="2">Method</th>
<th colspan="4">Waited for:</th>
</tr>
<tr>
<th>&lt;body&gt; &lt;script&gt;</th>
<th>&lt;head&gt; &lt;script&gt;</th>
<th>&lt;link&gt; CSS</th>
<th>&lt;img&gt;</th>
</tr>
</thead>
<tbody>
<tr>
<td>YUI 2.6.0</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>jQuery 1.2.6</td>
<td>Native DOMContentLoaded + Code to wait for Stylesheets</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>Prototype 1.6.0.3</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>MooTools 1.2.1</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Dojo 1.2.0</td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td><a href="http://javascript.nwbox.com/IEContentLoaded/">IEContentLoaded</a></td>
<td>N/A to Opera</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td><a href="http://www.thefutureoftheweb.com/blog/adddomloadevent">addDOMLoadEvent</a></td>
<td>Native DOMContentLoaded</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>As you can see above, <strong>Opera typically will fire DOMContentLoaded prior to stylesheets loading</strong> successfully (ignoring the jQuery specific code to provide consistency cross-browser)</p>
<p><em>Thanks to <a href="http://www.adamkoch.com/">Adam Koch</a> for first pointing me in the direction of jQuery in an iframe ignoring DOMContentLoaded in IE.</em></p>
<p><strong>Update:</strong> There is an open ticket for <a href="http://sourceforge.net/tracker/index.php?func=detail&#038;aid=2008289&#038;group_id=165715&#038;atid=836476">YUI on Sourceforge</a>, and I&#8217;ve opened a ticket for <a href="http://dev.jquery.com/ticket/3693">jQuery on their Trac site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/domcontentloaded-inconsistencies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Emulating onhashchange without setInterval</title>
		<link>http://www.zachleat.com/web/onhashchange-without-setinterval/</link>
		<comments>http://www.zachleat.com/web/onhashchange-without-setinterval/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 06:00:13 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Back Button]]></category>
		<category><![CDATA[History]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=143</guid>
		<description><![CDATA[There is one limitation that all of the major JavaScript browser history management plugins have to hack around: How to tell when there is a change to the location.hash? Sure, you can tell when you&#8217;re modifying the hash yourself, but what if the user hits the back/forward button? YUI&#8217;s History component and Really Simple History [...]]]></description>
			<content:encoded><![CDATA[<p>There is one limitation that all of the major JavaScript browser history management plugins have to hack around:  How to tell when there is a change to the <code>location.hash</code>?  Sure, you can tell when you&#8217;re modifying the hash yourself, but what if the user hits the back/forward button?</p>
<p><a href="http://developer.yahoo.com/yui/history/">YUI&#8217;s History component</a> and Really Simple History both use setInterval with an internal variable to compare and find changes.  But this isn&#8217;t really an optimal solution.  As proper front end engineers, we should avoid timeouts as much as possible.  Internet Explorer 8 will have an <a href="http://msdn.microsoft.com/en-us/library/cc288209(VS.85).aspx">onhashchange event</a> that clients will be able to subscribe to.  That will be nice.  But surely, a cross browser solution without the use of setInterval exists.</p>
<p><strong>Look, a cross browser solution without the use of setInterval:</strong></p>
<ol>
<li>On initialization, we load an iframe onto the page that is positioned absolutely at -500px,-500px so the user can&#8217;t see it. It is a skeleton page that only needs cross browser code to add an &#8220;<code>onscroll</code>&#8221; event, and to be able to calculate the scrolled position of the iframe itself.  For my example, I use jQuery and the dimensions plugin to accomplish this, but it could easily be trimmed down to only the bare essentials (or ported to a different library).</li>
<li>To add an AJAX history entry into the browser&#8217;s history under an assigned hash string, we first add a <code>&lt;a name="hashString"&gt;hashString&lt;/a&gt;</code> to the <code>&lt;body&gt;</code> tag of the iframe.  Using css to increase the size of the a tag proportional to the iframe&#8217;s height, we can guarantee scrolling will happen.</li>
<li>Then, we change the <code>location.hash</code> of the iframe to point to that <code>&lt;a&gt;</code> tag.  This will scroll the iframe to the content, and create a new entry in the browser&#8217;s <code>history</code> object.</li>
<li>Inside the iframe, we have our <code>onscroll</code> event that fires when the scrolling in the previous step took place.  (Minor IE-related workaround: The browser&#8217;s <code>history</code> object is changed, but the hash property doesn&#8217;t when attempting to read it later.  Instead, we find the <code>&lt;a&gt;</code> that matches up with the scrollY/pageOffsetY property inside of the iframe, and retrieve the matching hash from the <code>&lt;a&gt;</code> tag.)</li>
</ol>
<p>The nice thing about this approach is that you don&#8217;t even need a history manager anymore.  This little iframe will do all of your dirty work for you.  And it will even maintain your history alongside any other iframe browsing on the page.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li>Can serve as back button support and full AJAX history manager.</li>
<li>Page Weight: the test page and iframe HTML files together weigh in at 2.76 KB.  That includes the non-jQuery JavaScript needed to do everything.</li>
<li>Cross browser: Tested in FF3, IE7, IE6, Opera 9.5, (not Safari &#8212; see below)</li>
</ul>
<p><strong>Limitations:</strong></p>
<ul>
<li>No bookmarking support.  We aren&#8217;t changing the top hash, we&#8217;re changing the iframe hash, so these aren&#8217;t bookmarkable.</li>
</ul>
<p><strong>Sample Example:</strong></p>
<ul>
<li>
<a href="http://www.zachleat.com/Projects/history/">My Test Page</a></li>
<li><a href="http://www.zachleat.com/Projects/history/history.zip">Download the test page (2 HTML files, and jQuery 1.2.6 and dimensions)</a></li>
</ul>
<p><strong>Update</strong>: Given time for more rigorous testing, it doesn&#8217;t look like Safari supports this approach.  So, until WebKit fixes <a href="https://bugs.webkit.org/show_bug.cgi?id=9166">#9166</a>, we&#8217;ll have to stick to timers in Safari.  A more pragmatic programmer than I might hack around this approach by exploiting <a href="https://bugs.webkit.org/show_bug.cgi?id=19202">#19202</a>, but that certainly wouldn&#8217;t be a long term solution.  I&#8217;ve also updated the test page above, at <a href="http://dean.edwards.name/">Dean Edwards</a> humble request, to support dynamic client size text size changes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/onhashchange-without-setinterval/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Selecting XML Nodes with JavaScript (Peril of getElementsByTagName)</title>
		<link>http://www.zachleat.com/web/selecting-xml-with-javascript/</link>
		<comments>http://www.zachleat.com/web/selecting-xml-with-javascript/#comments</comments>
		<pubDate>Sat, 10 May 2008 23:27:02 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=132</guid>
		<description><![CDATA[Parsing XML in the browser can be a tricky beast.  There are many different wrong ways to do it, which can leave you cold and naked in a snowstorm if you're not careful.  So, let's put on the metaphorical electric one-sie of standards based code and let the power of Edison heat our JavaScript code like the innards of a <a href="http://starwars.wikia.com/wiki/Tauntaun">tauntaun</a>.]]></description>
			<content:encoded><![CDATA[<p><em>There are two popular camps for ajax data formats right now: XML and JSON.  Both have their (dis-)advantages.  The purpose of this article is  to show you how to effectively parse XML in the browser.</em></p>
<h3>Super Fast Beginner&#8217;s Primer</h3>
<ul>
<li>Case 1: <strong>Node</strong> (or un-namespaced node, null-namespaced node): a node without a prefix, such as child here:<br />
<code>&lt;child/&gt;</code></li>
<li>Case 2: <strong>Default namespaced node</strong>: a node without a prefix, but a parent node (or itself) has a xmlns attribute, like both root and child here:<br />
<code>&lt;root xmlns="http://example.com/"&gt;&lt;child/&gt;&lt;/root&gt;</code></li>
<li>Case 3: <strong>Namespaced node</strong>: a node with a prefix, and a parent node (or itself) declaring a xmlns with that prefix attached, like both child and root here:<br />
<code>&lt;prefix:root prefix:xmlns="http://example.com/"&gt;&lt;prefix:child/&gt;&lt;/root&gt;</code></li>
</ul>
<h3>/End Primer</h3>
<p>Parsing XML in the browser can be a tricky beast.  There are many different wrong ways to do it, which can leave you cold and naked in a snowstorm if you&#8217;re not careful.  So, let&#8217;s put on the metaphorical electric one-sie of standards based code and let the power of Edison heat our JavaScript code like the innards of a <a href="http://starwars.wikia.com/wiki/Tauntaun">tauntaun</a>.</p>
<p>If there is one thing you can take away from this article, its that the problems with XML in JavaScript have already been solved, and there is library code out there to do the job for you.  But libraries aren&#8217;t a substitute for knowledge (abstraction is a dangerous thing during education), so let&#8217;s learn <strong>why</strong> these problems are occurring so we can wrinkle our gray matter and increase our productivity at the same time.</p>
<h2>Use Cases</h2>
<p>These are the main use cases that takes place when selecting a node inside of an XML document:</p>
<ol>
<li><strong>Case 1</strong>: Selecting un-namespaced nodes (or nodes in the null namespace):

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;root<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;child</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This one is easy.  If you can guarantee that your XML will never have any namespaces, you&#8217;re home free.  Take your get out of jail free card and run for the hills.  Using this assumption, you can query nodes inside of your XML Document object using nothing other than <code>getElementsByTagName()</code>.  Lucky bastard.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// assume oDocEl is the documentElement inside of an XML Document </span>
<span style="color: #003366; font-weight: bold;">var</span> correctForCase1 <span style="color: #339933;">=</span> oDocEl.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'child'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li><strong>Case 2</strong>: Selecting default namespaced nodes:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;root</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://example.com/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;child</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Tread lightly, this is about to get serious.  In most cases, historically I had thought that using the solution described for Case 1 would be sufficient in this case.  I had learned awhile back that Internet Explorer treats node names (including namespace prefix and local name together) as one string.  So, the method for Case 1 should work for Internet Explorer, especially in the case of node sans prefix.  In Firefox, you&#8217;d have to use getElementsByTagNS(), but that would be just a simple wrapper.</p>
<p>Then I met an Internet Explorer exception.  The only unique thing about this installation of Internet Explorer 7 was that it had MSXML 6 installed, when all the other computers I had tested on were using MSXML 3.  The obvious conclusion here is that MSXML 6 won&#8217;t select child nodes for Case 2.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> incorrectForCase2 <span style="color: #339933;">=</span> oDocEl.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'child'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Here&#8217;s the right way to select nodes for Case 2.  Fair warning, to keep the code examples here simple, this solution requires Sarissa (sarissa.js and sarissa_ieemu_xpath.js) to be included on the page prior to usage.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// assume oDoc is an XML Document object.</span>
oDoc.<span style="color: #660066;">setProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SelectionNamespaces&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;xmlns:whatever='http://example.com/'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oDocEl <span style="color: #339933;">=</span> oDoc.<span style="color: #660066;">documentElement</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> correctForCase2A <span style="color: #339933;">=</span> oDocEl.<span style="color: #660066;">selectNodes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'whatever:child'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> correctForCase2B <span style="color: #339933;">=</span> oDocEl.<span style="color: #660066;">selectSingleNode</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'whatever:child'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Note how we&#8217;ve mapped what was the default namespace (without a prefix) to be a namespace WITH a prefix during the node selection.</p>
<p>It should be noted that when the resultant XML has a namespace attached (Case 2 and 3), Firefox works fine using getElementsByTagNameNS.  IE doesn&#8217;t include support for that method, however, so we&#8217;re forced to find a more complete solution.
</li>
<li><strong>Case 3</strong>: Select a non-default namespaced node:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;root</span> <span style="color: #000066;">prefix:xmlns</span>=<span style="color: #ff0000;">&quot;http://example.com/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;prefix:child</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/root<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As I mentioned in Case 2, normally (pre-MSXML 6), you&#8217;d be able to perform a <code>getElementsByTagName('prefix:child')</code> in IE and use getElementsByTagNameNS in Firefox as usual.  But that has changed now.  We need to set up the SelectionNamespaces property for IE, and we&#8217;ll use Sarissa to take it cross-browser for us.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// assume oDoc is an XML Document object.</span>
oDoc.<span style="color: #660066;">setProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SelectionNamespaces&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;xmlns:whatever='http://example.com/'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oDocEl <span style="color: #339933;">=</span> oDoc.<span style="color: #660066;">documentElement</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> correctForCase3A <span style="color: #339933;">=</span> oDocEl.<span style="color: #660066;">selectNodes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'whatever:child'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> correctForCase3B <span style="color: #339933;">=</span> oDocEl.<span style="color: #660066;">selectSingleNode</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'whatever:child'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Note, this is the same code as Case 2 (which is a good thing)</span></pre></div></div>

<p>Note that we did <em>not</em> have to use the same prefix that was defined by the result XML.  We can map it to whatever we want (literally).
</li>
</ol>
<h2>Why is this important?</h2>
<p>Because most libraries don&#8217;t handle Case 2 and Case 3, which are important parts of XML.  Here&#8217;s some code straight from YUI 2.5.1 (DataSource component):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Line 1394</span>
<span style="color: #003366; font-weight: bold;">var</span> xmlNode <span style="color: #339933;">=</span> result.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>xmlNode <span style="color: #339933;">&amp;&amp;</span> xmlNode.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> xmlNode.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">firstChild</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    data <span style="color: #339933;">=</span> xmlNode.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">nodeValue</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
       data <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Notice how they just do getElementsByTagName.  For shame :(  jQuery doesn&#8217;t handle Case 2 or Case 3 either.  (Proof is an exercise to the reader :P)  So, if you have XML data sources with namespaces, it would do you well to use the solution presented in this article, or you&#8217;re going to have headaches later.</p>
<h2>Springer&#8217;s Final Word</h2>
<p>Don&#8217;t use getElementsByTagName.  If you do, PLEASE include a note saying that your code isn&#8217;t going to support namespaced XML.  Branch your selection code to check if Sarissa has been included on the page, and use Sarissa for namespaced XML if it&#8217;s there.  It&#8217;s not fun to be pidgin-holed into the simplest case of XML.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/selecting-xml-with-javascript/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Javascript Objects are NOT JSON</title>
		<link>http://www.zachleat.com/web/javascript-objects-are-not-json/</link>
		<comments>http://www.zachleat.com/web/javascript-objects-are-not-json/#comments</comments>
		<pubDate>Sat, 10 May 2008 04:47:55 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=134</guid>
		<description><![CDATA[The headline should more accurately read &#8220;Javascript Objects are not necessarily JSON.&#8221; But that waters it down a bit, don&#8217;t you think? I know this has been posted a few times before, but this is not something I knew until recently, and after learning it, have noticed quite a few other people doing it wrong [...]]]></description>
			<content:encoded><![CDATA[<p><em>The headline should more accurately read &#8220;Javascript Objects are not <strong>necessarily</strong> JSON.&#8221;  But that waters it down a bit, don&#8217;t you think?</em></p>
<p>I know this has been posted a few times before, but this is not something I knew until recently, and after learning it, have noticed quite a few other people doing it wrong as well.  So, to risk adding another reverb to the echo chamber, I&#8217;ll post a link to a <a href="http://www.thefutureoftheweb.com/blog/json-is-not-just-object-notation">good explanation</a> by Jesse Skinner on the specifics of the JSON specification.</p>
<p>The main point here is that <strong>all object keys and strings in JSON must have double quotes.</strong>  I encourage you to look through the <a href="http://json.org/">train track specification</a> to verify for yourself.</p>
<p>If you try to use Captain <a href="http://www.json.org/json2.js">Crockford&#8217;s JSON Parser</a>, it won&#8217;t parse your string with single quotes or (un/single)-quoted object keys.  His parser has a nice regex checker built-in (and a walker callback to let you parse date strings into Date() objects).  It&#8217;s a good way to verify that external data, or a data source not under your control, is safe to eval and use in your own code.</p>
<p>Here are a few quick examples:</p>
<h2>Valid JSON</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;myKey&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;myString&quot;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Don&#8217;t use single quotes.  Don&#8217;t use unquoted object keys.</p>
<h2>Invalid JSON</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>myKey<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;myString&quot;</span><span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'myKey'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'myString'</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Credits to Jonathan Snook for the <a href="http://www.snook.ca/archives/javascript/json_is_a_subse/">initial write-up</a> and Crockford for formalizing JSON.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/javascript-objects-are-not-json/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

