<?xml version="1.0" encoding="UTF-8"?>
<rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Web 3.0, 6 Bladed Razors, 7 Minute Abs</title>
	
	<link>http://www.zachleat.com/web</link>
	<description />
	<lastBuildDate>Fri, 30 Jul 2010 01:59:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/zachleat" /><feedburner:info uri="zachleat" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Faking Onload for Link Elements</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/sZ5L3aUgaFM/</link>
		<comments>http://www.zachleat.com/web/2010/07/29/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[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 it block the host page while loading), and whether or not [...]]]></description>
			<content:encoded><![CDATA[<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</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>This is 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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/sZ5L3aUgaFM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/07/29/load-css-dynamically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/07/29/load-css-dynamically/</feedburner:origLink></item>
		<item>
		<title>ALARMd is now on Github</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/frGvydtOUp4/</link>
		<comments>http://www.zachleat.com/web/2010/07/21/alarmd-is-now-on-github/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 01:47:40 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Alarmd]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Github]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=726</guid>
		<description><![CDATA[In an effort to mindlessly copy what everyone else on the internet is doing keep current on the latest and greatest Source Code Management tools, I decided that it would be good practice to move my open source project ALARMd (as seen on Lifehacker) from Google Code to Github. Feel free to fork/contribute at your [...]]]></description>
			<content:encoded><![CDATA[<p>In an effort to <del datetime="2010-07-22T00:54:05+00:00">mindlessly copy what everyone else on the internet is doing</del> keep current on the latest and greatest Source Code Management tools, I decided that it would be good practice to move my open source project ALARMd (as seen on <a href="http://lifehacker.com/271043/wake-up-to-a-youtube-video-with-alarmd">Lifehacker</a>) from <a href="/web/2008/10/08/alarmd-is-a-google-code-project/">Google Code</a> to Github.</p>
<p>Feel free to fork/contribute at your leisure.<br />
<a href="http://github.com/zachleat/ALARMd">http://github.com/zachleat/ALARMd</a></p>
<p>If you&#8217;re new, you can check out <a href="http://www.alarmd.com/">ALARMd.com</a> to see what I&#8217;m talking about.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/frGvydtOUp4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/07/21/alarmd-is-now-on-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/07/21/alarmd-is-now-on-github/</feedburner:origLink></item>
		<item>
		<title>Maiden Voyage of the DOM Sailbloat</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/GdM93MRqunQ/</link>
		<comments>http://www.zachleat.com/web/2010/07/19/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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/GdM93MRqunQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/07/19/dom-sailbloat/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/07/19/dom-sailbloat/</feedburner:origLink></item>
		<item>
		<title>A Race Against Time Pickers</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/Cd2v2uXeAMQ/</link>
		<comments>http://www.zachleat.com/web/2010/06/08/a-race-against-time-pickers/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 23:57:25 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Interface Design]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=633</guid>
		<description><![CDATA[The Date Picker component is one of the most popular user interface components on the web today. Its operation is very simple: focus into a field (sometimes a click on a dedicated calendar button is required) intended to contain a specific date and an on-screen calendar will be shown next to the form field, allowing [...]]]></description>
			<content:encoded><![CDATA[<p>The Date Picker component is one of the most popular user interface components on the web today.  Its operation is very simple: focus into a field (sometimes a click on a dedicated calendar button is required) intended to contain a specific date and an on-screen calendar will be shown next to the form field, allowing the user to click on a specific date to populate the form field.</p>
<p><a href="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-01-at-8.57.37-PM.png"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-01-at-8.57.37-PM.png" alt="" title="Date Picker Component" width="314" height="235" class="alignnone size-full wp-image-640" /></a></p>
<p>Date Pickers are helpful components that are useful for a couple of reasons:</p>
<ol>
<li>They allow you to easily <strong>map an existing real-world mental model</strong> (the Calendar) to form input (a text field). This provides <strong>additional context</strong> beyond what the simple string value of a date represents: days of the week, Calendar month labels, leap year information.</li>
<li>They allow for more usable and actionable data restrictions and error feedback.  Want the user to select a weekday?  Just show them on the calendar which days are available.</li>
<li>Visual cue as to what the form field&#8217;s data format should be.  If a calendar icon is next to the form field, it becomes very obvious what kind of data the user should put into the field.</li>
</ol>
<p>Now, the last two reasons are all well and good, but carry no intrinsic incentive for the user to actually click on and use the Date Picker component.  <strong>The first reason is what actually motivates a user</strong> to bring up the Date Picker and select a date on it.</p>
<p>Now, consider the following Time Picker component, popularized by <a href="http://ejohn.org/blog/picking-time/">a John Resig blog post</a>:<br />
<a href="http://haineault.com/media/jquery/ui-timepickr/page/"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-06-at-3.28.22-PM.png" alt="" title="Time Picker Example #2" width="462" height="128" class="alignnone size-full wp-image-642" /></a></p>
<p>Comparing to the Date Picker component above, one could easily make the argument that it offers little to <strong>no incentive over simple keyboard input</strong>.  It offers no additional context, extra data, or an existing physical mental model for the user to associate with.  The only advantage it might offer is an easy calculator for those unfamiliar with 24-hour (military) time.  I would argue that placing the AM/PM selection at the beginning of the selection creates a reversal of the closest established mental model a person typically uses to represent a time: the digital clock (hours, minutes, seconds, and AM/PM at the end).</p>
<div style="font-style:italic; font-size: 86%; width: 400px; margin: auto;">
Here&#8217;s a sampling of some other time picker implementations:</p>
<p><a href="http://pttimeselect.sourceforge.net/example/index.html"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/pttimeselect.png" alt="" title="Another Time Picker" width="271" height="239" class="alignnone size-full wp-image-670" /></a><br />
This implementation is very similar to the first example, just organized differently.  We can do better.</p>
<p><a href="http://www.pit-r.de/timepicker/demo/pickerDemo.htm"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/picker.png" alt="" title="Yet Another Time Picker, Two Analog Clocks, one for hours and one for minutes" width="294" height="203" class="alignleft size-full wp-image-674" /></a></p>
<div style="clear: both"></div>
<p>Reading an analog clock isn&#8217;t the problem.  When we think of time, we start with numeric representations of the hours and minutes.  The first thing that pops into the average person&#8217;s head when they hear &#8220;6:00 PM&#8221; probably isn&#8217;t: the little hand on the 6 and the big hand on the 12.  The analog clock representation is <strong>a mental hurdle</strong>.</p>
<p><a href="http://www.zachleat.com/web/wp-content/uploads/2010/06/timedatepicker.png"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/timedatepicker.png" alt="" title="A simple time picker" width="108" height="230" class="alignnone size-full wp-image-679" /></a><br />
Now we&#8217;re getting closer.  The user selects a full representation of the time, not just the last piece of the puzzle.  I like the intuitive and simple organization of this time picker.  You know immediately what you&#8217;re selecting.  I think we can organize the times a little bit better though, give them a visual hierarchy.</p>
<p><a href="http://www.jnathanson.com/index.cfm?page=jquery/clockpick/ClockPick#demog"><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/clockpick.png" alt="" title="Yet Another Time Picker" width="146" height="123" class="alignnone size-full wp-image-672" /></a><br />
This picker represents more of the spirit of what we&#8217;re looking for.  It shows a simple list of the hourly options and progressively discloses the minute selections.  I think switching to a single column layout would be more intuitive for keyboard navigation (combining the above two implementations into one super-component) and would do well with larger click targets.
</div>
<p>These implementation examples speak to a larger trend of front end engineers that concentrate too much on code optimization and cross browser compatibility, and <strong>not enough on usability and user driven design</strong>.  It&#8217;s an easy trap to fall prey to, but one we must be wary of.  A Time Picker might offer benefit in terms of data restriction (e.g.: select an hour in the range of a normal workday), but it does very little for the efficiency and usability of data entry.  So, before you start putting Time Pickers on all of your forms, make sure the Time Picker you add represents something like this:</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/ISPKA4134_large.jpg" alt="" title="Digital Clock" width="320" height="320" class="alignnone size-full wp-image-691" /></p>
<p>and not this:</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/06/Screen-shot-2010-06-06-at-4.04.50-PM.png" alt="" title="Onscreen Keyboard" width="489" height="176" class="alignnone size-full wp-image-646" /></p>
<ol style="font-size:70%; font-style:italic;">
Image Sources:</p>
<li><a href="http://www.tesora.com.au/Digibell_Retro_Alarm_Clock_.htm">tesora.com.au</a></li>
<li><a href="http://www.codeproject.com/">codeproject.com</a></li>
</ol>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/Cd2v2uXeAMQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/06/08/a-race-against-time-pickers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/06/08/a-race-against-time-pickers/</feedburner:origLink></item>
		<item>
		<title>Point, Charset, Match: Character Encoding in JavaScript</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/mzdY3e9IEWc/</link>
		<comments>http://www.zachleat.com/web/2010/03/26/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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/mzdY3e9IEWc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/03/26/charset/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/03/26/charset/</feedburner:origLink></item>
		<item>
		<title>Internet Explorer Array.sort Unreliable</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/f7XNDo_3qEY/</link>
		<comments>http://www.zachleat.com/web/2010/02/24/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>
</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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/f7XNDo_3qEY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/02/24/array-sort/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/02/24/array-sort/</feedburner:origLink></item>
		<item>
		<title>If the Menu Fitts, We Must Acquit</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/3OMRuVj5S_4/</link>
		<comments>http://www.zachleat.com/web/2010/02/15/if-the-menu-fitts-we-must-acquit/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 05:52:14 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Interface Design]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Fitts's Law]]></category>
		<category><![CDATA[Gmail]]></category>
		<category><![CDATA[Google Reader]]></category>
		<category><![CDATA[MacOS]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=542</guid>
		<description><![CDATA[One of the first things you&#8217;ll learn when diving into a self-taught course on usability is the hugely popular Fitts&#8217;s Law. In a nutshell, Fitts&#8217;s Law tries to predict the time needed to move to a &#8220;target area&#8221; (usually a link, menu, button, or form element) as a function of the distance to the element [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first things you&#8217;ll learn when diving into a self-taught course on usability is the hugely popular Fitts&#8217;s Law.  In a nutshell, Fitts&#8217;s Law tries to predict the time needed to move to a &#8220;target area&#8221; (usually a link, menu, button, or form element) as a function of the distance to the element and its size.  <strong>The bigger/closer the element, the faster a user can move to it.</strong></p>
<p>Now, upon discovering myself a newly minted Mac OS convert from the hugely popular World of Windows, I quickly discovered that the application menus (File, Edit, etc) were one of the glaring differences I&#8217;d have to adjust to.  Mac OS had all menus separated from the application window, all the way at the top of the screen.  Coming from the Windows environment, this seemed unintuitive.  But after reading more about Fitts&#8217;s Law, I discovered the reasoning: the <a href="http://www.codinghorror.com/blog/2006/08/fitts-law-and-infinite-width.html">edges of the screen are treated as an infinite height or width</a>!  Which is just a way of modifying the Fitts&#8217;s Law to say: <strong>the easiest things to click on are at the edges of the screen.</strong>  That&#8217;s why the close icon or the Start Menu is so easy to access on Windows, and <a href="http://www.asktog.com/basics/firstPrinciples.html#fittsLaw">why the Application Menu is at the top of the screen in Mac OS</a>.</p>
<p>We know about Fitts&#8217;s Law, but <strong>why aren&#8217;t we applying it to our web applications?</strong>  Why aren&#8217;t we using the power of infinite height/width to help out on our designs?  It seems like this crucial usability law has been overlooked on the web, and without good reason. Let&#8217;s look at a few applications that get it wrong (of course, in my humble opinion).</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/02/Screen-shot-2010-02-15-at-11.08.15-PM.png" alt="WordPress Admin Menu" title="Screen shot 2010-02-15 at 11.08.15 PM" width="174" height="307" class="alignleft size-full wp-image-550"/><img src="http://www.zachleat.com/web/wp-content/uploads/2010/02/Screen-shot-2010-02-15-at-11.12.57-PM.png" alt="Google Mail Menu" title="Screen shot 2010-02-15 at 11.12.57 PM" width="176" height="251" class="alignleft size-full wp-image-552"/><img src="http://www.zachleat.com/web/wp-content/uploads/2010/02/Screen-shot-2010-02-15-at-11.09.16-PM.png" alt="Google Reader Menu" title="Screen shot 2010-02-15 at 11.09.16 PM" width="192" height="367" class="alignleft size-full wp-image-551" /></p>
<div style="clear: left"></div>
<p>All of these screenshots were taken from 100% width designs, with no real reason not to incorporate the ideas behind Fitts&#8217;s Law into the menuing system.  At first glance when I brought up Google Reader, I was excited.  The hover behavior appeared when the mouse cursor was positioned at the very far left of the screen, but was disappointed to discover that the although the hover background color had changed, the entire hover target was not clickable.</p>
<p>Naturally, I decided to make a test of my own, to test which web browsers allowed <em>Fitts&#8217;s Law Menus</em>.  The test case encompassed both left and bottom aligned menus, for completeness.  A top menu was excluded, given that the top of the screen is reserved for browser chrome or application menuing.  A right menu was also excluded as the right portion of the screen is reserved for the page scrollbar (which is the easiest scrollbar to manipulate with your mouse, per the same rules).</p>
<p>Also, on the Mac OS 10.6 and Windows XP operating systems, a <em>Fitts&#8217;s Law Menu</em> at the bottom of the screen is not possible, given that the Dock and Taskbar in these operating systems occupy at least a 4 pixel trough of the bottom-most space on the monitor, even as a hover target in &#8220;auto-hide&#8221; mode.  <strong>Everyone is fighting over these crucial and very useful edge pixels.</strong></p>
<p>To test whether or not this behavior is working correctly, <strong>maximize your browser window</strong> and <strong>move the cursor as far left on the screen as possible</strong>, but still over the menu.  If the links are still clickable, congratulations, your browser works!</p>
<h2><a href="/test/fittmenu/">View the Demo / Test Page for the Fitts&#8217;s Law Menu</a></h2>
<h2>Compatibility Table</h2>
<style type="text/css"> 
#compatibility td { font-family: Verdana; }
#compatibility td.yes { background-color: #00882D; color: #fff; }
#compatibility td.no { background-color: #CB000F; color: #fff; }
#compatibility td.emulate { background-color: #40A662; color: #fff; }</p>
</style>
<table id="compatibility">
<thead>
<tr>
<th>Browser</th>
<th>Operating System</th>
<th>Left Menu</th>
<th>Bottom Menu</th>
<th>Status Bar</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
<tr>
<td>Internet Explorer 8</td>
<td>Windows XP</td>
<td class="no">no</td>
<td class="no">no</td>
<td>yes</td>
<td>IE8 has a small 3 pixel border on the left and right of each window.</td>
</tr>
<tr>
<td>Internet Explorer 7</td>
<td>Windows XP</td>
<td class="no">no</td>
<td class="no">no</td>
<td>yes</td>
<td>IE7 has a small 3 pixel border on the left and right of each window.</td>
</tr>
<tr>
<td>Internet Explorer 6</td>
<td>Windows XP</td>
<td class="no">no</td>
<td class="no">no</td>
<td>yes</td>
<td>IE6 has a small 3 pixel border on the left and right of each window.</td>
</tr>
<tr>
<td>Google Chrome</td>
<td>Windows XP and Mac OS 10.6</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td>no</td>
<td></td>
</tr>
<tr>
<td>Mozilla Firefox 3.5 and 3.6</td>
<td>Windows XP and Mac OS 10.6</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td>yes</td>
<td></td>
</tr>
<tr>
<td>Safari 4.0.4</td>
<td>Windows XP and Mac OS 10.6</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td>no</td>
<td></td>
</tr>
</tbody>
</table>
<p><em>The full screen mode of each individual browser was considered outside the scope of this study.</em></p>
<h2>Conclusion</h2>
<p>We should stand on the shoulders of giants and reuse the usability studies already completed on software that has gone before us.  The left side of the browser window is the best place to utilize Fitts&#8217;s Law, and we should move our left-aligned menus on fluid width designs to occupy the space flush with the window&#8217;s edge to increase the speed at which those menus will be accessible by users.  Having an infinite width menu is a big click target to hit.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/3OMRuVj5S_4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/02/15/if-the-menu-fitts-we-must-acquit/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/02/15/if-the-menu-fitts-we-must-acquit/</feedburner:origLink></item>
		<item>
		<title>CSS 3 Text: A Tale of writing-mode Woe</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/d31mHxT2cnY/</link>
		<comments>http://www.zachleat.com/web/2010/02/12/css3-text-writing-mode/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 04:45:54 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web Browsers]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=496</guid>
		<description><![CDATA[After reading an interesting article on using the writing-mode CSS property to display vertical text (I&#8217;m always interested in how to abuse what browsers currently support into something new and exciting), I decided to look into this writing-mode property and see what opportunities it might present. Generally when exploring a development opportunity, I tend to [...]]]></description>
			<content:encoded><![CDATA[<p>After reading an interesting article on using the <a href="http://www.thecssninja.com/css/real-text-rotation-with-css">writing-mode CSS property</a> to display vertical text (I&#8217;m always interested in how to abuse what browsers currently support into something new and exciting), I decided to look into this <code>writing-mode</code> property and see what opportunities it might present.</p>
<p>Generally when exploring a development opportunity, I tend to prioritize my adventures towards things that are supported in Internet Explorer first.  This often has the biggest cross-browser payoff, since the other browser vendors tend to have a quicker draw than the Microsoft Team.  However, surprisingly enough, this <code>writing-mode</code> study proved the opposite to be true.  It seems very interesting that Microsoft has decided to implement a portion of the CSS 3 specification, given its general stance of moving slower than an iceberg to avoid &#8220;breaking the web.&#8221;  But I, for one, welcome our new choose-your-own-adventure standards loving overlords.</p>
<p>As far as my tests go, the only browser to support the <code><a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#writing-mode">writing-mode</a></code> property at all is Internet Explorer, which was very surprising.  At it&#8217;s heart, though, <code>writing-mode</code> is just shorthand for two other properties: <code><a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#direction">direction</a></code> and <code><a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#block-progression">block-progression</a></code>.  Luckily, <strong>Firefox, Safari, Chrome and IE back through at least version 6 support the <code><a href="https://developer.mozilla.org/en/CSS/direction">direction</a></code> property</strong> and have proprietary options for rotation, which <strong>allows for emulation of a few of the unsupported <code>writing-mode</code>&#8216;s</strong>, but not all of them.  The missing piece of <code>writing-mode</code> emulation belongs to the <code>block-progression</code> property, which isn&#8217;t supported by anyone, and would allow elements to flow reverse vertically (start at the bottom of a block and flow upwards).</p>
<p><em>It&#8217;s important to note that while <a href="http://blogs.msdn.com/ie/archive/2009/05/29/the-css-corner-writing-mode.aspx">IE8 has really set the bar for implementation here</a> and has chosen to support <code>writing-mode: lr-bt</code> and <code>writing-mode: rl-bt</code>, they aren&#8217;t used to display any known language text.  They&#8217;re just included for completeness, and aren&#8217;t a part of the <a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/">W3C CSS 3 Text Module specification.</a></em></p>
<h2><a href="http://zachleat.com/test/writing-mode/">View the Demo / Test Page</a></h2>
<h2>Compatibility Table</h2>
<style type="text/css">
#compatibility td { font-family: Verdana; }
#compatibility td.yes { background-color: #00882D; color: #fff; }
#compatibility td.no { background-color: #CB000F; color: #fff; }
#compatibility td.emulate { background-color: #40A662; color: #fff; }</p>
</style>
<table id="compatibility">
<thead>
<tr>
<th rowspan="2">writing-mode</th>
<th colspan="3">Internet Explorer<br/>(Trident)</th>
<th>Mozilla Firefox<br/>(Gecko)</th>
<th>Apple Safari<br/>(Webkit)</th>
<th>Google Chrome<br/>(Webkit)</th>
</tr>
<tr>
<th>6</th>
<th>7</th>
<th>8</th>
<th>3.6</th>
<th>4</th>
<th>4</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lr-tb</code></td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
</tr>
<tr>
<td><code>rl-tb</code></td>
<td class="emulate">emulatable</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
</tr>
<tr style="background-color: #eee;">
<td><code>lr-bt</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr style="background-color: #eee;">
<td><code>rl-bt</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr>
<td><code>tb-lr</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr>
<td><code>tb-rl</code></td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
</tr>
<tr>
<td><code>bt-lr</code></td>
<td class="no">no</td>
<td class="no">no</td>
<td class="yes">yes</td>
<td class="no">no</td>
<td class="no">no</td>
<td class="no">no</td>
</tr>
<tr>
<td><code>bt-rl</code></td>
<td class="emulate">emulatable</td>
<td class="yes">yes</td>
<td class="yes">yes</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
<td class="emulate">emulatable</td>
</tr>
</tbody>
</table>
<h2>CSS Code for Emulation</h2>
<table>
<thead>
<tr>
<th>writing-mode</th>
<th>CSS</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lr-tb</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Default</pre></div></div>

</td>
</tr>
<tr>
<td><code>rl-tb</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">direction</span><span style="color: #00AA00;">:</span> rtl<span style="color: #00AA00;">;</span></pre></div></div>

</td>
</tr>
<tr style="background-color: #eee;">
<td><code>lr-bt</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr style="background-color: #eee;">
<td><code>rl-bt</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr>
<td><code>tb-lr</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr>
<td><code>tb-rl</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">-webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
-moz-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.BasicImage<span style="color: #00AA00;">&#40;</span>rotation<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span></pre></div></div>

</td>
</tr>
<tr>
<td><code>bt-lr</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">// Not possible using W3C spec</pre></div></div>

</td>
</tr>
<tr>
<td><code>bt-rl</code></td>
<td>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">direction</span><span style="color: #00AA00;">:</span> rtl<span style="color: #00AA00;">;</span>
-webkit-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
-moz-transform<span style="color: #00AA00;">:</span> rotate<span style="color: #00AA00;">&#40;</span>90deg<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
filter<span style="color: #00AA00;">:</span> progid<span style="color: #3333ff;">:DXImageTransform</span><span style="color: #6666ff;">.Microsoft</span>.BasicImage<span style="color: #00AA00;">&#40;</span>rotation<span style="color: #00AA00;">=</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span></pre></div></div>

</td>
</tr>
</tbody>
</table>
<h2>Conclusion</h2>
<p>Given that <strong>4 of the 6 known writing modes are available</strong> or available through CSS emulation means we&#8217;re in pretty good shape on the internationalization front.  Consulting the Microsoft provided table for common use cases, we&#8217;re only in trouble when trying to use the &#8220;Mongolian script writing system&#8221; and an &#8220;Arabic script block quote embedded in Mongolian script document.&#8221;</p>
<p>In some far fetched fantasy-world legacy application where a page may use tables for layout, I could see an application team possibly using the <code>direction</code> property to redistribute the tables for a print stylesheet.  But that certainly wouldn&#8217;t be a common use case, since using CSS for layouts is going to give you much more flexibility in that regard.  If you can think of any other off the wall uses for <code>writing-mode</code> or <code>direction</code>, I&#8217;d love to hear them!</p>
<h2>Related</h2>
<ul>
<li>Very <a href="http://fantasai.inkedblade.net/style/discuss/vertical-text/#logical">complete article on CSS 3 writing-mode</a>, including some <code>direction</code> properties that don&#8217;t exist in the specification (like <code>ttb</code>, <code>ltr-ttb</code>, and <code>ltr-btt</code>)</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=writing-mode">Bugzilla Bug for writing-mode in Firefox</a></li>
<li>As of the time of this writing, I was unable to find any results for writing-mode on the Webkit bug tracker.</li>
</ul>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/d31mHxT2cnY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/02/12/css3-text-writing-mode/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/02/12/css3-text-writing-mode/</feedburner:origLink></item>
		<item>
		<title>Trash that “Back to Top” Link</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/_G-BvhoLhok/</link>
		<comments>http://www.zachleat.com/web/2010/02/05/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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/_G-BvhoLhok" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/02/05/trash-that-back-to-top-link/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/02/05/trash-that-back-to-top-link/</feedburner:origLink></item>
		<item>
		<title>The “24″ Clock on ALARMd</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/63H91-yJynM/</link>
		<comments>http://www.zachleat.com/web/2010/01/24/the-24-clock-on-alarmd/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 07:37:52 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Alarmd]]></category>
		<category><![CDATA[font-face]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=465</guid>
		<description><![CDATA[If you&#8217;re only using @font-face for titles and text, you&#8217;re missing out on a whole wealth of use cases that have yet to be explored. For instance, I created a very simple 7 Segment Display Numeric font to be used for a skin on alarmd.com and changed the color using nothing but CSS to create [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re only using @font-face for titles and text, you&#8217;re missing out on a whole <a href="http://www.zachleat.com/web/2010/01/03/css-sprites-using-font-face/">wealth of use cases</a> that have yet to be explored.  For instance, I created a very simple <a href="http://fontstruct.fontshop.com/fontstructions/show/282059">7 Segment Display Numeric font</a> to be used for a skin on <a href="http://www.alarmd.com/">alarmd.com</a> and changed the color using nothing but CSS to create the &#8220;24&#8243; Clock (true fans will note that the actual font is italic and <a href="http://www.panopticist.com/2006/05/there_is_something_weird_going_on_with_the_clock_on_24.php">has a serif on the 1</a>).  Nonetheless, this is just another useful application of @font-face.</p>
<p>Take a look at the <a href="http://www.fontsquirrel.com/fonts/list/style/Dingbat">Dingbats section on fontsquirrel</a> to get your brain going in the same direction.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2010/01/Screen-shot-2010-01-24-at-1.22.39-AM.png" alt="" title="Screenshot of the 24 Clock on alarmd.com"/></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/63H91-yJynM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/01/24/the-24-clock-on-alarmd/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/01/24/the-24-clock-on-alarmd/</feedburner:origLink></item>
		<item>
		<title>DIY Webdings – CSS Sprites using @font-face</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/VCVRx7raKPA/</link>
		<comments>http://www.zachleat.com/web/2010/01/03/css-sprites-using-font-face/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 00:48:29 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[css-sprites]]></category>
		<category><![CDATA[font-face]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=433</guid>
		<description><![CDATA[Almost everyone knows the Webdings font or its sibling Wingdings. Even if you don&#8217;t, chances are pretty good that it&#8217;s installed on your system. Webdings is a symbol font designed in 1997 as a response to the need of Web designers for a fast and easy method of incorporating graphics in their pages. &#8230; Webdings [...]]]></description>
			<content:encoded><![CDATA[<p>Almost everyone knows the Webdings font or its sibling Wingdings.  Even if you don&#8217;t, chances are pretty good that it&#8217;s installed on your system.</p>
<blockquote><p>Webdings is a symbol font designed in 1997 as a response to the need of Web designers for a fast and easy method of incorporating graphics in their pages.<br />
&#8230;</p>
<p>Webdings is ideal for enriching the appearance of a Web page. Because it’s a font, it can be installed on the user’s system, (or embedded in the document itself) is fully scaleable [sic] and quick to render. It’s a perfect way of including graphics on your site without making users wait for lots of graphic files to download.</p>
<p> &#8211; Source <a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=5">Microsoft Typography</a></p></blockquote>
<p>Microsoft was onto something here, and there is a nice parallel that can be drawn between the font and a CSS sprite: namely that multiple images are stored under the guise of a single HTTP request.  So, why not create our own font and use it as a CSS sprite?  Each character in the font (glyph) will be a single image in the sprite.</p>
<h2>Why is this awesome?</h2>
<ul>
<li>We can <strong>change the color</strong> of our font using nothing but CSS <code>color</code>.  This is a big one.  We don&#8217;t have to have separate images for hover states!  And if we want to change the color scheme, there are no new images to generate and we don&#8217;t have to make any changes to the font to do so.</li>
<li>Don&#8217;t have to monkey around with difficult to maintain CSS positioning code.</li>
<li>Fonts scale, graphics don&#8217;t.  Zooming in on a graphic will result in a pixelated image, but fonts will be smooth like a 6 blade razor shave.  Try zooming on the demo file below.</li>
</ul>
<h2>Why is this not awesome?</h2>
<ul>
<li>Font glyphs can only contain one color.</li>
<li>May experience the Flash of unstyled text (FOUT) while the font is loading.</li>
<li>Extra markup required for IE6 and IE7.  While @font-face is supported in all non-extinct versions of IE, each @font-face sprite requires a corresponding text character on the screen.  For instance, <code>&lt;span style="font-family: MyCustomFont;"&gt;A&lt;/span&gt;</code>, the A is required to display the @font-face Sprite stored under the A glyph.<br/><br />
Luckily, in most browsers we can inject a character using CSS :after/:before and the <code>content</code> property.  Unfortunately, this is <a href="http://www.quirksmode.org/css/beforeafter_content.html">not supported in IE6 or IE7</a>.  I haven&#8217;t investigated whether or not this might be solved using other means (CSS expressions) yet.</li>
<li>Safari asks for permission to use the font with a scary popup box, which I assume is a security precaution gleaned from the Windows Vista playbook.</li>
</ul>
<h2>Demo</h2>
<p>The following <a href="http://jquery-ui.googlecode.com/svn/trunk/tests/static/icons.html">jQuery UI Icons</a> are currently used in jQuery UI and are stored in <a href="http://jqueryui.com/themeroller/images/?new=888888&#038;w=256&#038;h=240&#038;f=png&#038;fltr[]=rcd|256&#038;fltr[]=mask|icons/icons.png">one big CSS sprite</a>.</p>
<p>It was pretty trivial to create <a href="http://fontstruct.fontshop.com/fontstructions/show/jquery_ui_icons_1">a font</a> with a subset of the jQuery UI icons (only the first 20, just a proof of concept here) using the wonderful <a href="http://fontstruct.fontshop.com/">FontStruct</a> utility.  Then, I took the TTF generated by FontStruct and plugged it into the completely lovely <a href="http://www.fontsquirrel.com/fontface/generator">FontSquirrel @font-face Kit Generator</a>.  That gave me everything I needed for a fully cross-browser test.</p>
<ul>
<li><a href="http://www.zachleat.com/test/fonts/font.html" style="font-size: 160%; font-weight: bold;">View the Demo</a></li>
</ul>
<p>Let me know what you think!</p>
<div style="font-size: 80%">
Successfully tested on:</p>
<ul>
<li>Google Chrome 4 (Mac)</li>
<li>Safari 4 (Mac)</li>
<li>Firefox 3.5 (Mac and Windows)</li>
<li>Internet Explorer 8</li>
<li>With documented limitations above:
<ul>
<li>Internet Explorer 6</li>
<li>Internet Explorer 7 (Compatibility Mode in IE8)</li>
</ul>
</li>
</ul>
<p>Does not work on (no @font-face support):</p>
<ul>
<li>Google Chrome 3 and prior</li>
<li>Firefox 3 and prior</li>
</ul>
</div>
<p>Read more about <a href="http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/">@font-face support from Paul Irish</a>.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/VCVRx7raKPA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2010/01/03/css-sprites-using-font-face/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2010/01/03/css-sprites-using-font-face/</feedburner:origLink></item>
		<item>
		<title>Don’t Give Up on Internet Explorer Yet</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/-NtO2mXshgQ/</link>
		<comments>http://www.zachleat.com/web/2009/12/09/dont-give-up-on-ie/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 03:24:46 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Web Browsers]]></category>
		<category><![CDATA[Google Wave]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Zombies]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=351</guid>
		<description><![CDATA[These days, the browser landscape is more fragmented than ever. Were times easier back when IE6 and Firefox ruled the internet? Easier perhaps in terms of the number of browsers you had to launch for testing, but not better for any user&#8217;s experience. We are in a new world, where more web browsers are causing [...]]]></description>
			<content:encoded><![CDATA[<p>These days, the browser landscape is more fragmented than ever.  Were times easier back when IE6 and Firefox ruled the internet? Easier perhaps in terms of the number of browsers you had to launch for testing, but <strong>not better</strong> for any user&#8217;s experience. We are in a new world, where more web browsers are causing developers to become <strong>increasingly pragmatic</strong> with their designs and code. Sure, standards have created a safe haven under the newest versions of the Big 3 (Firefox, IE, Safari), but the lay majority are still using whatever default has been installed onto their computer, and they probably can&#8217;t tell you <a href="http://googlesystem.blogspot.com/2009/06/browser-is-search-engine.html">the difference between their web browser and a search engine</a>.</p>
<p>We must be resilient to resist the transformation from development pragmatism to user abandonment, especially considering a developer&#8217;s trend of being insulated with the latest equipment.  We use the newest hardware and download the most sophisticated browser software because we want the best experiences.  We stack the cards in our favor.  The difficulty lies with the populace that <strong>want a good experience</strong> (they can tell a fast site from a slow site), but they <strong>don&#8217;t want to buy new equipment or install a better browser.</strong>  So the question has become: Where do you place your chips on the spectrum balancing modern hardware/software and the user experience?</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/12/zombies.png" alt="zombie" title="zombie" width="200" height="234" class="alignright size-full wp-image-361" />As web developers, it has become increasingly easy to become disenfranchised with the lay majority&#8217;s computing environment.  I&#8217;ve witnessed this personally after purchasing my first Apple computer, a device curiously immune to the plague of IE 6/7 (8 as well, but I would hesitate to label it as a plague, more like a normal run of the mill flesh eating virus).  It&#8217;s an interesting phenomenon, being cutoff from the Windows environment (save virtualization) during development.  It&#8217;s delightfully tempting to declare damnation upon the plague ridden Internet Explorer Zombies, and develop your web presence to standards alone, allowing less focus on the harshest development environment imaginable and more on actual problem solving.</p>
<p>When developers engage in quasi-web development, perhaps in the form of an iPhone specific web application or an Adobe AIR desktop application, it fosters similar feelings.   The work shares many languages and technologies with real (wide-open) web development, but is targeted towards a single web browser.  This benefits of this sort of tunnel vision device targeting must be carefully weighed against the penalties you&#8217;re paying in narrowed default-install client compatibility.  At that point, it&#8217;s just <strong>friends with benefits</strong>.</p>
<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/12/google-wave-ie8.png" alt="Denial of Access with Internet Explorer Screenshot" title="Denial of Access with Internet Explorer Screenshot" width="454" height="339" class="aligncenter size-full wp-image-363" /><br />
Google Wave, in fact, requires the use of Safari, Firefox, Chrome, or the Google Chrome Frame plugin (which doesn&#8217;t count as actual browser support).  As of the time this article was written, as many as <strong>64% of all users</strong> (<a href="http://en.wikipedia.org/wiki/Usage_share_of_web_browsers">source</a>) are met with the above screen when trying to access Google Wave. Let&#8217;s be clear: <strong>Ease of development is not an excuse to abandon users.</strong>  Whatever happened to <a href="http://www.zachleat.com/web/2009/08/29/device-independence/">Device Independence</a>?</p>
<p>Not surprisingly, Google Wave&#8217;s stand against Internet Explorer <strong>has not started a trend</strong>.  Instead of all out war, the community at large has decided that subtlety is what&#8217;s needed to win this fight.  Let&#8217;s hold back the <a href="http://en.wikipedia.org/wiki/Sexual_Healing">sexual healing</a> of rounded corners, even though perhaps users will call our design harsh or cold.  Let&#8217;s give them plain buttons instead of nice three dimensional buttons with text and box shadows, even though they may be less actionable.</p>
<p>Let&#8217;s make it easier on ourselves at the expense of the user experience of The Zombie Majority.  We make this sacrifice because we assume that Zombies won&#8217;t be able to tell the difference between eating a big juicy Einstein brain and a smaller but nonetheless still tasty brush clearing George W.  And you know what, <strong>I think we&#8217;re right.</strong></p>
<p><em><strong>Updated</strong> to include a few more thoughts on Adobe AIR and the iPhone.</em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/-NtO2mXshgQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/12/09/dont-give-up-on-ie/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/12/09/dont-give-up-on-ie/</feedburner:origLink></item>
		<item>
		<title>Device Independence on the Open Web</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/MlhHs_IR0r8/</link>
		<comments>http://www.zachleat.com/web/2009/08/29/device-independence/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 18:37:12 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Application Design]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=329</guid>
		<description><![CDATA[Open Web advocacy can get pretty lonely working in Big Enterprise. Armed with slow moving standards bodies, and held back by antiquated browser support, architectural battles over tools and frameworks can get pretty hairy if you don&#8217;t approach them with the right frame of mind. Big Enterprise is traditionally known for creating development environments that [...]]]></description>
			<content:encoded><![CDATA[<p>Open Web advocacy can get pretty lonely working in Big Enterprise.  Armed with slow moving standards bodies, and held back by antiquated browser support, architectural battles over tools and frameworks can get pretty hairy if you don&#8217;t approach them with the right frame of mind.</p>
<p>Big Enterprise is traditionally known for creating development environments that foster a &#8220;get it done&#8221; mentality, often rewarding results over correctness (mileage, of course, may vary).</p>
<blockquote><p>My company uses IE6, and the application works in IE6, so it&#8217;s done!</p></blockquote>
<p>This little quagmire is amplified by the fact that when using Open Web technology, there are many ways to get things done, and most of them are incorrect.  But those mistakes don&#8217;t manifest themselves until the project is in the hands of the end user, whom we often punish for our oversight.</p>
<p>But there is hope. Using the power of web standards and Open Web best practices, we can achieve something panoramically, not microscopically, beautiful.</p>
<p>The secret sauce of building for the Web isn&#8217;t its distribution model, in which updates are managed on the web server without the need to update software on the client (although the Anti-IE6 vigilantes would tell you differently).  It most certainly isn&#8217;t development efficiency, as most people new to the game will so readily inform you of.  Cross browser quirks due to non-standard browser implementations of CSS and JavaScript, or vague standards specifications have seen to that.</p>
<blockquote><p>When I was writing Visual Basic, I got my job done so much quicker and easier!</p></blockquote>
<h2>The power of the Open Web is Device Independence.</h2>
<p>Visitors to our sites <strong>shouldn&#8217;t be met with warnings</strong> about what device they&#8217;ve chosen to use.</p>
<blockquote><p>This site viewable only in IE7+, Firefox, Chrome, or Safari, and at minimum 1024&#215;768 resolution.</p></blockquote>
<blockquote><p>This site requires Flash or Silverlight</p></blockquote>
<p>I realize that this is a controversial stance, especially given that most sites are dropping support for IE6, and more are relying on Flash and Silverlight plugins.  <strong>Architect applications to your client device usage statistics, and don&#8217;t let your tools shape the statistics for you.</strong>  Using techniques like progressive enhancement, we can ensure that our sites degrade gracefully to the capabilities of the client device.  At it&#8217;s truest form, this is basic accessibility. But, Device Independence might be a more accurate term, since accessibility is unfortunately an overloaded term scoped solely with devices tied to disabilities (screen readers, for example).  While screen readers are a very important piece, there is a bigger picture.</p>
<p>When the iPhone came out, there was an uproar because it didn&#8217;t support Flash, for battery life and other reasons.  But the uproar was from developers who had designed applications specifically for Flash!  Would you say that those Flash applications were designed with device independence in mind?  YouTube got around this by encoding their videos in MP4 format, which arguably has a higher device independence rating than the Flash format.</p>
<p>Keep in mind that we&#8217;re <strong>not attempting to handle every permutation of end user browser settings</strong>, since most don&#8217;t change the defaults.  Instead we are trying to scoop up the largest base of supported devices with the least amount of effort!  Who cares if an end user disabled JavaScript in their preferences?  I&#8217;m more worried about the mobile browser that doesn&#8217;t even support JavaScript at all.  But when you use Open Web properly, you get support for both!</p>
<h2>Output Device Independence</h2>
<ul>
<li>Full Web Browsers: Does your site work in Opera? Don&#8217;t worry about pixel perfection, that&#8217;s something completely different &#8212; does it work?</li>
<li>Web Browsers on Mobiles</li>
<li>Search Engine Spiders and other Screen Scrapers</li>
<li>Screen Readers</li>
<li>Printers: Ever had to make an entirely separate page for print-friendly version of your application? Flash/Silverlight <strong>do not</strong> print well</li>
<li>Televisions: Xbox 360, Wii, and Other Media Center Devices</li>
<li>Projectors</li>
<li><em>and more&#8230;</em></li>
</ul>
<p>Take a look at the <a href="http://www.w3.org/TR/CSS21/media.html#media-types">CSS specification for media types</a>.  The standards are there!  Support for CSS media types isn&#8217;t fool proof by any means, but the end goal is clearly visible.</p>
<h2>Input Device Independence</h2>
<p>But I&#8217;m not just talking about output device independence either.  User interfaces should be adaptable to different input devices as well.</p>
<ul>
<li>Mouse</li>
<li>Keyboard (often overlooked in web applications)</li>
<li>Touch Screens (Single and <a href="http://hacks.mozilla.org/2009/08/multi-touch-firefox/">Multi-touch</a>)</li>
<li>Voice, Motion Capture, and Facial Recognition (the standards and technology aren&#8217;t quite there yet, but <a href="http://hacks.mozilla.org/2009/06/connecting-html5-video/">progress is being made</a>)</li>
<li><em>and more&#8230;</em></li>
</ul>
<p>The world is developing the Open Web, and it isn&#8217;t limited by a single company&#8217;s goals and timelines.  At times, Open Web may seem like it&#8217;s a very slow moving <strong>glacier</strong> headed our way, but what else can you do but laugh when companies try to <strong>power their Titanic right through it</strong>?</p>
<p><em>Article originally inspired by <a href="http://developer.yahoo.com/yui/articles/gbs/#history">Yahoo&#8217;s Graded Browser Support</a>.</em></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/MlhHs_IR0r8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/08/29/device-independence/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/08/29/device-independence/</feedburner:origLink></item>
		<item>
		<title>Quick Performance Tip: jQuery and addClass</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/KSPTGBeoEiM/</link>
		<comments>http://www.zachleat.com/web/2009/06/30/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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/KSPTGBeoEiM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/06/30/quick-performance-tip-jquery-and-addclass/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/06/30/quick-performance-tip-jquery-and-addclass/</feedburner:origLink></item>
		<item>
		<title>Adobe Reverts Flex Store to Open Web</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/F715iDkx2HE/</link>
		<comments>http://www.zachleat.com/web/2009/05/23/adobe-reverts-flex-store-to-open-web/#comments</comments>
		<pubDate>Sat, 23 May 2009 18:19:08 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Adobe]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=220</guid>
		<description><![CDATA[A few weeks ago in the process of doing some research about the Adobe Flex platform, I came across their online store, a dogfooded full page application using Flex. This morning I went back to the same URL to find a site that was no longer using the full page Flex application I had been [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago in the process of doing some research about the Adobe Flex platform, I came across their online store, a dogfooded full page application using Flex.</p>
<p>This morning I went back to the <a href="https://store1.adobe.com/cfusion/store/html/index.cfm?store=OLS-US&#">same URL</a> to find a site that was no longer using the full page Flex application I had been expecting.  Instead it was now using native Open Web technology.</p>
<p>Naturally, my first assumption was that I had hallucinated the original research.  But as it turns out, I wasn&#8217;t the only one that noticed the Flex application.  This blogger <a href="http://www.cfinternals.org/blog/2007/06/adobes_flashfle.html">complained about the accessibility</a> of a full page Flash/Flex store.  Another blogger had a <a href="http://www.abdulqabiz.com/blog/archives/adobe/adobe_store_is_still.php">similar complaint</a>.</p>
<p>I have no idea how long the Flash/Flex Adobe store experiment went on before they changed it back.  I&#8217;m just glad I&#8217;m not crazy.</p>
<p><strong>Update</strong>: Turns out they are using a whitelist/blacklist of user agents to decide whether or not to show the Flex store.  The <a href="https://store1.adobe.com/cfusion/store/index.cfm">original entry point</a> above is incorrect, and shouldn&#8217;t have the html subdirectory.  If you go to the site in Chrome, it will redirect you to the HTML version.  My apologies, Adobe, although I do think the HTML version is much more accessible.</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/F715iDkx2HE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/05/23/adobe-reverts-flex-store-to-open-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/05/23/adobe-reverts-flex-store-to-open-web/</feedburner:origLink></item>
		<item>
		<title>Performance Caveat with jQuery Selectors and Live Events</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/-Uo94fnuKGI/</link>
		<comments>http://www.zachleat.com/web/2009/05/08/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>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/-Uo94fnuKGI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/05/08/performance-caveat-with-jquery-selectors-and-live-events/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/05/08/performance-caveat-with-jquery-selectors-and-live-events/</feedburner:origLink></item>
		<item>
		<title>Jonathan Sharp at The Ajax Experience</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/pJXZ77DiFi4/</link>
		<comments>http://www.zachleat.com/web/2009/02/20/jonathan-sharp-at-the-ajax-experience/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 03:35:51 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[People]]></category>
		<category><![CDATA[Ajaxian]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[The Ajax Experience]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=200</guid>
		<description><![CDATA[Former co-worker and all around good guy Jonathan Sharp gave a presentation at The Ajax Experience about a project that he developed, and subsequently passed onto me around 3Q2008.]]></description>
			<content:encoded><![CDATA[<p>Former co-worker and all around good guy <a href="http://jdsharp.us/">Jonathan Sharp</a> gave a presentation at The Ajax Experience about a project that he developed, and subsequently passed onto me around 3Q2008.  A custom built UI component library based on jQuery, used by 450+ developers on 80+ internal and external web applications.  You wouldn&#8217;t think it, but railroads have pretty large IT departments. This presentation was <a href="http://ajaxian.com/archives/jquery-ajax-experience-framework-videos">posted on Ajaxian</a> this week.  Enjoy!</p>
<p><embed src="http://services.brightcove.com/services/viewer/federated_f8/1596744118" bgcolor="#FFFFFF" flashVars="videoId=1828663222&#038;playerId=1596744118&#038;viewerSecureGatewayURL=https://console.brightcove.com/services/amfgateway&#038;servicesURL=http://services.brightcove.com/services&#038;cdnURL=http://admin.brightcove.com&#038;domain=embed&#038;autoStart=false&#038;" base="http://admin.brightcove.com" name="flashObj" width="486" height="412" seamlesstabbing="false" type="application/x-shockwave-flash" swLiveConnect="true" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></embed></p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/pJXZ77DiFi4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/02/20/jonathan-sharp-at-the-ajax-experience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/02/20/jonathan-sharp-at-the-ajax-experience/</feedburner:origLink></item>
		<item>
		<title>ALARMd Unix Time Format for 1234567890 Day</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/ChjbspUhrPw/</link>
		<comments>http://www.zachleat.com/web/2009/02/13/alarmd-unix-time-format-for-1234567890-day/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 19:11:18 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=196</guid>
		<description><![CDATA[In honor of 1234567890 day, I&#8217;ve added the Unix time format to ALARMd. Hit Options, then the Clock Format tab to change to Unix Time. Enjoy!]]></description>
			<content:encoded><![CDATA[<p>In honor of <a href="http://www.1234567890day.com/">1234567890 day</a>, I&#8217;ve added the Unix time format to <a href="http://www.alarmd.com/">ALARMd</a>.</p>
<p>Hit <strong>Options</strong>, then the <strong>Clock Format tab</strong> to change to Unix Time.  Enjoy!</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/ChjbspUhrPw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/02/13/alarmd-unix-time-format-for-1234567890-day/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/02/13/alarmd-unix-time-format-for-1234567890-day/</feedburner:origLink></item>
		<item>
		<title>Registration Forms Suck, Let’s Mitigate Suckiness</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/VASF_nYcxYA/</link>
		<comments>http://www.zachleat.com/web/2009/01/10/registration-forms-suck-lets-mitigate-suckiness/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 23:59:45 +0000</pubDate>
		<dc:creator>Zach Leatherman</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Forms]]></category>
		<category><![CDATA[OpenID]]></category>
		<category><![CDATA[Registration]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.zachleat.com/web/?p=181</guid>
		<description><![CDATA[A lot of people <strong>complain about registration forms</strong>. Some people have suggested getting rid of them altogether, allowing users to utilize login credentials from accounts they already have through OpenID.  But registration forms aren't going away.  How can we make them more friendly?]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.zachleat.com/web/wp-content/uploads/2009/01/signup-form.png" alt="Signup Form" title="signup-form" width="250" height="293" class="size-full wp-image-183" style="float:right" /> A lot of people <strong>complain about registration forms</strong>. Some people have suggested getting rid of them altogether, allowing users to utilize login credentials from accounts they already have through OpenID.  But even with a highly technical audience, OpenID adoption is <a href="http://blog.stackoverflow.com/2008/10/stack-overflow-openid-case-study/">problematic</a>.</p>
<p>So, some sites have gone two ways, allowing OpenID, but also a proprietary registration system.  This too, <a href="http://www.wetpaintcentral.com/page/OpenID?t=anon">is problematic</a>.  It would seem that given a choice, the <strong>John Doe the Plumber style user will choose a proprietary account</strong> over the confusing user experience presented to them through OpenID.</p>
<p>But the annoyance doesn&#8217;t just lie with account registration for web applications.  Typing your personal information on every blog you comment at is also repetitive and unnecessary.  <a href="http://www.ajaxian.com">Some sites</a> even require account registration for something so minor and transient as a blog comment.</p>
<p>Unfortunately, for the time being, it looks like <strong>registration forms are here to stay</strong>.  So, what can we do to make those registration forms more usable, more efficient, and ultimately downright friendly?  I know that you&#8217;re ahead of me on this one: <strong>Let&#8217;s auto-complete information for the user</strong>.</p>
<p>Please keep in mind that this power can be used for both good and evil.  Essentially what we&#8217;re discussing here is data mining available information from various social networking sites on the internet, trying to glean personal information about an end user that has volunteered a piece of their data already.  What can we get from what we already have?</p>
<p>Once a user has typed in their <strong>e-mail address</strong>, we can:</p>
<ul>
<li>Retrieve Twitter profile information (<a href="http://www.wait-till-i.com/2009/01/08/using-twitter-as-a-data-provider-to-automatically-fill-forms/">example shown on Chris Heilmann&#8217;s blog</a>):
<ul>
<li>Full Name</li>
<li>Short Personal Description</li>
<li>Location</li>
<li>Web site URL</li>
<li>Time Zone</li>
<li>Favorite Colors (used on their profile)</li>
</ul>
</li>
<li>Retrieve an <strong>avatar</strong> if they&#8217;ve registered for the Gravatar web service (<a href="http://www.zachleat.com/web/2009/01/08/scare-your-visitors-with-this-javascript-gravatar-plugin/">See my earlier post discussing this</a>).</li>
<li>Get their <a href="http://gdata-javascript-client.googlecode.com/svn/trunk/samples/calendar/simple_sample/simple_sample.html">upcoming calendar events</a> from a public Google Calendar. (Perhaps not as useful for autocompleting forms, but interesting)</li>
<li>Find their <a href="http://www.flickr.com/services/api/flickr.people.findByEmail.html">UID on Flickr</a>, which gives you <a href="http://www.flickr.com/services/api/flickr.people.getInfo.html">a source</a> for:
<ul>
<li>Full Name</li>
<li>Location</li>
<li>Flickr Avatar</li>
</ul>
</li>
</ul>
<p>If you know any of their social networking usernames, you can:</p>
<ul>
<li><a href="http://developer.yahoo.com/mybloglog/V1/member_find_byservice.html">find their MyBlogLog profile</a>, if they&#8217;ve linked the service to their account (<a href="http://mybloglog.yahooapis.com/v1/user/service/twitter/zachleat?AppId=YahooDemo&#038;format=xml">Sample query, I added my twitter</a>).  Now we have:
<ul>
<li>MyBlogLog Screen Name and ID, from which you get their <a href="http://developer.yahoo.com/mybloglog/V1/member_find_byid.html">MyBlogLog profile</a>:
<ul>
<li>Nickname</li>
<li>Picture</li>
<li>Age</li>
<li>Sex</li>
<li>Location</li>
<li>A list of tags they use to describe themselves.</li>
</ul>
</li>
<li>MyBlogLog Avatar</li>
</ul>
</li>
</ul>
<p>Those are only some of the proof of concept API&#8217;s that I&#8217;ve listed here.  The interesting piece of this, is that once you have a small piece of information, it <strong>opens up the door to other searches</strong>.</p>
<p>One can only imagine how many leaves are in this tree.  For example:</p>
<ul>
<li>Facebook&#8217;s <a href="http://wiki.developers.facebook.com/index.php/Users.getInfo">Users.getInfo</a> (<a href="http://wiki.developers.facebook.com/index.php/JavaScript_Client_Library">in JavaScript</a>)</li>
<li>Yahoo&#8217;s Social Tools, get an <a href="http://developer.yahoo.com/social/rest_api_guide/introspective-guid-resource.html">end user&#8217;s GUID</a> and go to town on <a href="http://developer.yahoo.com/social/rest_api_guide/social_dir_api.html">their profile</a>.
<li>Google Contacts, I didn&#8217;t even start to look through <a href="http://code.google.com/apis/contacts/">their API&#8217;s</a>.</li>
</ul>
<p>Before you start jumping the privacy fence to a self induced heart attack, remember that <strong>all this information has been volunteered</strong> by each individual participating in each of these services.  Remember, with great power comes great responsibility.</p>
<p>What do you think?  Scary or useful?</p>
<img src="http://feeds.feedburner.com/~r/zachleat/~4/VASF_nYcxYA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/01/10/registration-forms-suck-lets-mitigate-suckiness/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/01/10/registration-forms-suck-lets-mitigate-suckiness/</feedburner:origLink></item>
		<item>
		<title>Scare Your Visitors with this JavaScript Gravatar Plugin</title>
		<link>http://feedproxy.google.com/~r/zachleat/~3/BBhhBTyNdVU/</link>
		<comments>http://www.zachleat.com/web/2009/01/08/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>

<img src="http://feeds.feedburner.com/~r/zachleat/~4/BBhhBTyNdVU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.zachleat.com/web/2009/01/08/scare-your-visitors-with-this-javascript-gravatar-plugin/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.zachleat.com/web/2009/01/08/scare-your-visitors-with-this-javascript-gravatar-plugin/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 3.513 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-07-29 20:00:06 -->
