<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><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/" version="2.0">

<channel>
	<title>James Padolsey</title>
	
	<link>http://james.padolsey.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sat, 21 Aug 2010 04:38:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<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/JamesPadolsey" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="jamespadolsey" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">JamesPadolsey</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FJamesPadolsey" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FJamesPadolsey" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FJamesPadolsey" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/JamesPadolsey" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FJamesPadolsey" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FJamesPadolsey" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FJamesPadolsey" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item>
		<title>Detect IE in JS using conditional comments</title>
		<link>http://james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/</link>
		<comments>http://james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 14:10:21 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1659</guid>
		<description><![CDATA[A short snippet for detecting versions of IE in JavaScript without resorting to user-agent sniffing]]></description>
			<content:encoded><![CDATA[<p>I originally posted this as a gist, <a href="http://gist.github.com/527683">here</a>. I thought it best to keep my readers informed so that&#8217;s why I&#8217;m posting it here too:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">// ----------------------------------------------------------</span>
<span class="co1">// A short snippet for detecting versions of IE in JavaScript</span>
<span class="co1">// without resorting to user-agent sniffing</span>
<span class="co1">// ----------------------------------------------------------</span>
<span class="co1">// If you're not in IE (or IE version is less than 5) then:</span>
<span class="co1">//     ie === undefined</span>
<span class="co1">// If you're in IE (&gt;=5) then you can determine which version:</span>
<span class="co1">//     ie === 7; // IE7</span>
<span class="co1">// Thus, to detect IE:</span>
<span class="co1">//     if (ie) {}</span>
<span class="co1">// And to detect the version:</span>
<span class="co1">//     ie === 6 // IE6</span>
<span class="co1">//     ie &gt; 7 // IE8, IE9 ...</span>
<span class="co1">//     ie &lt; 9 // Anything less than IE9</span>
<span class="co1">// ----------------------------------------------------------</span>
&nbsp;
<span class="co1">// UPDATE: Now using Live NodeList idea from @jdalton</span>
&nbsp;
<span class="kw2">var</span> ie <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> undef<span class="sy0">,</span>
        v <span class="sy0">=</span> <span class="nu0">3</span><span class="sy0">,</span>
        div <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span><span class="sy0">,</span>
        all <span class="sy0">=</span> div.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'i'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">while</span> <span class="br0">&#40;</span>
        div.<span class="me1">innerHTML</span> <span class="sy0">=</span> <span class="st0">'&lt;!--[if gt IE '</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="sy0">++</span>v<span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">']&gt;&lt;i&gt;&lt;/i&gt;&lt;![endif]--&gt;'</span><span class="sy0">,</span>
        all<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>
    <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">return</span> v <span class="sy0">&gt;</span> <span class="nu0">4</span> <span class="sy0">?</span> v <span class="sy0">:</span> undef<span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p class="video"><strong><a href="http://gist.github.com/527683">http://gist.github.com/527683</a></strong></p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dear .NET</title>
		<link>http://james.padolsey.com/javascript/dear-net/</link>
		<comments>http://james.padolsey.com/javascript/dear-net/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 00:24:10 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Critical]]></category>
		<category><![CDATA[Industry]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1619</guid>
		<description><![CDATA[<em><a href="http://www.netmag.co.uk/">A letter to the .NET magazine</a></em>

Staring keenly at a stack of magazines, I hazard a gaze towards the computer
section and lay my eyes upon the newest cover of my sworn enemy, the .NET
magazine. Its luring front-page convinces me that it deserves my consideration.&#8230;]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://www.netmag.co.uk/">A letter to the .NET magazine</a></em></p>

<p>Staring keenly at a stack of magazines, I hazard a gaze towards the computer
section and lay my eyes upon the newest cover of my sworn enemy, the .NET
magazine. Its luring front-page convinces me that it deserves my consideration.</p>

<p>I buy it without looking inside. I want to reserve the surprise for later.</p>

<p>Now sitting in the lounge at London Gatwick Airport, I whip out the magazine
and rush to a JavaScript article. I can&#8217;t wait. It&#8217;s about jQuery and I just know
that they&#8217;ve gotten their act together since <a href="http://james.padolsey.com/general/a-lack-of-progression-2008/">previous encounters</a>. I&#8217;m sure this
article will contain the best in jQuery techniques and JavaScript best practices.</p>

<p>Well, .NET, now I&#8217;m sitting here with the unfortunate duty to inform you of my
unsurprising disappointment.</p>

<p>The truth is I expected nothing more from you.</p>

<p>Please turn to page 80 of issue 205 and pay special consideration to the
following reservations of mine:</p>

<p>The author doesn&#8217;t mention the possibility nor the applicability of creating a
jQuery plugin instead of the single globally defined function &#8216;drawerToggler&#8217;.
What&#8217;s wrong with this? Well, the function happens to contain functionality that
could be abstracted to deal with arbitrary sets of nodes and is therefore suited
to jQuery&#8217;s plugin mechanism. I would understand if at least a mention surfaced,
but nothing.</p>

<p>This is certainly not the worst of it though.</p>

<p>The function itself:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">function</span> drawerToggler<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    $<span class="br0">&#40;</span><span class="st0">'#theme-drawer'</span><span class="br0">&#41;</span>.<span class="me1">slideToggle</span><span class="br0">&#40;</span><span class="st0">&quot;normal&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
        <span class="kw1">if</span> <span class="br0">&#40;</span>$<span class="br0">&#40;</span><span class="st0">'#theme-drawer'</span><span class="br0">&#41;</span>.<span class="kw1">is</span><span class="br0">&#40;</span><span class="st0">&quot;:visible&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            $<span class="br0">&#40;</span><span class="st0">'#wrapper'</span><span class="br0">&#41;</span>.<span class="me1">css</span><span class="br0">&#40;</span><span class="st0">&quot;margin-bottom&quot;</span><span class="sy0">,</span> <span class="st0">&quot;150px&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
            $<span class="br0">&#40;</span><span class="st0">'#wrapper'</span><span class="br0">&#41;</span>.<span class="me1">css</span><span class="br0">&#40;</span><span class="st0">&quot;margin-bottom&quot;</span><span class="sy0">,</span> <span class="st0">&quot;20px&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>




<p>Where it&#8217;s being called:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    $<span class="br0">&#40;</span><span class="st0">'.drawer-toggler'</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
        drawerToggler<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>This function is called within the click event handler for any element with a
className containing <code>drawer-toggler</code>. Since it&#8217;s getting called on every click,
and the elements selected within the <code>drawerToggler</code> do not change between calls,
it would be logical to select and &#8220;cache&#8221; the DOM object references beforehand,
and then the function could use these DOM references instead of continually
(and redundantly) re-querying the DOM on every single call!</p>

<p>The function itself contains some redundant code too. The &#8216;theme-wrapper&#8217; to
which the <code>slideToggle</code> method is applied, is then re-queried within the callback.
Apparently unbeknown to the author, this very element can be accessed via the
&#8216;this&#8217; keyword within the callback function &#8212; there is absolutely no need to
re-query the DOM for <code>#theme-wrapper</code>!</p>

<p>This isn&#8217;t just a case of my preferences versus the author. There are established
best practices in the jQuery community and as one of the industry&#8217;s top
publications you should be providing not only good advice but near enough the
best advice according to current industry practices and standards.</p>

<span id="more-1619"></span>

<p>Now, I could stop, but the reign of nonsensical JavaScript programming continues.</p>

<p>On page 82, along with the insistence of using <code>$(this).attr('rel')</code> instead of
the terser and faster DOM equivalent, <code>this.rel</code>, the author insists, again,
on re-querying the DOM for unchanged elements within the click event handler for
all anchor elements within <code>#themes-wrapper</code>!</p>

<p>There&#8217;s a few more specific issues I&#8217;d like to raise but I feel I&#8217;ve already made my point in regards to the obvious inadequacy of the article itself.</p>

<p>The article specifically says that it&#8217;s geared towards developers with an
<em>intermediate-level</em> understanding of HTML, CSS and JavaScript. If you want to
further the knowledge and understanding of these developers then you must, as
reason would dictate, have a teacher that presents a <em>higher-than-intermediate</em>
understanding of these technologies.</p>

<p>Before you suggest that I write an article to amend previously made mistakes (<em>&#8220;Instead of complaining write your own article.. blah blah blah&#8221;</em>) I&#8217;d
like to let you know that I will do no such thing. It is your responsibility to
find the best authors and the best content featuring the topic at hand.</p>

<p>I write
this letter not only because I care, but because I am desperately worried, as
are many others, about the state of jQuery within the JavaScript community, and
more generally the lacking understanding that is slowly rotting the core principles of
JavaScript from under its feet. Let the ignorance stain the ranks of beginners
and hobbyists, as it always has and always will, but let it not protrude into a publication that claims to
encapsulate the ever-changing essence of the web industry. Stop pandering to
the lowest common denominator and be the best!</p>

<p>I realise that, from a
monetary perspective, such concerns are likely to be lower on your priority
list than getting that new coffee machine for your staff, but for the love of
what you claim to stand for, prove to me that you are more than what I dare think
you may just be &#8212; another profit-based publication whose sole concern is the
quantity of its readership rather than the quality of its content.</p>

<p>If you&#8217;re going to publish articles relating to JavaScript then you&#8217;re going to
have to tighten your belt and get to work. It&#8217;s not a playground. Currently,
you&#8217;re only serving as a catalyst to the ignorance that a magazine such as
yours should be out to destroy.</p>

<p>If you think this letter is not worthy of your consideration, then discard it as one of many (no doubt) complaints, for I am only too happy to accept that I&#8217;m right about you!</p>

<p>Prove me wrong. I dare you.</p> 

<p><em>JAMES PADOLSEY</em></p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/dear-net/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Me…</title>
		<link>http://james.padolsey.com/general/me/</link>
		<comments>http://james.padolsey.com/general/me/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 17:24:12 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[My Life]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Me]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1613</guid>
		<description><![CDATA[Okay. For once, I&#8217;m going to say what I actually think on this site of mine! I&#8217;ve done it to a degree before but I got frequently hushed by the few people that see anything but neutrality as a weakness or a threat. I&#8217;m only&#8230;]]></description>
			<content:encoded><![CDATA[<p>Okay. For once, I&#8217;m going to say what I actually think on this site of mine! I&#8217;ve done it to a degree before but I got frequently hushed by the few people that see anything but neutrality as a weakness or a threat. I&#8217;m only human, and I have some damned opinions. So here they are!</p>

<p><em>Be prepared for mildly offensive rhetoric and inappropriate usage of the ellipsis and exclamation mark!!!</em></p>

<ul>
    <li>
        <p>I think this universe is simply awesome. We&#8217;re quite tiny when everything is put into perspective. Heck, we&#8217;re just one form of life, on one planet, in one star system of hundreds of billions of star systems in this galaxy alone (which itself is accompanied by hundreds of billions of other galaxies), and yet some people still have the arrogance to feel that the human race is at the centre of the whole universe! Our wonderful yet miniscule existence is aptly covered in this <a href="http://www.youtube.com/watch?v=p86BPM1GV8M">beautifully poetic video</a> from the late Carl Sagan.</p>
    </li>
    <li>I think inline documentation, like that made possible with JSDoc, makes code ugly and unreadable. I want to see the code, and that&#8217;s all!</li>
    <li>I love the outdoors. I envy people that have jobs outside. And I don&#8217;t mean outside on the street cleaning up human sewage. I mean outside in the real world &#8212; the places that we haven&#8217;t yet destroyed.</li>
    <li>I think heavy UI abstractions like ExtJS totally take away all of the fun, excitement and challenges that should form a central part in any programmer&#8217;s role. To me, it looks like a product built for business people, and business people rarely understand the motives and desires of programmers &#8212; they only understand a couple of things: profit margins and economic viability.</li>
    <li>I&#8217;ve yet to sit in an office chair that won&#8217;t make my back hurt like hell after eight hours.</li>
    <li>I don&#8217;t believe in a God. I also don&#8217;t believe in fairies or unicorns.</li>
    <li>I get annoyed when people don&#8217;t realise the difference between believing that something doesn&#8217;t exist and rejecting the belief that something does exist, for it should be apparent that there is a huge difference.</li>
    <li>My favourite comedians of all time are <a href="http://www.youtube.com/watch?v=hYytaZ06Hco">Ricky Gervais</a>, <a href="http://www.youtube.com/watch?v=MvgN5gCuLac">George Carlin</a>, <a href="http://www.youtube.com/watch?v=QvOQxeQKrdw">Frankie Boyle</a> and <a href="http://www.youtube.com/watch?v=Q95kX_EP2Nk">Bill Hicks</a> (watch all the videos!).</li>
    <li>I hate running, but I absolutely love cycling!</li>
    <li>I don&#8217;t understand Node.js. I really did try, but it just ended up confusing me. I&#8217;m not a Linux wizz so installing it was trouble enough.</li>
    <li>I think modern day advertising and marketing techniques are the bane of western society. Oh, and politicians!</li>
    <li>I didn&#8217;t care for the World Cup, and I always find it amusing how people shout at the TV and put flags on their cars when it won&#8217;t have the slightest effect on the game itself.</li>
    <li>I&#8217;m trying to become a vegetarian. Watch the documentary, <a href="http://www.earthlings.com/">Earthlings</a>, and you&#8217;ll understand why.</li>
    <li>Pixar <a href="http://www.imdb.com/title/tt0435761/">made me cry</a>. I don&#8217;t know how they did it&#8230;</li>
    <li>I&#8217;d love to know how to play a musical instrument properly. Preferably the piano.</li>
    <li>I think humans have a responsibility to stop using non-renewable resources, but I don&#8217;t think playing the blame-game is helpful. I also don&#8217;t think change will happen given the current political and economic powers that be.</li>
    <li>I have a love-hate relationship with PHP. Doing most things is dead simple (which is great), but it&#8217;s such an ugly language!</li>
    <li>Even after all this time, jQuery is still my favourite JavaScript library. It&#8217;s small, intuitive and doesn&#8217;t require me to adopt a new programming paradigm!</li>
    <li>Other movies that have made me weep like a baby include <a href="http://www.imdb.com/title/tt1277737/">The Stoning of Soraya M</a>, <a href="http://www.imdb.com/title/tt0109830/">Forrest Gump</a>, <a href="http://www.imdb.com/title/tt0078950/">The Champ</a> and <a href="http://www.imdb.com/title/tt0223897/">Pay It Forward</a>.</li>
</ul>

<p>Okay, that&#8217;s enough for today. Comment if you want. If you disagree with me on any of these points, then, GOOD! This world would be such a dull place without such varied opinions and people!</p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/general/me/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Replacing text in the DOM… it’s not that simple!</title>
		<link>http://james.padolsey.com/javascript/replacing-text-in-the-dom-its-not-that-simple/</link>
		<comments>http://james.padolsey.com/javascript/replacing-text-in-the-dom-its-not-that-simple/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 06:07:23 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1601</guid>
		<description><![CDATA[Finding and replacing strings of text in a DOM document is very tricky, especially if you&#8217;re looking to do it properly and entirely unobtrusively.

In this context, &#8220;unobtrusive&#8221; means affecting the page in a minimally invasive manner &#8212; minimal DOM destruction, no un-called-for normalizing of&#8230;]]></description>
			<content:encoded><![CDATA[<p>Finding and replacing strings of text in a DOM document is very tricky, especially if you&#8217;re looking to do it properly and entirely unobtrusively.</p>

<p>In this context, &#8220;unobtrusive&#8221; means affecting the page in a minimally invasive manner &#8212; minimal DOM destruction, no un-called-for normalizing of text nodes (i.e. joining separate text-nodes together) etc.</p>

<p>Essentially, what I&#8217;m talking about is finding a specific piece of text in a page or a piece of text that matches a pattern and then doing something with it &#8212; possibly wrapping it in an element or changing it in some other way.</p>

<p>Imagine that we have the following paragraph:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>This order's reference number is RF83297.<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span></pre></div></div>




<p>We want to locate the reference number and wrap it in an anchor that leads to the order&#8217;s page (pretend that we&#8217;re making a bookmarklet to enhance the admin panel of some online store). Given what we know about the HTML structure this can be quite easy:</p>

<p><em>(Using jQuery)</em></p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">jQuery<span class="br0">&#40;</span><span class="st0">'p'</span><span class="br0">&#41;</span>.<span class="me1">each</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> p <span class="sy0">=</span> $<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    p.<span class="me1">html</span><span class="br0">&#40;</span>
        p.<span class="me1">text</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span>
            <span class="co2">/\bRF\d{5}/g</span><span class="sy0">,</span>
            <span class="st0">'&lt;a href=&quot;/order/$&amp;&quot;&gt;$&amp;&lt;/a&gt;'</span>
        <span class="br0">&#41;</span>
    <span class="br0">&#41;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>The problem with this approach is that it breaks once you add any elements to any of the paragraphs on the page. It sets the content of the the element to the (replaced) text of that very element, by definition destroying any non-text nodes in the process, or, to put it poetically, it flattens the DOM structure of any given paragraph.</p>

<p>Additionally, the above technique does not care to avoid paragraphs that do not contain a match for the pattern &#8212; it&#8217;ll blindly flatten all elements within the paragraphs&#8230;</p>

<span id="more-1601"></span>

<p>Sure, we could fix it up a bit by making sure that it only messes with paragraphs that contain a match for the pattern (<code>/\bRF\d{5}/g</code>) but we&#8217;re still faced with the obtrusive destruction of each matching paragraph&#8217;s inner-DOM structure.</p>

<p>If there happened to be another link in the paragraph, it&#8217;d be wiped:</p>

<p>Before replacement:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>
    <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;/admin&quot;</span>&gt;</span>Go back to admin!<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="kw2">br</span><span class="sy0">/</span>&gt;</span>
    This order's reference number is RF83297.
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span></pre></div></div>




<p>After replacement:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>
    Go back to admin!
    This order's reference number is <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;/order/RF83297&quot;</span>&gt;</span>RF83297<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;</span>.
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span></pre></div></div>




<p>So, to be appropriately blunt, this is obviously a terrible technique and should be avoided at all costs.</p>

<p><strong>EDIT</strong>: The reason it would also be a bad idea to do something like <code>p.html( p.html.replace(...) );</code> is because you&#8217;d have to have some way of avoiding text in HTML attributes/tags (which, in itself, would require a messy regular expression) and you&#8217;d be destroying what elements currently exist within the paragraph &#8212; yes, the HTML would be the same following the replacement, but the elements themselves would have changed &#8212; meaning that event handlers and other bound data would be lost.</p>

<h3>The right way</h3>

<p>Whether we like it or not, the correct way to handle text in a DOM structure is to get intimate with the text nodes themselves. Text nodes aren&#8217;t that different from element nodes (the ones you&#8217;re used to dealing with) &#8212; the key differences are:</p>

<ul>
    <li>Text nodes don&#8217;t have descendents (or <code>childNodes</code>).</li>
    <li>Almost everything you would want to know about a text node will be contained in its <code>data</code> (or <code>nodeValue</code>) property, which contains whatever text the node encapsulates.</li>
    <li>Text nodes don&#8217;t fire events, can&#8217;t have any styles applied, and are pretty useless at everything except holding a piece of text!</li>
</ul>

<p>These text nodes will appear in the DOM structure just like element nodes. If we consider this paragraph again:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>
    <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;/admin&quot;</span>&gt;</span>Go back to admin!<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="kw2">br</span><span class="sy0">/</span>&gt;</span>
    This order's reference number is RF83297.
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span></pre></div></div>




<p>Its DOM structure is as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">-&gt; P ELEMENT
    -&gt; TEXT NODE (data: &quot;\n   &quot;)
    -&gt; A ELEMENT (href: &quot;/admin&quot;)
        -&gt; TEXT NODE (data: &quot;Go back to admin!&quot;)
    -&gt; BR ELEMENT
    -&gt; TEXT NODE (data: &quot;\n    This order's reference number is RF83297.\n&quot;)</pre></div></div>




<p>Firebug&#8217;s your friend:</p>

<p><img src="http://img811.imageshack.us/img811/462/scr1278440259.png"/></p>

<p>We don&#8217;t know which text node we&#8217;ll find the reference number in so our only choice is to traverse and test all text nodes, including the nested ones. This in itself is quite simple:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">// Pretending we have more than one paragraph to look through</span>
jQuery<span class="br0">&#40;</span><span class="st0">'p'</span><span class="br0">&#41;</span>.<span class="me1">each</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    traverseChildNodes<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw2">function</span> traverseChildNodes<span class="br0">&#40;</span>node<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> next<span class="sy0">;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span>node.<span class="me1">nodeType</span> <span class="sy0">===</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="co1">// (Element node)</span>
&nbsp;
        <span class="kw1">if</span> <span class="br0">&#40;</span>node <span class="sy0">=</span> node.<span class="me1">firstChild</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="kw1">do</span> <span class="br0">&#123;</span>
                <span class="co1">// Recursively call traverseChildNodes</span>
                <span class="co1">// on each child node</span>
                next <span class="sy0">=</span> node.<span class="me1">nextSibling</span><span class="sy0">;</span>
                traverseChildNodes<span class="br0">&#40;</span>node<span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span> <span class="kw1">while</span><span class="br0">&#40;</span>node <span class="sy0">=</span> next<span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
&nbsp;
    <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>node.<span class="me1">nodeType</span> <span class="sy0">===</span> <span class="nu0">3</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="co1">// (Text node)</span>
&nbsp;
        <span class="kw1">if</span> <span class="br0">&#40;</span><span class="co2">/\bRF\d{5}/</span>.<span class="me1">test</span><span class="br0">&#40;</span>node.<span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="co1">// Do something interesting here</span>
            <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'FOUND A MATCH!'</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
&nbsp;
    <span class="br0">&#125;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>





<p>Finding a match isn&#8217;t too tricky, but replacing the matched portion of a text node with an element (wrapping it with the anchor) can be troublesome. Fortunately we can call on the useful <code>innerHTML</code> trick to create an out-of-DOM collection of nodes and add them one by one.</p>

<p>First, let&#8217;s adjust our <code>traverseChildNodes</code> so that it calls <code>wrapMatchesInNode</code> whenever it finds a node that matches:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">// ....</span>
<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>node.<span class="me1">nodeType</span> <span class="sy0">===</span> <span class="nu0">3</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="co1">// (Text node)</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="co2">/\bRF\d{5}/</span>.<span class="me1">test</span><span class="br0">&#40;</span>node.<span class="me1">data</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        wrapMatchesInNode<span class="br0">&#40;</span>node<span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
<span class="br0">&#125;</span>
<span class="co1">// ....</span></pre></div></div>




<p><code>wrapMatchesInNode</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">function</span> wrapMatchesInNode<span class="br0">&#40;</span>textNode<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> temp <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    temp.<span class="me1">innerHTML</span> <span class="sy0">=</span> textNode.<span class="me1">data</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/\bRF\d{5}/g</span><span class="sy0">,</span> <span class="st0">'&lt;a href=&quot;/order/$&amp;&quot;&gt;$&amp;&lt;/a&gt;'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// temp.innerHTML is now:</span>
    <span class="co1">// &quot;\n    This order's reference number is &lt;a href=&quot;/order/RF83297&quot;&gt;RF83297&lt;/a&gt;.\n&quot;</span>
    <span class="co1">// |_______________________________________|__________________________________|___|</span>
    <span class="co1">//                     |                                      |                 |</span>
    <span class="co1">//                 TEXT NODE                             ELEMENT NODE       TEXT NODE</span>
&nbsp;
    <span class="co1">// Extract produced nodes and insert them</span>
    <span class="co1">// before original textNode:</span>
    <span class="kw1">while</span> <span class="br0">&#40;</span>temp.<span class="me1">firstChild</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        console.<span class="me1">log</span><span class="br0">&#40;</span>temp.<span class="me1">firstChild</span>.<span class="me1">nodeType</span><span class="br0">&#41;</span><span class="sy0">;</span>
        textNode.<span class="me1">parentNode</span>.<span class="me1">insertBefore</span><span class="br0">&#40;</span>textNode<span class="sy0">,</span> temp.<span class="me1">firstChild</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
    <span class="co1">// Logged: 3,1,3</span>
&nbsp;
    <span class="co1">// Remove original text-node:</span>
    textNode.<span class="me1">parentNode</span>.<span class="me1">removeChild</span><span class="br0">&#40;</span>textNode<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>




<p>That&#8217;ll work quite nicely. The result:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>
    <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;/admin&quot;</span>&gt;</span>Go back to admin!<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;&lt;<span class="kw2">br</span><span class="sy0">/</span>&gt;</span>
    This order's reference number is <span class="sc2">&lt;<span class="kw2">a</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;/order/RF83297&quot;</span>&gt;</span>RF83297<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">a</span>&gt;</span>.
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span></pre></div></div>




<p>But now we face another problem&#8230;</p>

<p>A given chunk of text in a DOM snippet is not guaranteed to be encapsulated within a single text node. The HTML parsed by the browser will produce single DOM nodes from uninterrupted strings of text, such as what&#8217;s within this <code>DIV</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span>
    Nothing but text.
    No elements.
    No comments.
    Nada...
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">div</span>&gt;</span></pre></div></div>




<p>&#8230; But, any extra text appended to that element will not merge into the already-existing text node, unless, of course, you&#8217;re using <code>innerHTML</code>/<code>innerText</code> (<code>/textContent</code>) to set your content.</p>

<p>So, it&#8217;s possible &#8212; not likely, but possible that we will encounter our reference number in two or more text nodes. For example:</p>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">-&gt; TEXT NODE (data: RF)
-&gt; TEXT NODE (data: 832)
-&gt; TEXT NODE (data: 97)</pre></div></div>




<p>This occurance will not be noticed by our current solution, since it treats each text-node as its own &#8220;haystack&#8221;.</p>

<p>Before we discuss solutions to this, we must first cover other potential issues. Consider this:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">span</span>&gt;</span>RF<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">span</span>&gt;</span>83297</pre></div></div>




<p>A similar problem occurs here &#8212; the text is separated, both parts in separate text-nodes &#8212; one nested in an element. It may seem as though I&#8217;m stretching the reference-number example but please remember that it&#8217;s just an example: what I&#8217;m trying to cover is the complexities involved in getting what is seemingly a simple operation to work correctly.</p>

<p>If we are to match a string of text, even when part of it is wrapped in arbitrary elements (like above), what elements should we allow? Surely not block-level elements? Well, of course, but this means that we need to test the computed style of every traversed element to see if its &#8220;inline&#8221; or otherwise.</p>

<p>Let&#8217;s consider an abstraction that solves all the covered issues. It let&#8217;s you search a specified root node for occurrences of a string and let&#8217;s you replace with whatever HTML you want &#8212; allowing you to wrap it in an anchor element, for example. But, what happens in cases like this:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">p</span>&gt;</span>
    ...
    This order's reference <span class="sc2">&lt;<span class="kw2">em</span>&gt;</span>number is RF<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">em</span>&gt;</span>83297.
<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">p</span>&gt;</span></pre></div></div>




<p>Wrapping <code>RF&lt;/em&gt;83297</code> in <code>&lt;a&gt;...&lt;/a&gt;</code> would produce invalid HTML&#8230;</p>

<p>So it seems that, while possible, a solution that protects against all of the potential problems is likely to be slow and, in the end, simply not worth it.</p>

<p>The only viable solution, in my eyes, is to forget about matching strings that are interrupted with HTML elements (like <code>&lt;em&gt;RF&lt;/em&gt;83297</code>). Only test text-node data, and to handle neighbouring text nodes merge them together or to be truly &#8220;unobtrusive&#8221; collect up data in neighbouring text nodes and test the collected text at the end.</p>

<p>That&#8217;s really all I have to say on the matter. I hope I didn&#8217;t coerce you down the rabbit hole with the false promise of an all-encompassing solution&#8230; I simply don&#8217;t have one!</p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/replacing-text-in-the-dom-its-not-that-simple/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Creating fairies</title>
		<link>http://james.padolsey.com/javascript/creating-fairies/</link>
		<comments>http://james.padolsey.com/javascript/creating-fairies/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 15:02:18 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1583</guid>
		<description><![CDATA[I wanted to give a brief overview of the techniques involved in creating <a href="http://jamespadolsey.github.com/Fairy/"><strong>this</strong></a>. It&#8217;s slightly pointless but still quite fun and I think there are a few notable aspects of its implementation that are worth writing about.

It is a &#8220;Fairy&#8221; generator that creates&#8230;]]></description>
			<content:encoded><![CDATA[<p>I wanted to give a brief overview of the techniques involved in creating <a href="http://jamespadolsey.github.com/Fairy/"><strong>this</strong></a>. It&#8217;s slightly pointless but still quite fun and I think there are a few notable aspects of its implementation that are worth writing about.</p>

<p>It is a &#8220;Fairy&#8221; generator that creates small pulsating elements and moves them around the viewport in random directions, but not too eratically. You can load some fairies on this page by <a href="javascript:(function(){if(window.fairyEnvironment&#038;&#038;fairyEnvironment.Fairy){return init()}var s=document.documentElement.appendChild(document.createElement('script')),t=setInterval(function(){if(window.fairyEnvironment&#038;&#038;fairyEnvironment.Fairy){clearInterval(t);s.parentNode.removeChild(s);init()}},50);s.src='http://github.com/jamespadolsey/Fairy/raw/master/fairy.js';function init(){var d=document.body.appendChild(document.createElement('div')),docEl=document.documentElement,body=document.body,winHeight,resize=function(){winHeight=window.innerHeight||docEl.clientHeight||body.clientHeight;fairyEnvironment.bounds.right=Math.max(docEl.clientWidth,docEl.offsetWidth);scroll()},scroll=function(){fairyEnvironment.bounds.top=Math.max(~~window.pageYOffset,body.scrollTop,docEl.scrollTop);fairyEnvironment.bounds.left=Math.max(~~window.pageXOffset,body.scrollLeft,docEl.scrollLeft);fairyEnvironment.bounds.bottom=fairyEnvironment.bounds.top+winHeight};resize();if(window.addEventListener){window.addEventListener('resize',resize,false);window.addEventListener('scroll',scroll,false)}else{window.attachEvent('onresize',resize);window.attachEvent('onscroll',scroll)}fairyEnvironment.spawn(25,function(){if(this.dom){d.appendChild(this.dom);this.start()}})}}());"><strong>clicking this bookmarklet</strong></a>!</p>

<p>The original problem was that I had been mentally locked-in to a specific type of animation on the client-side and I would sit there thinking, &#8220;Okay, how do I animate this element from &#8216;a&#8217; to &#8216;b&#8217; while taking random detours and going in random directions?&#8221;&#8230; I was still in the conventional client-side animation mindset, where you take an element and call an animation function to mutate certain CSS properties over a specified duration. The prospect of doing it via manual calls to <code>setInterval</code>, with <code>delta-x/y</code> values never crossed my mind.</p>

<p>Eventually it became clear that this would be the only way to make the fairies fly as I wanted &#8212; i.e. not to simply go from &#8216;a&#8217; to &#8216;b&#8217;, but to continually fly around in all directions.</p>

<p>I started with an environment singleton instance, named &#8220;fairyEnvironment&#8221;, containing the various bounds and rules attributed to the current document:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">var</span> fairyEnvironment <span class="sy0">=</span> <span class="kw2">new</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">bounds</span> <span class="sy0">=</span> <span class="br0">&#123;</span>
        left<span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">,</span>
        top<span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">,</span>
        right<span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">,</span>
        bottom<span class="sy0">:</span> <span class="nu0">0</span>
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">speedLimit</span> <span class="sy0">=</span> <span class="br0">&#123;</span>
        high<span class="sy0">:</span> <span class="nu0">6</span><span class="sy0">,</span>
        low<span class="sy0">:</span> <span class="nu0">2</span>
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">spawn</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>amount<span class="sy0">,</span> postCreation<span class="sy0">,</span> config<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="kw2">var</span> ret <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">,</span> i <span class="sy0">=</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span>
&nbsp;
        amount <span class="sy0">=</span> ~~amount
&nbsp;
        <span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy0">++</span>i <span class="sy0">&lt;</span> amount<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            postCreation <span class="sy0">&amp;&amp;</span>
                postCreation.<span class="me1">call</span><span class="br0">&#40;</span>
                    ret<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">new</span> fairyEnvironment.<span class="me1">Fairy</span><span class="br0">&#40;</span>config<span class="br0">&#41;</span>
                <span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
&nbsp;
        <span class="kw1">return</span> ret<span class="sy0">;</span>
&nbsp;
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="sy0">;</span></pre></div></div>




<p>The generated fairies would have to stay within a specific area, defined by the bounds, &#8220;top&#8221;, &#8220;left&#8221;, &#8220;right&#8221; and &#8220;bottom&#8221;. I also specified the upper and lower speed limit and a function to spawn multiple Fairy instances at once. You can see that I&#8217;ve referenced <code>fairyEnvironment.Fairy</code>, which is defined as follows:</p>

<span id="more-1583"></span>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">fairyEnvironment.<span class="me1">Fairy</span> <span class="sy0">=</span> <span class="kw2">function</span> Fairy<span class="br0">&#40;</span>config<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="co1">// Config is optional, defaults apply</span>
    config <span class="sy0">=</span> config <span class="sy0">||</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">bounds</span> <span class="sy0">=</span> fairyEnvironment.<span class="me1">bounds</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">speedLimit</span> <span class="sy0">=</span> fairyEnvironment.<span class="me1">speedLimit</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">timer</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// If no width is specified then generate width between 10 and 30</span>
    <span class="kw1">this</span>.<span class="me1">width</span> <span class="sy0">=</span> config.<span class="me1">width</span> <span class="sy0">||</span> <span class="nu0">0</span> <span class="sy0">|</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="nu0">20</span> <span class="sy0">+</span> <span class="nu0">10</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">height</span> <span class="sy0">=</span> config.<span class="me1">height</span> <span class="sy0">||</span> <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">opacity</span> <span class="sy0">=</span> <span class="nu0">1</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">dOpacity</span> <span class="sy0">=</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> .1<span class="sy0">;</span>
&nbsp;
    <span class="co1">// If no speed is specified then genarate a random width between</span>
    <span class="co1">// the upper and lower limits specified in FairyEnvironment</span>
    <span class="kw1">this</span>.<span class="me1">speed</span> <span class="sy0">=</span> config.<span class="me1">speed</span> <span class="sy0">||</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span>
                 <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">speedLimit</span>.<span class="me1">high</span> <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">speedLimit</span>.<span class="me1">low</span><span class="br0">&#41;</span>
                 <span class="sy0">+</span> <span class="kw1">this</span>.<span class="me1">speedLimit</span>.<span class="me1">low</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">dX</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">dY</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// Setup an arbitrary direction (to get things rolling)</span>
    <span class="kw1">this</span>.<span class="me1">shiftDirection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// If no color is specified then generate one randomly</span>
    <span class="co1">// Note that this will generate intensities between 155 and 255</span>
    <span class="kw1">this</span>.<span class="me1">color</span> <span class="sy0">=</span> config.<span class="me1">color</span> <span class="sy0">||</span> <span class="br0">&#91;</span>
        <span class="nu0">0</span><span class="sy0">|</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="sy0">+</span><span class="nu0">155</span><span class="sy0">,</span>
        <span class="nu0">0</span><span class="sy0">|</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="sy0">+</span><span class="nu0">155</span><span class="sy0">,</span>
        <span class="nu0">0</span><span class="sy0">|</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="sy0">+</span><span class="nu0">155</span>
    <span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// Spawn the fairy somewhere random</span>
    <span class="kw1">this</span>.<span class="me1">y</span> <span class="sy0">=</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">bounds</span>.<span class="me1">bottom</span> <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">height</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">x</span> <span class="sy0">=</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">bounds</span>.<span class="me1">right</span> <span class="sy0">-</span> <span class="kw1">this</span>.<span class="me1">width</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// Build the canvas</span>
    <span class="co1">// Note, this doesn't HAVE to be a canvas - it could</span>
    <span class="co1">// just be a regular DOM element</span>
    <span class="kw1">this</span>.<span class="me1">dom</span> <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">build</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// set initial position</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">dom</span><span class="br0">&#41;</span> <span class="kw1">this</span>.<span class="me1">step</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> 
&nbsp;
<span class="br0">&#125;</span><span class="sy0">;</span></pre></td></tr></table></div>




<p>The <code>dX</code> and <code>dY</code> properties are probably the most important. The &#8216;d&#8217; stands for &#8220;delta&#8221; which means the difference between two things &#8212; here it means the change that the <code>x</code> and <code>y</code> properties will experience on each step of the animation. So, if <code>dX</code> is set to <code>5</code> then the fairy will move five pixels to the right on every step of the animation. The <code>dX</code> and <code>dY</code> values can be changed at any time, before or after each step, thus producing changes in speed and direction.</p>

<p>The <code>speed</code> property (line 20) defines the limits of <code>dX</code> and <code>dY</code>. So, if the speed is set as 10 then the delta values can only go up to ten (either positive or negative) &#8212; so, <code>dX</code> would be able to change from <code>-10</code> to <code>+10</code>.</p>

<p>I&#8217;ve also used both the double-bitwise-not (<code>~~</code>) and bitwise-or (<code>|</code> &#8211; but with zero as left-hand operand &#8211; <code>0|</code>) operators quite a lot &#8212; in essence, they both floor the right-hand-side operand (i.e. number -&gt; integer). They&#8217;re better than <code>Math.floor</code> because they return a number (zero) even from <code>Undefined</code>, <code>Null</code>, <code>NaN</code>, and <code>Infinity</code> operands. <code>0|</code> is used instead of <code>~~</code> in some places simply because <code>|</code> (bitwise-or) has a lower <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Operator_Precedence">precedence</a> than <code>~</code> (bitwise-not), meaning that it can be used in expressions like <code>0|a*b+c</code> without having to wrap <code>a*b+c</code> in parenthesis (i.e. <code>~~(a*b+c)</code>). You can read more about this <a href="http://james.padolsey.com/javascript/double-bitwise-not/">&#8220;flooring&#8221; operation here</a>.</p>

<p>I&#8217;ve also used <code>Math.random()</code> a lot, e.g.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">// If no color is specified then generate one randomly</span>
<span class="co1">// Note that this will generate intensities between 155 and 255</span>
<span class="kw1">this</span>.<span class="me1">color</span> <span class="sy0">=</span> config.<span class="me1">color</span> <span class="sy0">||</span> <span class="br0">&#91;</span>
    <span class="nu0">0</span><span class="sy0">|</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="sy0">+</span><span class="nu0">155</span><span class="sy0">,</span> <span class="co1">// Red</span>
    <span class="nu0">0</span><span class="sy0">|</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="sy0">+</span><span class="nu0">155</span><span class="sy0">,</span> <span class="co1">// Green</span>
    <span class="nu0">0</span><span class="sy0">|</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">100</span><span class="sy0">+</span><span class="nu0">155</span>  <span class="co1">// Blue</span>
<span class="br0">&#93;</span><span class="sy0">;</span></pre></div></div>




<p>Generating a random number between two bounds is quite simple:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="br0">&#40;</span>upperBound <span class="sy0">-</span> lowerBound<span class="br0">&#41;</span> <span class="sy0">+</span> lowerBound</pre></div></div>




<p><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Math/random"><code>Math.random()</code></a> generates a number from zero to just below one (never one). Note that the lower bound is inclusive and the upper bound is exclusive.</p>

<p>This generated color is used when creating and painting the canvas:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="coMULTI">/* fairyEnvironment.Fairy.prototype = { ... */</span>
build<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="co1">// Create &lt;canvas&gt;</span>
&nbsp;
    <span class="kw2">var</span> c <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'canvas'</span><span class="br0">&#41;</span><span class="sy0">,</span>
        _ <span class="sy0">=</span> c.<span class="me1">getContext</span> <span class="sy0">&amp;&amp;</span> c.<span class="me1">getContext</span><span class="br0">&#40;</span><span class="st0">'2d'</span><span class="br0">&#41;</span><span class="sy0">,</span>
        color <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">color</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>_<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="co1">// Just for IE :D</span>
        <span class="kw2">var</span> d <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span><span class="sy0">;</span>
        d.<span class="me1">style</span>.<span class="me1">fontSize</span> <span class="sy0">=</span> <span class="st0">'12px'</span><span class="sy0">;</span>
        d.<span class="me1">style</span>.<span class="me1">fontFamily</span> <span class="sy0">=</span> <span class="st0">'monospace'</span><span class="sy0">;</span>
        d.<span class="me1">style</span>.<span class="me1">position</span> <span class="sy0">=</span> <span class="st0">'absolute'</span><span class="sy0">;</span>
        d.<span class="me1">style</span>.<span class="me1">color</span> <span class="sy0">=</span> <span class="st0">'#FFF'</span><span class="sy0">;</span>
        d.<span class="me1">style</span>.<span class="me1">background</span> <span class="sy0">=</span> <span class="st0">'#000'</span><span class="sy0">;</span>
        d.<span class="me1">innerHTML</span> <span class="sy0">=</span> <span class="st0">'IE SUCKS'</span><span class="sy0">;</span>
        <span class="kw1">this</span>.<span class="me1">width</span> <span class="sy0">=</span> <span class="nu0">48</span><span class="sy0">;</span>
        <span class="kw1">return</span> d<span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    c.<span class="me1">width</span> <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">;</span>
    c.<span class="me1">height</span> <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">height</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// Create radial gradient to make it Fairy-like</span>
    <span class="kw2">var</span> grad <span class="sy0">=</span> _.<span class="me1">createRadialGradient</span><span class="br0">&#40;</span>
        <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">/</span><span class="nu0">2</span><span class="sy0">,</span>
        <span class="kw1">this</span>.<span class="me1">height</span><span class="sy0">/</span><span class="nu0">2</span><span class="sy0">,</span>
        <span class="nu0">0</span><span class="sy0">,</span>
        <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">/</span><span class="nu0">2</span><span class="sy0">,</span>
        <span class="kw1">this</span>.<span class="me1">height</span><span class="sy0">/</span><span class="nu0">2</span><span class="sy0">,</span>
        <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">/</span><span class="nu0">2</span>
    <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    grad.<span class="me1">addColorStop</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="st0">'rgba('</span> <span class="sy0">+</span> color.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">',1)'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    grad.<span class="me1">addColorStop</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="st0">'rgba('</span> <span class="sy0">+</span> color.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">',0)'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    _.<span class="me1">fillStyle</span> <span class="sy0">=</span> grad<span class="sy0">;</span>
    _.<span class="me1">fillRect</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">,</span> <span class="kw1">this</span>.<span class="me1">height</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    c.<span class="me1">style</span>.<span class="me1">position</span> <span class="sy0">=</span> <span class="st0">'absolute'</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">return</span> c<span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="coMULTI">/*,...};*/</span></pre></div></div>




<p>Jacob Seidelin&#8217;s <a href="http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html">canvas cheatsheet</a> was infinitely useful during this endeavour. I don&#8217;t yet use canvas enough to know its API well enough &#8212; one day perhaps&#8230;</p>

<p>As you can see in the Fairy constructor, the return value of <code>build()</code> is assigned to <code>instance.dom</code> (line 43: <code>this.dom = this.build();</code>). Whoever instantiates the fairy is expected to add the canvas to the document. A simple example:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">var</span> myFairy <span class="sy0">=</span> <span class="kw2">new</span> fairyEnvironment.<span class="me1">Fairy</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
document.<span class="me1">body</span>.<span class="me1">appendChild</span><span class="br0">&#40;</span>myFairy.<span class="me1">dom</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// append to document</span>
myFairy.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>Or, with our useful <code>spawn</code> method:</code>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">fairyEnvironment.<span class="me1">spawn</span><span class="br0">&#40;</span><span class="nu0">25</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    document.<span class="me1">body</span>.<span class="me1">appendChild</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">dom</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>Calling <code>start()</code> begins the animation with a simple call to <code>setInterval</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">start<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">var</span> hoc <span class="sy0">=</span> <span class="kw1">this</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">timer</span> <span class="sy0">=</span> setInterval<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
        hoc.<span class="me1">step</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span><span class="sy0">,</span> <span class="nu0">30</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>




<p>The <code>step()</code> method is run every 30 milliseconds, which equates to about 33 frames per second. It could probably be made a little more infrequent though -- although the jury is still out on <a href="http://www.100fps.com/how_many_frames_can_humans_see.htm">the perfect FPS</a>.</code>

<p>The <code>step()</code> method involves a number of simple operations. This is where abstraction really starts to shine:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">step<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw1">this</span>.<span class="me1">detectEdges</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="kw1">this</span>.<span class="me1">shiftDirection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">limitSpeed</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">dom</span>.<span class="me1">style</span>.<span class="me1">left</span> <span class="sy0">=</span> ~~<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">x</span> <span class="sy0">+=</span> <span class="kw1">this</span>.<span class="me1">dX</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span>
    <span class="kw1">this</span>.<span class="me1">dom</span>.<span class="me1">style</span>.<span class="me1">top</span> <span class="sy0">=</span> ~~<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">y</span> <span class="sy0">+=</span> <span class="kw1">this</span>.<span class="me1">dY</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">pulse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>




<p>With the right level of abstraction and proper naming one can do away with the clutter caused by the overuse of comments. The only possibly questionable area in the above method is this:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw1">this</span>.<span class="me1">dom</span>.<span class="me1">style</span>.<span class="me1">left</span> <span class="sy0">=</span> ~~<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">x</span> <span class="sy0">+=</span> <span class="kw1">this</span>.<span class="me1">dX</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span>
<span class="kw1">this</span>.<span class="me1">dom</span>.<span class="me1">style</span>.<span class="me1">top</span> <span class="sy0">=</span> ~~<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">y</span> <span class="sy0">+=</span> <span class="kw1">this</span>.<span class="me1">dY</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">'px'</span><span class="sy0">;</span></pre></div></div>




<p>We've already established what <code>~~</code> does. One important thing that happens here, which would be easy to miss, is the expression <code>this.x += this.dX</code> which adds the <code>dX</code> (delta-x) value to the current <code>x</code> value and then returns the result of that addition. Retaining state using <code>this.x</code> is much better than having to re-query <code>this.dom.style.left</code> on every step.</p>

<p>As logic would dictate, the <code>detectEdges()</code> method determines whether the fairy is too close to any of the bounds specified in <code>fairyEnvironment.bounds</code>, and if it is then it takes action by calling <code>turnAway()</code>.</p>

<p><code>detectEdges()</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">detectEdges<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="co1">// If the fairy is too close to an edge (padding is fixed at 60px)</span>
    <span class="co1">// then slowly turn away... </span>
&nbsp;
    <span class="kw2">var</span> x <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">x</span><span class="sy0">,</span>
        y <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">y</span><span class="sy0">,</span>
        w <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">width</span><span class="sy0">,</span>
        h <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">height</span><span class="sy0">,</span>
        bounds <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">bounds</span><span class="sy0">,</span>
        padding <span class="sy0">=</span> <span class="nu0">60</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span>x <span class="sy0">&lt;</span> padding <span class="sy0">+</span> bounds.<span class="me1">left</span><span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">turnAway</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">LEFT_EDGE</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>y <span class="sy0">&lt;</span> padding <span class="sy0">+</span> bounds.<span class="me1">top</span><span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">turnAway</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">TOP_EDGE</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>x <span class="sy0">+</span> w <span class="sy0">&gt;</span> bounds.<span class="me1">right</span> <span class="sy0">-</span> padding<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">turnAway</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">RIGHT_EDGE</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>y <span class="sy0">+</span> h <span class="sy0">&gt;</span> bounds.<span class="me1">bottom</span> <span class="sy0">-</span> padding<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">turnAway</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">BOTTOM_EDGE</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>





<p><code>turnAway()</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">turnAway<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span>fromEdge<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span>fromEdge <span class="sy0">===</span> <span class="kw1">this</span>.<span class="me1">TOP_EDGE</span> <span class="sy0">||</span> fromEdge <span class="sy0">===</span> <span class="kw1">this</span>.<span class="me1">BOTTOM_EDGE</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="co1">// SLowly start inverting Y</span>
        <span class="kw1">this</span>.<span class="me1">dY</span> <span class="sy0">+=</span> fromEdge <span class="sy0">===</span> <span class="kw1">this</span>.<span class="me1">TOP_EDGE</span> <span class="sy0">?</span> <span class="nu0">1</span> <span class="sy0">:</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span>
        <span class="kw1">this</span>.<span class="me1">compensate</span><span class="br0">&#40;</span><span class="st0">'X'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
        <span class="co1">// Slowly start inverting X</span>
        <span class="kw1">this</span>.<span class="me1">dX</span> <span class="sy0">+=</span> fromEdge <span class="sy0">===</span> <span class="kw1">this</span>.<span class="me1">LEFT_EDGE</span> <span class="sy0">?</span> <span class="nu0">1</span> <span class="sy0">:</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span>
        <span class="kw1">this</span>.<span class="me1">compensate</span><span class="br0">&#40;</span><span class="st0">'Y'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    <span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>




<p>The <code>compensate()</code> method takes a single axis as its argument and makes sure that the full speed of the fairy is being expressed on both <code>dX</code> and <code>dY</code>. For example, if the speed is 10 and <code>dX</code> has been set to 3, then <code>compensate</code> will change <code>dY</code> to either -7 or +7 dependent on its current direction. <code>abs(dX)</code> plus <code>abs(dY)</code> must always equal <code>speed</code>.</p>

<p>The <code>shiftDirection()</code> method is called by <code>step()</code>, but only when the fairy is not near any edges. This method will randomly shift the direction of the fairy:</code></p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">shiftDirection<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="co1">// Only change direction 30% of the time</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">&gt;</span> .7<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="kw1">this</span>.<span class="me1">dX</span> <span class="sy0">+=</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="nu0">2</span> <span class="sy0">-</span> <span class="nu0">1</span><span class="sy0">;</span> <span class="co1">// between 1 &amp; -1</span>
        <span class="kw1">this</span>.<span class="me1">compensate</span><span class="br0">&#40;</span><span class="st0">'Y'</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>




<p>I might make this configurable in the future but right now it will only change the direction 30% of the time, and only one pixel at a time.</p>

<p>The pulsating opacity of the fairies is achieved with a very rudimentary <code>pulse()</code> method:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">pulse<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">opacity</span> <span class="sy0">&gt;=</span> <span class="nu0">1</span> <span class="sy0">||</span> <span class="kw1">this</span>.<span class="me1">opacity</span> <span class="sy0">&lt;=</span> .6<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="kw1">this</span>.<span class="me1">dOpacity</span> <span class="sy0">=</span> <span class="sy0">-</span><span class="kw1">this</span>.<span class="me1">dOpacity</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">dom</span>.<span class="me1">style</span>.<span class="me1">opacity</span> <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">opacity</span> <span class="sy0">+=</span> <span class="kw1">this</span>.<span class="me1">dOpacity</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>




<p>The opacity pulses between 0.6 and 1. <code>dOpacity</code> is set in the <code>Fairy</code> constructor to a number between zero and 0.1:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>16
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw1">this</span>.<span class="me1">dOpacity</span> <span class="sy0">=</span> Math.<span class="me1">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> .1<span class="sy0">;</span></pre></td></tr></table></div>




<h3>That's it!</h3>

<p>Like I said: quite pointless yet quite fun. You can check out the Github repo over here:</p>

<p class="video"><strong><a href="http://github.com/jamespadolsey/Fairy">"Fairy" on Github</a></strong></p>

<h3>The bookmarklet</h3>

<p>The bookmarklet loads the Fairy script from Github and then spawns 25 fairies. It also listens for the window's <code>scroll</code> and <code>resize</code> events so that it can change the bounds of fairyEnvironment according to where you are in the document. You can see this in action by <a href="javascript:(function(){if(window.fairyEnvironment&#038;&#038;fairyEnvironment.Fairy){return init()}var s=document.documentElement.appendChild(document.createElement('script')),t=setInterval(function(){if(window.fairyEnvironment&#038;&#038;fairyEnvironment.Fairy){clearInterval(t);s.parentNode.removeChild(s);init()}},50);s.src='http://github.com/jamespadolsey/Fairy/raw/master/fairy.js';function init(){var d=document.body.appendChild(document.createElement('div')),docEl=document.documentElement,body=document.body,winHeight,resize=function(){winHeight=window.innerHeight||docEl.clientHeight||body.clientHeight;fairyEnvironment.bounds.right=Math.max(docEl.clientWidth,docEl.offsetWidth);scroll()},scroll=function(){fairyEnvironment.bounds.top=Math.max(~~window.pageYOffset,body.scrollTop,docEl.scrollTop);fairyEnvironment.bounds.left=Math.max(~~window.pageXOffset,body.scrollLeft,docEl.scrollLeft);fairyEnvironment.bounds.bottom=fairyEnvironment.bounds.top+winHeight};resize();if(window.addEventListener){window.addEventListener('resize',resize,false);window.addEventListener('scroll',scroll,false)}else{window.attachEvent('onresize',resize);window.attachEvent('onscroll',scroll)}fairyEnvironment.spawn(25,function(){if(this.dom){d.appendChild(this.dom);this.start()}})}}());"><strong>clicking this</strong></a> and then scrolling up or down -- the fairies will follow you.</p>

<p><a href="http://github.com/jamespadolsey/Fairy/blob/master/bookmarklet-demo.fairy.js">bookmarklet-demo.fairy</a>:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">fairyEnvironment</span> <span class="sy0">&amp;&amp;</span> fairyEnvironment.<span class="me1">Fairy</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="kw1">return</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    <span class="kw2">var</span> s <span class="sy0">=</span> document.<span class="me1">documentElement</span>.<span class="me1">appendChild</span><span class="br0">&#40;</span>document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'script'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span>
        t <span class="sy0">=</span> setInterval<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">fairyEnvironment</span> <span class="sy0">&amp;&amp;</span> fairyEnvironment.<span class="me1">Fairy</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                clearInterval<span class="br0">&#40;</span>t<span class="br0">&#41;</span><span class="sy0">;</span>
                s.<span class="me1">parentNode</span>.<span class="me1">removeChild</span><span class="br0">&#40;</span>s<span class="br0">&#41;</span><span class="sy0">;</span>
                init<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span><span class="sy0">,</span> <span class="nu0">50</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    s.<span class="me1">src</span> <span class="sy0">=</span> <span class="st0">'http://github.com/jamespadolsey/Fairy/raw/master/fairy.js'</span><span class="sy0">;</span>
&nbsp;
    <span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="kw2">var</span> d <span class="sy0">=</span> document.<span class="me1">body</span>.<span class="me1">appendChild</span><span class="br0">&#40;</span>document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span>
            docEl <span class="sy0">=</span> document.<span class="me1">documentElement</span><span class="sy0">,</span>
            body <span class="sy0">=</span> document.<span class="me1">body</span><span class="sy0">,</span>
            winHeight<span class="sy0">,</span>
            resize <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
                winHeight <span class="sy0">=</span> window.<span class="me1">innerHeight</span> <span class="sy0">||</span>
                            docEl.<span class="me1">clientHeight</span> <span class="sy0">||</span>
                            body.<span class="me1">clientHeight</span><span class="sy0">;</span>
&nbsp;
                fairyEnvironment.<span class="me1">bounds</span>.<span class="me1">right</span> <span class="sy0">=</span>
                    Math.<span class="me1">max</span><span class="br0">&#40;</span>docEl.<span class="me1">clientWidth</span><span class="sy0">,</span> docEl.<span class="me1">offsetWidth</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
                <span class="kw3">scroll</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
            <span class="br0">&#125;</span><span class="sy0">,</span>
            <span class="kw3">scroll</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
                fairyEnvironment.<span class="me1">bounds</span>.<span class="me1">top</span> <span class="sy0">=</span>
                    Math.<span class="me1">max</span><span class="br0">&#40;</span>
                        ~~window.<span class="me1">pageYOffset</span><span class="sy0">,</span>
                        body.<span class="me1">scrollTop</span><span class="sy0">,</span>
                        docEl.<span class="me1">scrollTop</span>
                    <span class="br0">&#41;</span><span class="sy0">;</span>
                fairyEnvironment.<span class="me1">bounds</span>.<span class="me1">left</span> <span class="sy0">=</span>
                    Math.<span class="me1">max</span><span class="br0">&#40;</span>
                        ~~window.<span class="me1">pageXOffset</span><span class="sy0">,</span>
                        body.<span class="me1">scrollLeft</span><span class="sy0">,</span>
                        docEl.<span class="me1">scrollLeft</span>
                    <span class="br0">&#41;</span><span class="sy0">;</span>
                fairyEnvironment.<span class="me1">bounds</span>.<span class="me1">bottom</span> <span class="sy0">=</span>
                    fairyEnvironment.<span class="me1">bounds</span>.<span class="me1">top</span> <span class="sy0">+</span> winHeight<span class="sy0">;</span>
&nbsp;
            <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
        resize<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
        <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">addEventListener</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            window.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">'resize'</span><span class="sy0">,</span> resize<span class="sy0">,</span> <span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
            window.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">'scroll'</span><span class="sy0">,</span> <span class="kw3">scroll</span><span class="sy0">,</span> <span class="kw2">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
            window.<span class="me1">attachEvent</span><span class="br0">&#40;</span><span class="st0">'onresize'</span><span class="sy0">,</span> resize<span class="br0">&#41;</span><span class="sy0">;</span>
            window.<span class="me1">attachEvent</span><span class="br0">&#40;</span><span class="st0">'onscroll'</span><span class="sy0">,</span> <span class="kw3">scroll</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
&nbsp;
        fairyEnvironment.<span class="me1">spawn</span><span class="br0">&#40;</span><span class="nu0">25</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
            <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">dom</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                d.<span class="me1">appendChild</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">dom</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="kw1">this</span>.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="br0">&#125;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></table></div>


]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/creating-fairies/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Questioning non UI events</title>
		<link>http://james.padolsey.com/javascript/questioning-non-ui-events/</link>
		<comments>http://james.padolsey.com/javascript/questioning-non-ui-events/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 06:22:31 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1573</guid>
		<description><![CDATA[Without UI events we&#8217;d be totally lost on the client-side &#8212; it is only via User Interface Events that we can know what the user wants to do. User-initiated events such as &#8220;click&#8221;, &#8220;mouseover&#8221; and &#8220;mousemove&#8221; are absolutely essential to upholding a user-centred experience and&#8230;]]></description>
			<content:encoded><![CDATA[<p>Without UI events we&#8217;d be totally lost on the client-side &#8212; it is only via User Interface Events that we can know what the user wants to do. User-initiated events such as &#8220;click&#8221;, &#8220;mouseover&#8221; and &#8220;mousemove&#8221; are absolutely essential to upholding a user-centred experience and I want to make it clear that my quarrel is not with these types of events. Any event that gives us information about users&#8217; intentions is a good event.</p>

<p>I feel that there are bad events too though &#8212; events that we feel we must utilise just because they exist &#8212; and we feel we must build into our APIs just because event-driven design dictates absolute submission to this way of thinking.</p>

<h3>DOM mutation events</h3>

<p>Every single time I&#8217;ve ever considered using a DOM-mutation event I&#8217;ve subsequently discovered that the problem can be better solved by re-architecting the codebase. The <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents">DOM2 mutation events</a> aren&#8217;t well supported in less capable browsers but offer an interesting opportunity &#8212; to listen for document mutation such as attribute changes, node insertion and node removal.</p>

<p>This sounds cool and I&#8217;m sure your mind was buzzing with ideas when you first heard about these events, but have you actually encountered a situation where utilising these events is the only viable solution? If so, I&#8217;d love to hear it.</p>

<span id="more-1573"></span>

<h3>Programmatic events</h3>

<p>This is where I lose all sense of comprehension. The premise is a mechanism that allows you to be notified when changes occur to your program &#8212; i.e. your objects, arrays and functions. I&#8217;m talking about the likes of <code>Object.prototype.watch</code>, IE&#8217;s <code>onPropertyChange</code> and a tonne of other new implementations (<a href="http://wiki.github.com/nje/jquery-datalink/jquery-data-linking-proposal#arraychange">e.g.</a>) that seem to perpetuate a dangerous disconnect of cogs that should be working together.</p>

<p>It seems pointless &#8212; it&#8217;s akin to starting your car, and then being notified by the car that you just started the car&#8230; an entirely redundant notification.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">var</span> a <span class="sy0">=</span> abstraction.<span class="me1">Array</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span><span class="nu0">2</span><span class="sy0">,</span><span class="nu0">3</span><span class="br0">&#41;</span><span class="sy0">;</span>
a.<span class="me1">push</span><span class="br0">&#40;</span><span class="nu0">4</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// &gt; Abstraction says: &quot;You just changed the array&quot;</span>
<span class="co1">// &gt; Me says: &quot;OH RLY&quot;</span></pre></div></div>




<h3>Left hand, meet right hand!</h3>

<p>Events exist so that processes outside the scope of your code can communicate with your code and let you know when certain things occur. Events typically operate up the abstraction chain &#8212; you listen for events from lower-level abstractions. I feel that the &#8220;outside the scope of your code&#8221; aspect is central to the whole concept of events and is why they make so much sense in a browser-scripting environment. The browser listens to events from the operating system and forwards certain events to the DOM where we can listen for them. It&#8217;s a simple fluid concept that works!</p>

<p>There&#8217;s a lot of hype surrounding event-driven programming/design at the moment and it seems that we&#8217;re approaching a risky threshold, where events are used just because they can be, and not because they <em>should</em> be.</p>

<p>If you&#8217;re creating an app, and it requires a great deal of client-side functionality, then you&#8217;re going to need to interface with the DOM to listen for events and apply certain changes. This is what JavaScript is all about. You write the logic layer of code (your own personal API) and then you write the implementation code that utilises the logic layer. You have authored two distinct layers of abstraction. That&#8217;s pretty much the gist of what we do.</p>

<p>What&#8217;s approaching, it seems, is an era of haphazard juggling of third-party scripts, multiple abstractions, multiple APIs and consequently, <em>dozens</em> of events. No need to write a consistently encapsulated logic layer &#8212; you can just bung these plugins/modules/classes into the app&#8230; To heck with maintenance, clean and consistent abstractions, intuitive APIs, self-documenting code and all sense of originality.</p>

<p>I&#8217;m not questioning events in general, and I will admit that they can be very helpful to make two scripts work together, but as I mentioned, I feel there&#8217;s a threshold where it becomes simply foolish&#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/questioning-non-ui-events/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Another JavaScript quiz</title>
		<link>http://james.padolsey.com/javascript/another-javascript-quiz/</link>
		<comments>http://james.padolsey.com/javascript/another-javascript-quiz/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 09:11:02 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ECMAScript]]></category>
		<category><![CDATA[quiz]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1534</guid>
		<description><![CDATA[After attempting <a href="http://perfectionkills.com/javascript-quiz/">multiple</a> <a href="http://dmitry.baranovskiy.com/post/91403200">JavaScript</a> <a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/">quizzes</a> I thought it would be fun to have a go creating one for my readers. It doesn&#8217;t involve any DOM nonsense or browser quirks &#8212; this is just plain ECMAScript (<a href="http://bclary.com/2004/11/07/">3rd edition</a>). It tests your knowledge of the language and specification.

Within each&#8230;]]></description>
			<content:encoded><![CDATA[<p>After attempting <a href="http://perfectionkills.com/javascript-quiz/">multiple</a> <a href="http://dmitry.baranovskiy.com/post/91403200">JavaScript</a> <a href="http://www.nczonline.net/blog/2010/02/16/my-javascript-quiz/">quizzes</a> I thought it would be fun to have a go creating one for my readers. It doesn&#8217;t involve any DOM nonsense or browser quirks &#8212; this is just plain ECMAScript (<a href="http://bclary.com/2004/11/07/">3rd edition</a>). It tests your knowledge of the language and specification.</p>

<p>Within each textbox enter what you think the piece of code above it returns.</p>

<ul>
<li>The pieces of code are executed as statements.</li>
<li><strong>Enter your answer as if you were typing the code literally</strong>. So, if the answer is the string &quot;foo&quot;, then type &quot;foo&quot; (including the quotes &#8212; double or single), and if it&#8217;s an array like <code>[1,2,3]</code> then type it out just like that.</li>
<li>If you think an error is thrown then enter <strong>ERROR</strong> in the appropriate textbox.</li>
<li>When there are multiple statements, type what the last statement returns.</li>
</ul>

<p class="nojs">Please access this post directly in order to take the quiz (note: JavaScript must be enabled).</p>

<span id="more-1534"></span>

<div id="jsquiz"></div>

<p>Like I said, it doesn&#8217;t test your everyday knowledge of JS, but your comprehension of the specification. Feel free to post results and discuss the quiz!</p>

<p>I&#8217;ll eventually post a comment with all the answers (plus explanations), assuming nobody beats me to it.</p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/another-javascript-quiz/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Library foundation code</title>
		<link>http://james.padolsey.com/javascript/library-foundation-code/</link>
		<comments>http://james.padolsey.com/javascript/library-foundation-code/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 17:48:19 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[JavaScript libraries]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1527</guid>
		<description><![CDATA[It should now be universally accepted that extending the DOM directly (via <code>Element.prototype</code>, <code>Node.prototype</code> etc.) <a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/">is a bad idea</a>. To combat the inherent problems with doing this]]></description>
			<content:encoded><![CDATA[<p>It should now be universally accepted that extending the DOM directly (via <code>Element.prototype</code>, <code>Node.prototype</code> etc.) <a href="http://perfectionkills.com/whats-wrong-with-extending-the-dom/">is a bad idea</a>. To combat the inherent problems with doing this, quite a few libraries (jQuery, BBC Glow, etc.) employ the &#8220;wrapper&#8221; technique which involves taking a bunch of DOM elements and stuffing them into an array-like object that inherits from a <em>safely</em>-extendible prototype.</p>

<p>If you want to have a go at creating your own jQuery-like DOM library, here&#8217;s something to get you started:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">window.<span class="me1">myWrapper</span> <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="co1">// &quot;cache&quot; useful methods, so they don't</span>
    <span class="co1">// have to be resolved every time they're used</span>
    <span class="kw2">var</span> push <span class="sy0">=</span> Array.<span class="me1">prototype</span>.<span class="me1">push</span><span class="sy0">,</span>
        slice <span class="sy0">=</span> Array.<span class="me1">prototype</span>.<span class="me1">slice</span><span class="sy0">,</span>
        toString <span class="sy0">=</span> Object.<span class="me1">prototype</span>.<span class="me1">toString</span><span class="sy0">,</span>
&nbsp;
        isArray <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>o<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            toString.<span class="me1">call</span><span class="br0">&#40;</span>o<span class="br0">&#41;</span> <span class="sy0">===</span> <span class="st0">'[object Array]'</span><span class="sy0">;</span>
        <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
        toArray <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
            <span class="kw1">try</span> <span class="br0">&#123;</span>
&nbsp;
                <span class="co1">// Return a basic slice() if the environment</span>
                <span class="co1">// is okay with converting NodeLists to</span>
                <span class="co1">// arrays using slice()</span>
&nbsp;
                slice.<span class="me1">call</span><span class="br0">&#40;</span>document.<span class="me1">childNodes</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
                <span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span>arrayLike<span class="br0">&#41;</span> <span class="br0">&#123;</span>
                    <span class="kw1">return</span> slice.<span class="me1">call</span><span class="br0">&#40;</span>arrayLike<span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
            <span class="br0">&#125;</span> <span class="kw1">catch</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>
&nbsp;
            <span class="co1">// Otherwise return the slower approach</span>
&nbsp;
            <span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span>arrayLike<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
                <span class="kw2">var</span> ret <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">,</span> i <span class="sy0">=</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">,</span> len <span class="sy0">=</span> arrayLike.<span class="me1">length</span><span class="sy0">;</span>
&nbsp;
                <span class="kw1">while</span> <span class="br0">&#40;</span><span class="sy0">++</span>i <span class="sy0">&lt;</span> len<span class="br0">&#41;</span> <span class="br0">&#123;</span>
                    ret<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> arrayLike<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span>
&nbsp;
                <span class="kw1">return</span> ret<span class="sy0">;</span>
&nbsp;
            <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
        <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw2">function</span> NodeList<span class="br0">&#40;</span>elems<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="kw1">this</span>.<span class="me1">length</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span>
&nbsp;
        push.<span class="me1">apply</span><span class="br0">&#40;</span>
            <span class="kw1">this</span><span class="sy0">,</span>
            elems.<span class="me1">nodeType</span> <span class="sy0">?</span>
                <span class="br0">&#91;</span>elems<span class="br0">&#93;</span> <span class="co1">// Single node</span>
                <span class="sy0">:</span> isArray<span class="br0">&#40;</span>elems<span class="br0">&#41;</span> <span class="sy0">?</span>
                    elems <span class="co1">// Real array</span>
                    <span class="sy0">:</span> toArray<span class="br0">&#40;</span>elems<span class="br0">&#41;</span> <span class="co1">// NodeList/Array-like-object</span>
        <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="br0">&#125;</span>
&nbsp;
    <span class="kw2">function</span> myWrapper<span class="br0">&#40;</span>elems<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span class="co1">// Instantiate and return new NodeList</span>
        <span class="kw1">return</span> <span class="kw2">new</span> NodeList<span class="br0">&#40;</span>elems<span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    myWrapper.<span class="me1">NodeList</span> <span class="sy0">=</span> NodeList<span class="sy0">;</span>
&nbsp;
    NodeList.<span class="me1">prototype</span> <span class="sy0">=</span> <span class="br0">&#123;</span>
&nbsp;
        each<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span>fn<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
            <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i <span class="sy0">=</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">,</span> l <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">length</span><span class="sy0">;</span> <span class="sy0">++</span>i <span class="sy0">&lt;</span> l<span class="sy0">;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                fn.<span class="me1">call</span><span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">,</span> <span class="kw1">this</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="sy0">,</span> i<span class="sy0">,</span> l<span class="sy0">,</span> <span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span>
&nbsp;
            <span class="kw1">return</span> <span class="kw1">this</span><span class="sy0">;</span>
&nbsp;
        <span class="br0">&#125;</span>
&nbsp;
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">return</span> myWrapper<span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>There&#8217;s no selector engine, but it&#8217;s easy enough to slot one in:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">function</span> myWrapper<span class="br0">&#40;</span>elems<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="co1">// E.g. using Sizzle as the selector engine</span>
    <span class="kw1">return</span> <span class="kw2">new</span> NodeList<span class="br0">&#40;</span> <span class="kw1">typeof</span> elems <span class="sy0">===</span> <span class="st0">'string'</span> <span class="sy0">?</span> Sizzle<span class="br0">&#40;</span>elems<span class="br0">&#41;</span> <span class="sy0">:</span> elems <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>




<p>Example of usage:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">myWrapper<span class="br0">&#40;</span>document.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">each</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span class="kw3">alert</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">id</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// Etc.</span></pre></div></div>




<p>Extending <code>NodeList</code>:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">myWrapper.<span class="me1">NodeList</span>.<span class="me1">prototype</span>.<span class="me1">applyCSS</span> <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> hasOwn <span class="sy0">=</span> Object.<span class="me1">prototype</span>.<span class="me1">hasOwnProperty</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span>props<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i <span class="sy0">=</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">,</span> l <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">length</span><span class="sy0">;</span> <span class="sy0">++</span>i <span class="sy0">&lt;</span> l<span class="sy0">;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> p <span class="kw1">in</span> props<span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="kw1">if</span> <span class="br0">&#40;</span>hasOwn.<span class="me1">call</span><span class="br0">&#40;</span>props<span class="sy0">,</span> p<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                    <span class="kw1">this</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">style</span><span class="br0">&#91;</span>p<span class="br0">&#93;</span> <span class="sy0">=</span> props<span class="br0">&#91;</span>p<span class="br0">&#93;</span><span class="sy0">;</span>
                <span class="br0">&#125;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span>
&nbsp;
        <span class="kw1">return</span> <span class="kw1">this</span><span class="sy0">;</span>
&nbsp;
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Usage:</span>
myWrapper<span class="br0">&#40;</span>document.<span class="me1">body</span><span class="br0">&#41;</span>.<span class="me1">applyCSS</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
    background<span class="sy0">:</span> <span class="st0">'red'</span><span class="sy0">,</span>
    color<span class="sy0">:</span> <span class="st0">'yellow'</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/library-foundation-code/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>76 bytes for faster jQuery</title>
		<link>http://james.padolsey.com/javascript/76-bytes-for-faster-jquery/</link>
		<comments>http://james.padolsey.com/javascript/76-bytes-for-faster-jquery/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 19:48:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1517</guid>
		<description><![CDATA[When jQuery fires a callback function, whether it is an event handler, an each iterator, or a filter function, it will normally give you a DOM element as the function&#8217;s context, accessible via the <code>this</code> keyword. It&#8217;s common practice to subsequently wrap <code>this</code> in <code>jQuery(...)</code> resulting in a&#8230;]]></description>
			<content:encoded><![CDATA[<p>When jQuery fires a callback function, whether it is an event handler, an each iterator, or a filter function, it will normally give you a DOM element as the function&#8217;s context, accessible via the <code>this</code> keyword. It&#8217;s common practice to subsequently wrap <code>this</code> in <code>jQuery(...)</code> resulting in a newly constructed jQuery instance.</p>

<p>This is no fault of jQuery&#8217;s but this practice of redundant &#8220;wrapping&#8221; generally sucks.</p>

<p>I &#8220;<a href="http://twitter.com/padolsey/status/10916597310">tweeted</a>&#8221; a while ago, complaining of this:</p>

<blockquote><p>Constructing a new jq obj on each iteration just to access some text seems wrong. jQuery(&#8216;a&#8217;).map(function(){ return $(this).text(); });</p></blockquote>

<p><a href="http://paulirish.com/">Paul Irish</a> <a href="http://twitter.com/paul_irish/status/10924853054">suggested</a> that I use <code>jQuery.text</code> instead of <code>jQuery.fn.text</code>, meaning that I wouldn&#8217;t have to bother with constructing a new jQuery object every single time my function was called. This was a good suggestion but unfortunately not all of jQuery&#8217;s methods have corresponding single-node functions, and it would mean not being able to chain methods.</p>

<p>This is a growing problem, and is only worsened by developers&#8217; insistence on constructing multiple jQuery objects with the same element! -</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">jQuery<span class="br0">&#40;</span><span class="st0">'a'</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span>jQuery<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">attr</span><span class="br0">&#40;</span><span class="st0">'href'</span><span class="br0">&#41;</span> <span class="sy0">===</span> <span class="st0">'blah'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        jQuery<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">next</span><span class="br0">&#40;</span><span class="st0">'.whatever'</span><span class="br0">&#41;</span>.<span class="me1">slideToggle</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    jQuery<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">fadeTo</span><span class="br0">&#40;</span><span class="st0">'slow'</span><span class="sy0">,</span> <span class="nu0">0.4</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>Eew! Not only are there multiple <em>pointless</em> constructors, but Mr. Uber Cool jQuery Developer isn&#8217;t accustomed to the DOM, so has absolutely no idea that, in most situations, <code>this.href</code> would suffice for getting the <code>href</code> property value. This kind of misuse has been discussed in step #3 here: <a href="http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/">http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/</a>.</p>

<p>The real problem remains that there are three jQuery objects being constructed, &#8212; I feel that it is a library&#8217;s obligation to protect against misuse like this. Even if you&#8217;re only constructing one jQuery object in a callback it&#8217;s still somewhat pointless, in that you&#8217;re only doing so to call a couple of methods&#8230;</p><span id="more-1517"></span>

<p>In light of my concerns I thought it would make sense to experiment with some ways to alleviate this troublesome situation. In the end, I landed on something so dead-simple that I feel silly even shining a spotlight on it:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">jQuery.<span class="me1">single</span><span class="sy0">=</span><span class="kw2">function</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span><span class="br0">&#123;</span><span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span>b<span class="br0">&#41;</span><span class="br0">&#123;</span>a<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy0">=</span>b<span class="sy0">;</span>return a<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#40;</span>jQuery<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>76 characters. Here&#8217;s the readable version:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">jQuery.<span class="me1">single</span> <span class="sy0">=</span> <span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>o<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> collection <span class="sy0">=</span> jQuery<span class="br0">&#40;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// Fill with 1 item, to make sure length === 1</span>
&nbsp;
    <span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span>element<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
        <span class="co1">// Give collection the element:</span>
        collection<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="sy0">=</span> element<span class="sy0">;</span>
&nbsp;
        <span class="co1">// Return the collection:</span>
        <span class="kw1">return</span> collection<span class="sy0">;</span>
&nbsp;
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>A single jQuery object is being created and is then used for every single call to <code>jQuery.single</code> &#8212; so only one jQuery object is ever being created. If you think about it, we tend to wrap elements in <code>jQuery(...)</code> (i.e. in a jQuery instance) so that we can have access to jQuery&#8217;s methods. Very rarely do we mutate the object itself &#8212; even when you call <code>parent()</code> or <code>children()</code>, the jQuery object itself isn&#8217;t being changed &#8212; a new object is being returned. It&#8217;s this non-mutability which makes this solution viable.</p>

<p>Obviously, you can&#8217;t use it in exactly the same was as <code>jQuery()</code>; <code>jQuery.single</code> will only work when you pass a single DOM element. Here&#8217;s an example of its usage:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">jQuery<span class="br0">&#40;</span><span class="st0">'a'</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> html <span class="sy0">=</span> jQuery.<span class="me1">single</span><span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// Method chaining works!</span>
&nbsp;
    <span class="kw3">alert</span><span class="br0">&#40;</span>html<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// etc. etc.</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>Also, you can&#8217;t cache it and save it for later as you normally would&#8230; well, actually, you can &#8212; but the object will change when you next call <code>jQuery.single</code>, so be careful! And please note that this is only meant to be used in situations where you have a DOM element that requires immediate wrapping.</p>

<p>You might be thinking that we could do away with this trickery by simply remembering to &#8220;cache&#8221; our jQuery objects, like so (using the example from before):</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">jQuery<span class="br0">&#40;</span><span class="st0">'a'</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> me <span class="sy0">=</span> jQuery<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span>me.<span class="me1">attr</span><span class="br0">&#40;</span><span class="st0">'href'</span><span class="br0">&#41;</span> <span class="sy0">===</span> <span class="st0">'blah'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        me.<span class="me1">next</span><span class="br0">&#40;</span><span class="st0">'.whatever'</span><span class="br0">&#41;</span>.<span class="me1">slideToggle</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    me.<span class="me1">fadeTo</span><span class="br0">&#40;</span><span class="st0">'slow'</span><span class="sy0">,</span> <span class="nu0">0.4</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




<p>This is a good practice, but is still not quite as speedy as <code>jQuery.single</code>. I absolutely recommend making up your own mind by carrying out your own tests, but having tested <code>jQuery.single()</code> myself I can tell you that it performs better.</p>

<p>You can make it even faster by assigning <code>jQuery.single</code> to a (closely-scoped) variable:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">var</span> $_ <span class="sy0">=</span> jQuery.<span class="me1">single</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Use $_(this) ...</span></pre></div></div>


]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/76-bytes-for-faster-jquery/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Labelled blocks, useful?</title>
		<link>http://james.padolsey.com/javascript/labelled-blocks-useful/</link>
		<comments>http://james.padolsey.com/javascript/labelled-blocks-useful/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 13:26:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Syntax]]></category>

		<guid isPermaLink="false">http://james.padolsey.com/?p=1504</guid>
		<description><![CDATA[I was recently playing around with <a href="http://bclary.com/2004/11/07/#a-12.12">labels</a> and <a href="http://bclary.com/2004/11/07/#a-12.1">blocks</a> (<em>as one does</em>) and found that they could be used as a way to annotate/contain chunks of JavaScript without using ugly comments (<em>or abstraction?</em>). I can see its appeal &#8211; it offers a sense of containment that is&#8230;]]></description>
			<content:encoded><![CDATA[<p>I was recently playing around with <a href="http://bclary.com/2004/11/07/#a-12.12">labels</a> and <a href="http://bclary.com/2004/11/07/#a-12.1">blocks</a> (<em>as one does</em>) and found that they could be used as a way to annotate/contain chunks of JavaScript without using ugly comments (<em>or abstraction?</em>). I can see its appeal &#8211; it offers a sense of containment that is hard to get with just comments.</p>

<p>I&#8217;ll use the example of a really simple &#8220;getJSONP&#8221; function:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">// BEFORE</span>
<span class="kw2">function</span> getJSONP<span class="br0">&#40;</span>url<span class="sy0">,</span> success<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    <span class="kw2">var</span> ud <span class="sy0">=</span> <span class="st0">'_'</span> <span class="sy0">+</span> <span class="sy0">+</span><span class="kw2">new</span> Date<span class="sy0">,</span>
        script <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'script'</span><span class="br0">&#41;</span><span class="sy0">,</span>
        head <span class="sy0">=</span> document.<span class="me1">head</span> <span class="sy0">||</span> document.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'head'</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>
                             <span class="sy0">||</span> document.<span class="me1">documentElement</span><span class="sy0">;</span>
&nbsp;
    window<span class="br0">&#91;</span>ud<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        head.<span class="me1">removeChild</span><span class="br0">&#40;</span>script<span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="kw1">delete</span> window<span class="br0">&#91;</span>ud<span class="br0">&#93;</span><span class="sy0">;</span>
        success <span class="sy0">&amp;&amp;</span> success<span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
    script.<span class="me1">src</span> <span class="sy0">=</span> url.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">'callback=?'</span><span class="sy0">,</span> <span class="st0">'callback='</span> <span class="sy0">+</span> ud<span class="br0">&#41;</span><span class="sy0">;</span>
    head.<span class="me1">appendChild</span><span class="br0">&#40;</span>script<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="br0">&#125;</span>
&nbsp;
<span class="co1">// AFTER</span>
<span class="kw2">function</span> getJSONP<span class="br0">&#40;</span>url<span class="sy0">,</span> success<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
    declareVars<span class="sy0">:</span> <span class="br0">&#123;</span>
        <span class="kw2">var</span> ud <span class="sy0">=</span> <span class="st0">'_'</span> <span class="sy0">+</span> <span class="sy0">+</span><span class="kw2">new</span> Date<span class="sy0">,</span>
            script <span class="sy0">=</span> document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'script'</span><span class="br0">&#41;</span><span class="sy0">,</span>
            head <span class="sy0">=</span> document.<span class="me1">head</span> <span class="sy0">||</span> document.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'head'</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>
                                 <span class="sy0">||</span> document.<span class="me1">documentElement</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    defineCallback<span class="sy0">:</span> <span class="br0">&#123;</span>
        window<span class="br0">&#91;</span>ud<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            head.<span class="me1">removeChild</span><span class="br0">&#40;</span>script<span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="kw1">delete</span> window<span class="br0">&#91;</span>ud<span class="br0">&#93;</span><span class="sy0">;</span>
            success <span class="sy0">&amp;&amp;</span> success<span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
    addScriptToDocument<span class="sy0">:</span> <span class="br0">&#123;</span>   
        script.<span class="me1">src</span> <span class="sy0">=</span> url.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">'callback=?'</span><span class="sy0">,</span> <span class="st0">'callback='</span> <span class="sy0">+</span> ud<span class="br0">&#41;</span><span class="sy0">;</span>
        head.<span class="me1">appendChild</span><span class="br0">&#40;</span>script<span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
&nbsp;
<span class="br0">&#125;</span></pre></div></div>




<p>You may think that doing this borders on totally pointless and in this instance I&#8217;d probably agree, but you must admit it could potentially be useful in other situations (none come to mind though).</p>

<p>We&#8217;re normally used to <code>{</code> and <code>}</code> being used to delimit an object literal, but they can also be used to create <a href="http://bclary.com/2004/11/07/#a-12.1">blocks</a> (or &#8220;compound statements&#8221;). A compound statement is a statement that contains any number of sub-statements. We use them all the time:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw1">while</span> <span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> normalStatement<span class="sy0">;</span>
<span class="kw1">while</span> <span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    iAmInACompoundStatement<span class="sy0">;</span>
    soAmI<span class="sy0">;</span>
    ermICallItABlock<span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>




<p>We use them everywhere, <code>if</code> statements, <code>for</code> statements, <code>while</code> statements, <code>switch</code> statements, <code>try/catch</code> statements &#8230;</p>

<span id="more-1504"></span>

<p>Since JavaScript doesn&#8217;t have block scope, using a block anywhere other than in the conventional places (if/while etc.) is almost totally pointless. However, as I mentioned, we could use them to annotate and contain logically related pieces of code:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">definingMyVar<span class="sy0">:</span> <span class="kw2">var</span> x <span class="sy0">=</span> <span class="nu0">123</span><span class="sy0">;</span>
&nbsp;
definingABunchOfVars<span class="sy0">:</span> <span class="br0">&#123;</span>
    <span class="kw2">var</span> x <span class="sy0">=</span> <span class="nu0">123</span><span class="sy0">,</span>
        y <span class="sy0">=</span> <span class="nu0">456</span><span class="sy0">,</span>
        z <span class="sy0">=</span> <span class="nu0">789</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>




<p>We can even use <code>break</code> within these blocks:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw2">var</span> x <span class="sy0">=</span> <span class="nu0">1</span><span class="sy0">;</span>
&nbsp;
foo<span class="sy0">:</span> <span class="br0">&#123;</span>
    x <span class="sy0">=</span> <span class="nu0">2</span><span class="sy0">;</span>
    <span class="kw1">break</span> foo<span class="sy0">;</span>
    x <span class="sy0">=</span> <span class="nu0">3</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
x <span class="sy0">===</span> <span class="nu0">2</span><span class="sy0">;</span></pre></div></div>




<p>Note that the <code>break</code> statement must include a label, otherwise it&#8217;s invalid; unlabelled <code>break</code>/<code>continue</code> statements are only permissible within switch statements and loops.</p>

<p>I dare say this is all quite pointless&#8230; but very interesting nonetheless. <strong>What say you</strong>?</p>]]></content:encoded>
			<wfw:commentRss>http://james.padolsey.com/javascript/labelled-blocks-useful/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 1.122 seconds --><!-- Cached page generated by WP-Super-Cache on 2010-08-21 05:38:26 -->
