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

<channel>
	<title>I does Javascript! &#187; Cross-Browser</title>
	<atom:link href="http://blog.stchur.com/category/cross-browser/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.stchur.com</link>
	<description>If you don&#039;t expect too much from me, you might not be let down.</description>
	<lastBuildDate>Tue, 03 Jan 2012 16:01:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Programmatically clicking a link in Javascript</title>
		<link>http://blog.stchur.com/2010/01/15/programmatically-clicking-a-link-in-javascript/</link>
		<comments>http://blog.stchur.com/2010/01/15/programmatically-clicking-a-link-in-javascript/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 01:09:03 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Useful Functions]]></category>
		<category><![CDATA[actuate]]></category>
		<category><![CDATA[click]]></category>
		<category><![CDATA[dispatch]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[link]]></category>
		<category><![CDATA[prevent default action]]></category>
		<category><![CDATA[programmatically clicking]]></category>
		<category><![CDATA[simulate]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/?p=129</guid>
		<description><![CDATA[More accurately, this would be called actuating a link (i.e. the process of setting the link's behavior into motion, if you will.) In other words, you have a link: &#60;a id = 'bingLink' href = &#34;http://www.bing.com&#34;&#62;Bing&#60;/a&#62; And you want to programmatically make that link do its thing. This usually means having the browser navigate to [...]]]></description>
			<content:encoded><![CDATA[	<p>More accurately, this would be called actuating a link (i.e. the process of setting the link's behavior into motion, if you will.)  In other words, you have a link:</p>
	<div class="dean_ch" style="white-space: nowrap;">&lt;a id = 'bingLink' href = &quot;http://www.bing.com&quot;&gt;Bing&lt;/a&gt;</div>
	<p>And you want to programmatically make that link do its thing.  This usually means having the browser navigate to the URL specified link's href attribute (though, it can also mean executing some click handler if one happens to be specified on said link.)</p>
	<p>To be honest, I don't think there are a ton of real-world uses for this, but there are a few.  And depending on your needs, it may not be trivial to accomplish this in a cross-browser fashion.  For example:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> myLink = document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">'myLink'</span><span class="br0">&#41;</span>;<br />
myLink.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
	<p>The above will do the trick in IE, because IE supports <code>.click()</code> on links.  Most other browsers don't though, so that's not an all-encompassing solution.</p>
	<p>One (partial) solution in non-IE browsers might be to read the <code>href</code> attribute from a given link and then use Javascript to make the browser navigate to to the URL specified by <code>href</code> that way:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">function</span> actuateLink<span class="br0">&#40;</span>link<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp;window.<span class="me1">location</span>.<span class="me1">href</span> = link.<span class="me1">href</span>;<br />
<span class="br0">&#125;</span></div>
	<p>This is not a complete solution for a couple of reasons:</p>
	<ol>
	<li>Navigating by setting <code>window.location.href</code> blows away the <code>document.referrer</code> property.</li>
	<li>Any click event handler wired to the link will not execute.</li>
	</ol>
	<p>For anyone who has read my post about <a href = "http://blog.stchur.com/2007/11/16/re-routing-events-in-javscript/" title = "Re-routing events in Javascript">Re-routing events in Javascript</a> post, you'll know that it is possible to simulate an event though the use of <code>.dispatchEvent(..)</code>.</p>
	<p>Here's a brief refresher of the part most relevant to this discussion:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> myEvt = document.<span class="me1">createEvent</span><span class="br0">&#40;</span><span class="st0">'MouseEvents'</span><span class="br0">&#41;</span>;<br />
myEvt.<span class="me1">initEvent</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp;<span class="st0">'click'</span> &nbsp; &nbsp; &nbsp;<span class="co1">// event type</span><br />
&nbsp; &nbsp;,<span class="kw2">true</span> &nbsp; &nbsp; &nbsp;<span class="co1">// can bubble?</span><br />
&nbsp; &nbsp;,<span class="kw2">true</span> &nbsp; &nbsp; &nbsp;<span class="co1">// cancelable?</span><br />
<span class="br0">&#41;</span>;<br />
document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">'myLink'</span><span class="br0">&#41;</span>.<span class="me1">dispatchEvent</span><span class="br0">&#40;</span>myEvt<span class="br0">&#41;</span>;</div>
	<p>This approach will ensure that any click event handlers will fire as desired (though, it's worth nothing that you'd have to handle <code>mousedown, mouseup, keydown, keypress</code> etc... separately,) but it does NOT actuate the link!</p>
	<p>This might surprise you.  Dispatching a click event to a link doesn't actually cause the browser to navigate to the URL specified by that link's href property.  This actually isn't shocking to me, personally.  A little surprising, but not shocking.</p>
	<p>Anyway, one option is to dispatch the click event and then use <code>window.location.href</code>.  This should achieve (some of) the desired effect, but again, the <code>document.referrer</code> will not be preserved if you do this.  Also, if the event handler <a href = "http://blog.stchur.com/2006/06/23/preventing-the-default-action/" title = "Preventing the default action">prevents the default action</a>, this method will not honor the code that prevents the default action (i.e. the link will navigate despite the code that attempts to prevent it from doing so.)</p>
	<p>You can work around the <code>window.location.href</code> problem by creating a &lt;form&gt; element, settings its <code>action</code> attribute to that of the link's href attribute and then submitting the form through <code>myForm.submit()</code>, but the problem regarding preventing the default action remains.</p>
	<h2>A 95% Solution</h2>
	<p>Is there a 100% perfect solution to this problem?  Probably, but I'm not 100% perfect.  I'm only 95% perfect, so I give you my 95% solution:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">function</span> actuateLink<span class="br0">&#40;</span>link<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> allowDefaultAction = <span class="kw2">true</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>link.<span class="me1">click</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;link.<span class="me1">click</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>document.<span class="me1">createEvent</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> e = document.<span class="me1">createEvent</span><span class="br0">&#40;</span><span class="st0">'MouseEvents'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">initEvent</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; <span class="st0">'click'</span> &nbsp; &nbsp; <span class="co1">// event type</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; ,<span class="kw2">true</span> &nbsp; &nbsp; &nbsp;<span class="co1">// can bubble?</span><br />
&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; ,<span class="kw2">true</span> &nbsp; &nbsp; &nbsp;<span class="co1">// cancelable?</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;allowDefaultAction = link.<span class="me1">dispatchEvent</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span>;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>allowDefaultAction<span class="br0">&#41;</span>&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> f = document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'form'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;f.<span class="me1">action</span> = link.<span class="me1">href</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;document.<span class="me1">body</span>.<span class="me1">appendChild</span><span class="br0">&#40;</span>f<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;f.<span class="me1">submit</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
	<p>To use it:</p>
	<div class="dean_ch" style="white-space: nowrap;">actuateLink<span class="br0">&#40;</span>document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">'bingLink'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
	<p>This code is self explanatory, right?</p>
	<p>If <code>.click()</code> is available, let's use that.  If not, let's try to do a W3C-style create and dispatch event.  Then, in order to maintain the <code>document.referrer</code> property, we'll use a form submission, but we only want to submit that form if the event handler (if there is one) for the <code>click</code> event doesn't explicitly prevent the default action.</p>
	<p>This isn't a 100% perfect solution because, actuating a link in this manner is only going to invoke click handlers and navigate to the URL of the link's href attribute (if appropriate to do so.)  It isn't going to invoke handlers for any other types of events.  And I'm not about to create and dispatch every possible kind of event.  Besides, I think we can all agree that <code>click</code> is by far the most common scenario.</p>
	<p>So there ya go.  Programmatically clicking (or more accurately, actuating) a link with Javascript.  Enjoy!</p>
	<p>(Tested: Firefox 3.5.7, IE8, Opera 10.01, Safari/Win 4.0.3, Chrome 3)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2010/01/15/programmatically-clicking-a-link-in-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fetch (a stand-alone CSS querying engine)</title>
		<link>http://blog.stchur.com/2009/03/06/fetch-a-stand-alone-css-querying-engine/</link>
		<comments>http://blog.stchur.com/2009/03/06/fetch-a-stand-alone-css-querying-engine/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 06:00:16 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Fetch]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[CSS Querying]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/?p=124</guid>
		<description><![CDATA[I've started work on a new side-project called Fetch. It's a stand-alone CSS querying engine, designed to be super lightweight and offer high performance across all modern browsers. It's still very much in development and the source is a bit sloppy, but it currently weighs in at only 2.5k compressed and gzipped and (in Firefox3) [...]]]></description>
			<content:encoded><![CDATA[	<p>I've started work on a new side-project called Fetch.  It's a stand-alone CSS querying engine, designed to be super lightweight and offer high performance across all modern browsers.</p>
	<p>It's still very much in development and the source is a bit sloppy, but it currently weighs in at only 2.5k compressed and gzipped and (in Firefox3) either outperforms or is on par with all other major Javascript libraries out there*.</p>
	<p>It's definitely not ready for production use, but when it is, it will become the new CSS querying engine for Gimme and will also be available as a stand-alone library, which will be extensible (so you can add your own rules) and which will also be guaranteed to play nicely with other libraries by not adding to the prototype of any native objects and only introducing one single global variable (fetch).</p>
	<p>For anyone interested, the current (i.e. sloppy) source is available on CodePlex: <a href = "http://gimme.codeplex.com/SourceControl/changeset/view/32017#399762">fetch.js</a>.</p>
	<p>As I said, it's not ready for prime time and the code is sloppy (and probably buggy).  Consider yourself warned.</p>
	<p>* <small>Fetch was not compared with libraries that use XPath or querySelectorAll, because it uses neither, but rather is a pure Javascript implementation.  Upon release, it will take advantage of querySelectorAll where appropriate, but will not use XPath.</small>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2009/03/06/fetch-a-stand-alone-css-querying-engine/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Ultimate addEvent(..) function</title>
		<link>http://blog.stchur.com/2008/09/25/the-ultimate-addevent-function/</link>
		<comments>http://blog.stchur.com/2008/09/25/the-ultimate-addevent-function/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 18:32:17 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Firefox Related]]></category>
		<category><![CDATA[Useful Functions]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Ultimate addEvent]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/09/25/the-ultimate-addevent-function/</guid>
		<description><![CDATA[Two articles in particular that I've written on this blog have garnered a lot of positive feedback. Fixing IE's attachEvent Failures mouseenter and mouseleave Events for Firefox (and other Non-IE Browsers) As time has gone on, I've seen mention of these articles pop up in programming forums here and there, and they still receive comments [...]]]></description>
			<content:encoded><![CDATA[	<p>Two articles in particular that I've written on this blog have garnered a lot of positive feedback.</p>
	<ol>
	<li><a href = "http://blog.stchur.com/2006/10/12/fixing-ies-attachevent-failures/" title = "Fixing IE's attachEvent Failures">Fixing IE's attachEvent Failures</a></li>
	<li><a href = "http://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/" title = "mouseenter and mouseleave Events for Firefox (and other Non-IE Browsers)">mouseenter and mouseleave Events for Firefox (and other Non-IE Browsers)</a></li>
	</ol>
	<p>As time has gone on, I've seen mention of these articles pop up in programming forums here and there, and they still receive comments from time to time, which lets me know that people are still getting something out of them.</p>
	<p>Unfortunately, the code in them is a tad dated.  I've learned more and improved my code since I originally wrote them, and while these improvements have made their way into my <a href = "http://gimme.stchur.com" title = "The Gimme Javascript Library">Javascript Library</a>, I know that the majority of people are just grabbing the code directly from the blog entries.</p>
	<p>So I've decided to post an update: a sort of fusion between these two blog entries which offers functionality for addressing all of the issues discussed in the aforementioned entries (and then some).</p>
	<p>I consider this new function the "Ultimate addEvent Function" because I really believe it addresses the large majority of cross-browser issues that people face when dealing with events in Javascript.  And furthermore, this function goes beyond anything that any other Javascript library provides (at least as far as I know).</p>
	<p>So without further ado, I offer to you:</p>
	<h3>sstchur's Ultimate addEvent(..) function!</h3></p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> xb = <span class="br0">&#123;</span><span class="br0">&#125;</span>;<br />
<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> GUIDCounter = <span class="nu0">0</span>;<br />
&nbsp; &nbsp;<span class="kw2">var</span> evtHash = <span class="br0">&#123;</span><span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;<span class="kw2">var</span> pseudoEvents =<br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="st0">'mouseenter'</span>: <span class="kw2">function</span><span class="br0">&#40;</span>_fn, _useCapture, _listening<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> f = mouseEnter<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_listening ?<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;xb.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="kw1">this</span>, <span class="st0">'mouseover'</span>, f, _useCapture, <span class="kw2">false</span><span class="br0">&#41;</span> :<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;xb.<span class="me1">removeEvent</span><span class="br0">&#40;</span><span class="kw1">this</span>, <span class="st0">'mouseover'</span>, f, _useCapture, <span class="kw2">false</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;f = <span class="kw2">null</span>;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span>,<br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="st0">'mouseleave'</span>: <span class="kw2">function</span><span class="br0">&#40;</span>_fn, _useCapture, _listening<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> f = mouseEnter<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_listening ?<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;xb.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="kw1">this</span>, <span class="st0">'mouseout'</span>, f, _useCapture, <span class="kw2">false</span><span class="br0">&#41;</span> :<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;xb.<span class="me1">removeEvent</span><span class="br0">&#40;</span><span class="kw1">this</span>, <span class="st0">'mouseout'</span>, f, _useCapture, <span class="kw2">false</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;f = <span class="kw2">null</span>;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;xb.<span class="me1">Helper</span> =<br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;getObjectGUID: getObjectGUID,<br />
&nbsp; &nbsp;&nbsp; &nbsp;storeHandler: storeHandler,<br />
&nbsp; &nbsp;&nbsp; &nbsp;retrieveHandler: retrieveHandler,<br />
&nbsp; &nbsp;&nbsp; &nbsp;isAnAncestorOf: isAnAncestorOf,<br />
&nbsp; &nbsp;&nbsp; &nbsp;mouseEnter: mouseEnter<br />
&nbsp; &nbsp;<span class="br0">&#125;</span>;&nbsp;<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;xb.<span class="me1">addEvent</span> = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> document.<span class="me1">addEventListener</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> w3c_addEvent;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> document.<span class="me1">attachEvent</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> ie_addEvent;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// no modern event support I guess <img src='http://blog.stchur.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// (you could use DOM 0 here if you really wanted to)</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">function</span> w3c_addEvent<span class="br0">&#40;</span>_elem, _evtName, _fn, _useCapture, _directCall<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> eventFn = pseudoEvents<span class="br0">&#91;</span>_evtName<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> eventFn === <span class="st0">'function'</span> &amp;&amp; _directCall !== <span class="kw2">false</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;eventFn.<span class="me1">call</span><span class="br0">&#40;</span>_elem, _fn, _useCapture, <span class="kw2">true</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_elem.<span class="me1">addEventListener</span><span class="br0">&#40;</span>_evtName, _fn, _useCapture<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">function</span> ie_addEvent<span class="br0">&#40;</span>_elem, _evtName, _fn, _useCapture, _directCall<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> eventFn = pseudoEvents<span class="br0">&#91;</span>_evtName<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> eventFn === <span class="st0">'function'</span> &amp;&amp; _directCall !== <span class="kw2">false</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;eventFn.<span class="me1">call</span><span class="br0">&#40;</span>_elem, _fn, _useCapture, <span class="kw2">true</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// create a key to identify this element/event/function combination</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> key = generateHandlerKey<span class="br0">&#40;</span>_elem, _evtName, _fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// if this element/event/combo has already been wired up, just return</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> f = evtHash<span class="br0">&#91;</span>key<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> f !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// create a helper function to fix IE's lack of standards support</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;f = <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// map .target to .srcElement</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">target</span> = e.<span class="me1">srcElement</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// map .relatedTarget to either .toElement or .fromElement</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_evtName == <span class="st0">'mouseover'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> e.<span class="me1">relatedTarget</span> = e.<span class="me1">fromElement</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>_evtName == <span class="st0">'mouseout'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> e.<span class="me1">relatedTarget</span> = e.<span class="me1">toElement</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">preventDefault</span> = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> e.<span class="me1">returnValue</span> = <span class="kw2">false</span>; <span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">stopPropagation</span> = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> e.<span class="me1">cancelBubble</span> = <span class="kw2">true</span>; <span class="br0">&#125;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// call the actual function, using entity (the element) as the 'this' object</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_fn.<span class="me1">call</span><span class="br0">&#40;</span>_elem, e<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// null out these properties to prevent memory leaks</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">target</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">relatedTarget</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">preventDefault</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">stopPropagation</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;e = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// add the helper function to the event hash</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;evtHash<span class="br0">&#91;</span>key<span class="br0">&#93;</span> = f;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// hook up the event (IE style)</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_elem.<span class="me1">attachEvent</span><span class="br0">&#40;</span><span class="st0">'on'</span> + _evtName, f<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;key = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;f = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;xb.<span class="me1">defineEvent</span> = <span class="kw2">function</span><span class="br0">&#40;</span>_evtName, _logicFn<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;pseudoEvents<span class="br0">&#91;</span>_evtName<span class="br0">&#93;</span> = _logicFn;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span>;</p>
	<p>&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="co1">// Helper Functions</span><br />
&nbsp; &nbsp;<span class="kw2">function</span> storeHandler<span class="br0">&#40;</span>_key, _handler<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;evtHash<span class="br0">&#91;</span>_key<span class="br0">&#93;</span> = _handler;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw2">function</span> retrieveHandler<span class="br0">&#40;</span>_key<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> evtHash<span class="br0">&#91;</span>_key<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw2">function</span> generateHandlerKey<span class="br0">&#40;</span>_elem, _evtName, _handler<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'{'</span> + getObjectGUID<span class="br0">&#40;</span>_elem<span class="br0">&#41;</span> + <span class="st0">'/'</span> + _evtName + <span class="st0">'/'</span> + getObjectGUID<span class="br0">&#40;</span>_handler<span class="br0">&#41;</span> + <span class="st0">'}'</span>;&nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw2">function</span> isAnAncestorOf<span class="br0">&#40;</span>_ancestor, _descendant, _generation<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_ancestor === _descendant<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="kw2">false</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> gen = <span class="nu0">0</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">while</span> <span class="br0">&#40;</span>_descendant &amp;&amp; _descendant != _ancestor<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;gen++;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_descendant = _descendant.<span class="me1">parentNode</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;_generation = _generation || gen;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _descendant === _ancestor &amp;&amp; _generation === gen;&nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw2">function</span> mouseEnter<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span>&nbsp; <br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> key = xb.<span class="me1">Helper</span>.<span class="me1">getObjectGUID</span><span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> f = evtHash<span class="br0">&#91;</span>key<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> f === <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;f = evtHash<span class="br0">&#91;</span>key<span class="br0">&#93;</span> = <span class="kw2">function</span><span class="br0">&#40;</span>_evt<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> relTarget = _evt.<span class="me1">relatedTarget</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">this</span> === relTarget || isAnAncestorOf<span class="br0">&#40;</span><span class="kw1">this</span>, relTarget<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_fn.<span class="me1">call</span><span class="br0">&#40;</span><span class="kw1">this</span>, _evt<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> f;&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="kw2">function</span> getObjectGUID<span class="br0">&#40;</span>_elem<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_elem === window<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'theWindow'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>_elem === document<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'theDocument'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _elem.<span class="me1">uniqueID</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _elem.<span class="me1">uniqueID</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> ex = <span class="st0">'__$$GUID$$__'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _elem<span class="br0">&#91;</span>ex<span class="br0">&#93;</span> === <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_elem<span class="br0">&#91;</span>ex<span class="br0">&#93;</span> = ex + GUIDCounter++;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _elem<span class="br0">&#91;</span>ex<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp;</div>
	<div class = "note">The code above, as is, won't work "out of the box" because (for the sake of brevity) I have not included the <code>xb.removeEvent(..)</code> function.  Fear not however.  There will be a link to a download of the full source code, complete with both <code>xb.addEvent(..)</code> and <code>xb.removeEvent(..)</code> at the end of this post.</div>
	<h3>Commentary</h3>
	<p>So some of you may be wondering: "Why <em>another</em> addEvent function.  Haven't we been through this?"  We have, but I think you'll find that this version does more than any other addEvent function you've seen.  For example:</p>
	<ul>
	<li>Works in all browsers that matter</li>
	<li>Ensures <em>one</em> event wire up for any given element/event/handler combination (this is mostly for IE)</li>
	<li>Forces IE to honor the <code>this</code> keyword from within event handler functions</li>
	<li>Normalizes the wire up mechanism in all browsers (no need to include the "on" prefix for IE)</li>
	<li>Forces IE to recognize the following properties/methods on event objects: <code>.stopPropagation()</code>, <code>.preventDefault()</code>, <code>.target</code>, <code>.relatedTarget</code></li>
	<li>Enhances Non-IE browsers to support <code>mouseenter</code> and <code>mouseleave</code> events</li>
	<li>Provides an extension mechanism so developers can write their own custom events that plug right in ('mousewheel' or 'DOMContentReady' for example)</li>
	</ul>
	<p>Given all that the Ultimate addEvent function does, it's not surprising that it has a bit of length to it.  But it isn't super long, and I think it's well worth it.</p>
	<h3>Usage</h3>
	<p>Using the function(s) is just as easy as you'd expect:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> myDiv = document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">'myDiv'</span><span class="br0">&#41;</span>;<br />
xb.<span class="me1">addEvent</span><span class="br0">&#40;</span>myDiv, <span class="st0">'click'</span>, clickHandler<span class="br0">&#41;</span>;</p>
	<p><span class="kw2">function</span> clickHandler<span class="br0">&#40;</span>e<span class="br0">&#41;</span></p>
	<p>
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'The this keywords works (even in IE!): '</span> + <span class="kw1">this</span>.<span class="me1">id</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
	<h3>Extending Functionality</h3>
	<p>Since I mentioned that it was possible to extend the Ultimate addEvent function with custom events that plug right in, I figure I'd better offer an example.  Actually, there already is an example built right into it.  Both the <code>mouseenter</code> and <code>mouseleave</code> events utilize the extension mechanism internally, but for demonstration purposes, let's go ahead and add a <code>mousewheel<code> event:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="co1">// Extend the Ultimate addEvent function to recognize a &quot;mousewheel&quot; event</span><br />
xb.<span class="me1">defineEvent</span><span class="br0">&#40;</span><span class="st0">'mousewheel'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>_fn, _useCapture, _listening<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// event name for IE, Opera and Safari</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> evtName = <span class="st0">'mousewheel'</span>;</p>
	<p>&nbsp; &nbsp;<span class="co1">// hander for IE, Opera, and Safari</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> f = _fn;<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="co1">// if we're dealing with a Gecko browser, the event name</span><br />
&nbsp; &nbsp;<span class="co1">// and handler need some adjustment</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> ua = navigator.<span class="me1">userAgent</span>.<span class="me1">toLowerCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>ua.<span class="me1">indexOf</span><span class="br0">&#40;</span><span class="st0">'khtml'</span><span class="br0">&#41;</span> === <span class="nu0">-1</span> &amp;&amp; ua.<span class="me1">indexOf</span><span class="br0">&#40;</span><span class="st0">'gecko'</span><span class="br0">&#41;</span> !== <span class="nu0">-1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;evtName = <span class="st0">'DOMMouseScroll'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;f = mouseWheel<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// _listening represents whether this is an event attachment or detachment</span><br />
&nbsp; &nbsp;<span class="co1">// that 5th parameter? &nbsp;Don't worry about it; just always use false</span><br />
&nbsp; &nbsp;_listening ? xb.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="kw1">this</span>, evtName, f, _useCapture, <span class="kw2">false</span><span class="br0">&#41;</span> : xb.<span class="me1">removeEvent</span><span class="br0">&#40;</span><span class="kw1">this</span>, evtName, f, _useCapture, <span class="kw2">false</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</p>
	<p><span class="co1">// Helper function for dealing with mousewheel in Gecko browsers</span><br />
<span class="kw2">function</span> mouseWheel<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> key = xb.<span class="me1">Helper</span>.<span class="me1">getObjectGUID</span><span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="kw2">var</span> f = xb.<span class="me1">Helper</span>.<span class="me1">retrieveHandler</span><span class="br0">&#40;</span>key<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> f === <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;f = <span class="kw2">function</span><span class="br0">&#40;</span>_evt<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_evt.<span class="me1">wheelDelta</span> = -<span class="br0">&#40;</span>_evt.<span class="me1">detail</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_fn.<span class="me1">call</span><span class="br0">&#40;</span><span class="kw1">this</span>, _evt<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;_evt.<span class="me1">wheelDelta</span> = <span class="kw2">null</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;xb.<span class="me1">Helper</span>.<span class="me1">storeHandler</span><span class="br0">&#40;</span>key, f<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">return</span> f;<br />
<span class="br0">&#125;</span></div>
	<p>I'm glossing over some details here because I don't want this post to get bogged down in something that it isn't really about, but I trust you get the idea.</p>
	<p>Most of this code actually comes from the <a href = "http://gimme.stchur.com" title = "The Gimme Javascript Library">The Gimme Javascript Library</a>.  If you're using Gimme in any of your web pages, you already have all of this functionality for free.  The syntax is a touch different, but all the capabilities are the same.</p>
	<p>And if you happen to be the author of a Live Maps Mashup, you already have Gimme, as the latest version shipped with the most recent <a href = "http://dev.virtualearth.net" title = "Virtual Earth MapControl Developers">Virtual Earth MapControl</a>.</p>
	<p><a name="end"></a></p>
	<h3>Complete Source</h3>
	<p>As promised, here is the <a href = "http://blog.stchur.com/blogcode/ultimate_addevent/ultimate.zip" title = "The Ultimate addEvent function">complete source</a>, including both <code>xb.addEvent(..)</code> and <code>xb.removeEvent(..)</code></p>
	<p>Enjoy! And please don't hesitate to send your feedback, both good and bad (I'm very willing to address issues or try to make requested enhancements).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/09/25/the-ultimate-addevent-function/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>CSS Word-wrap: break word; (revisited)</title>
		<link>http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/</link>
		<comments>http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 00:16:30 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Firefox Related]]></category>
		<category><![CDATA[MiniPosts]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/</guid>
		<description><![CDATA[HedgerWow is a great blog. If you've never checked it out, you definitely should. I just noticed the other day that his latest post gives some props to my Emulating CSS word-wrap for Mozilla/Firefox blog post, but his version adds some much needed cross-browser support for browsers I neglected. Nice One, HedgerWow!]]></description>
			<content:encoded><![CDATA[<p><a href = "http://www.hedgerwow.com" title = "Keep It Simple, Stupid">HedgerWow</a> is a great blog.  If you've never checked it out, you definitely should.</p>

<p>I just noticed the other day that his latest post gives some props to my <a href = "http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/" title = "Emulating CSS word-wrap for Mozilla/Firefox">Emulating CSS word-wrap for Mozilla/Firefox</a> blog post, but <a href = "http://www.hedgerwow.com/360/dhtml/css-word-break.html" title = "Cross Browser Word Breaker">his version</a> adds some much needed cross-browser support for browsers I neglected.</p>

<p><a href = "http://www.hedgerwow.com/360/dhtml/css-word-break.html" title = "Cross Browser Word Breaker">Nice One</a>, HedgerWow!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programmatically Accessing the CSS Rules in Your Page&#039;s Stylesheets</title>
		<link>http://blog.stchur.com/2008/04/09/programmatically-accessing-the-css-rules-in-your-pages-stylesheets/</link>
		<comments>http://blog.stchur.com/2008/04/09/programmatically-accessing-the-css-rules-in-your-pages-stylesheets/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 19:10:55 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/04/09/programmatically-accessing-the-css-rules-in-your-pages-stylesheets/</guid>
		<description><![CDATA[It's not a scenario that comes up too often, but every once in a while, I find the need to programmatically access a CSS rule in one of my stylesheets (which includes rules embedded in the page via the &#60;style&#62; tag). The major problem here is that there is only one mechanism available for accessing [...]]]></description>
			<content:encoded><![CDATA[	<p>It's not a scenario that comes up too often, but every once in a while, I find the need to programmatically access a CSS rule in one of my stylesheets (which includes rules embedded in the page via the <code>&lt;style&gt;</code> tag).</p>
	<p>The major problem here is that there is only one mechanism available for accessing a <code>CSSStyleSheetDeclaration</code> object and its corresponding <code>CSSRule</code> collection.</p>
	<p>And that (rather unfortunate) mechanism is by zero-based index, which means you need to know exactly where in the DOM a particular stylesheet lives and exactly where in said stylesheet the particular rule you're interested in lives.</p>
	<p>Needless to say, accessing these sheets and rules by index is risky, since any update to your CSS may require an update to the code which accesses your CSSRule by index.</p>
	<p>You might be thinking that one solution is to put the rule (or rules) that interest you in a predictable place (e.g. the very first rule of the very first stylesheet in your page), but even this is risky and error prone (I know; I did it, and it once came back to bite me).</p>
	<p>In light of these issues, I wrote a function that, given a CSS selector rule, finds the the corresponding CSSRule (if it exists).  Since this is not necessarily a cheap process, the results are cached so that future requests for the same rule are returned in constant time.</p>
	<p>The full code is offered below, with explanations of anything interested embedded in comments.</p>
	<h3>The findCSSRule(..) function</h3>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> findCSSRule = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span> &nbsp; <br />
&nbsp; &nbsp;<span class="kw2">var</span> cache = <span class="br0">&#123;</span><span class="br0">&#125;</span>;<br />
&nbsp; &nbsp;<span class="kw2">function</span> worker<span class="br0">&#40;</span>_selector, _media<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> cache<span class="br0">&#91;</span>_selector<span class="br0">&#93;</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> cache<span class="br0">&#91;</span>_selector<span class="br0">&#93;</span>;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// return the cached rule if it exists</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;_media = _media || <span class="st0">''</span>;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <span class="co1">// if _media isn't passed in, default to empty string</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> i, j,<br />
&nbsp; &nbsp;&nbsp; &nbsp;mediaText,<br />
&nbsp; &nbsp;&nbsp; &nbsp;sheet, rule, rules, rulesLen,<br />
&nbsp; &nbsp;&nbsp; &nbsp;sheets = document.<span class="me1">styleSheets</span>,<br />
&nbsp; &nbsp;&nbsp; &nbsp;sheetsLen = sheets.<span class="me1">length</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>i = <span class="nu0">0</span>; i &lt; sheetsLen; i++<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;sheet = sheets<span class="br0">&#91;</span>i<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// accessing the media attribute of the stylesheet requires a bit of cross-browser trickery</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;mediaText = <span class="kw1">typeof</span> sheet.<span class="me1">media</span>.<span class="me1">mediaText</span> !== <span class="st0">'undefined'</span> ? sheet.<span class="me1">media</span>.<span class="me1">mediaText</span> : sheet.<span class="me1">media</span>;<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// don't waste time with this sheet if its not of the right media type</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>mediaText.<span class="me1">indexOf</span><span class="br0">&#40;</span>_media<span class="br0">&#41;</span> === <span class="nu0">-1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">continue</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;rules = sheet<span class="br0">&#91;</span>prop<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;rulesLen = rules.<span class="me1">length</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>j = <span class="nu0">0</span>; j &lt; rulesLen; j++<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;rule = rules<span class="br0">&#91;</span>j<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>rule.<span class="me1">selectorText</span> === _selector<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> cache<span class="br0">&#91;</span>_selector<span class="br0">&#93;</span> = rule;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="kw2">null</span>; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// this function is returned if the browser doesn't provide a known</span><br />
&nbsp; &nbsp;<span class="co1">// mechanism for accessing stylesheets and/or CSS rules</span><br />
&nbsp; &nbsp;<span class="kw2">function</span> unsupported<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="kw2">null</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// make sure there's at least 1 stylesheet to search,</span><br />
&nbsp; &nbsp;<span class="co1">// then prop will be &quot;cssRules&quot; (W3C), &quot;rules&quot; (IE), or null (unsupported)</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> test = document.<span class="me1">styleSheets</span>.<span class="me1">length</span> &gt; <span class="nu0">0</span> &amp;&amp; document.<span class="me1">styleSheets</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;<span class="kw2">var</span> prop = test &amp;&amp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw1">typeof</span> test.<span class="me1">cssRules</span> !== <span class="st0">'undefined'</span> ? <span class="st0">'cssRules'</span> :<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">typeof</span> test.<span class="me1">rules</span> !== <span class="st0">'undefined'</span> ? <span class="st0">'rules'</span> :<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">null</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;<span class="co1">// false prop (meaning no stylesheets or unsupported method of accessing the CSSRules),</span><br />
&nbsp; &nbsp;<span class="co1">// means this function won't work, so rather than return the worker, return the unsupported function</span><br />
&nbsp; &nbsp;<span class="kw1">return</span> prop ? worker : unsupported;<br />
<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
	<h3>Caveats:</h3>
	<p>This function isn't perfect by any means -- a few things need to be called out.</p>
	<ol>
	<li>Specifying media type could be more flexible:  I'm just doing a simple <code>indexOf(..)</code> check on the stylesheet's media attribute, which means that if you want to filter by more than one media type, you'll need to specify the comma separated list yourself, and you'll need to make sure you do it in the right order if you want the <code>indexOf(..)</code> check to pass.  A more robust solution might be to parse a comma separated string of media types for the user, or to allow the user to specify multiple media types in an array.</li>
	<li>Memory consumption could be an issue:  I don't think it's likely, but if you're grabbing lots and lots of rules, the cache could become large and memory leaks could become an issue (since the cache is created in a closure).  I'm not overly concerned about this though -- you can decide for yourself is this is a big deal.</li>
	<li>No mechanism for handling dynamically created styles:  If you happen to load a stylesheet later in page's lifetime (after the initial load) this function is still going to return the <code>unsupported()</code> function, since it does its check once, up front, to decide whether or not accessing stylesheets/rules is feasible.  I'm okay with this, but again, you can decide for yourself.</li>
	</ul>
	<h3>Examples:</h3>
	<p>Now that the function is written, a few examples are in order.  Assume the following stylesheets:</p>
	<h4> - stylesheet 0 - (media = "print") </h4>
	<div class="dean_ch" style="white-space: nowrap;">div&gt;span<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">border</span>: <span class="re3">10px</span> <span class="kw2">solid</span> <span class="kw2">red</span>;<br />
<span class="br0">&#125;</span></p>
	<p><span class="re1">.christmas</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">background</span>: <span class="kw2">green</span>;<br />
&nbsp; &nbsp;<span class="kw1">color</span>: <span class="kw2">red</span>;<br />
<span class="br0">&#125;</span></p>
	<p><span class="re1">.pascha</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">background</span>: <span class="kw2">purple</span>;<br />
&nbsp; &nbsp;<span class="kw1">color</span>: <span class="kw2">yellow</span>;<br />
<span class="br0">&#125;</span></div>
	<h4> - stylesheet 1 - (media = "screen")</h4>
	<div class="dean_ch" style="white-space: nowrap;">div&gt;span<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">border</span>: <span class="re3">5px</span> <span class="kw2">dotted</span> <span class="kw1">blue</span>;<br />
<span class="br0">&#125;</span></p>
	<p><span class="re0">#main</span> div~span<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">background</span>: pink;<br />
<span class="br0">&#125;</span></div>
	<p>Accessing any of the above styles is fairly trivial.</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="co1">// returns the div&gt;span rule from stylesheet 0</span><br />
<span class="kw2">var</span> r1 = findCSSRule<span class="br0">&#40;</span><span class="st0">'div&gt;span'</span>, <span class="st0">'print'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<br />
<span class="co1">// also returns the div&gt;span rule from stylesheet 0 (since media default to empty string, the first stylesheet with this rule will match)</span><br />
<span class="kw2">var</span> r2 = findCSSRule<span class="br0">&#40;</span><span class="st0">'div&gt;span'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<br />
<span class="co1">// returns the div&gt;span rule from stylesheet 1</span><br />
<span class="kw2">var</span> r3 = findCSSRule<span class="br0">&#40;</span><span class="st0">'div&gt;span'</span>, <span class="st0">'scren'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<br />
<span class="co1">// returns the .pascha rule from stylesheet 0</span><br />
<span class="kw2">var</span> r4 = findCSSRule<span class="br0">&#40;</span><span class="st0">'.pascha'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<br />
<span class="co1">// returns null</span><br />
<span class="kw2">var</span> r5 = findCSSRule<span class="br0">&#40;</span><span class="st0">'.halloween'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<br />
<span class="co1">// returns the #main div~span rule from stylesheet 1</span><br />
<span class="kw2">var</span> r6 = findCSSRule<span class="br0">&#40;</span><span class="st0">'#main div~span'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<br />
<span class="co1">// returns null (b/c the rule doesn't exist in a stylesheet with media = &quot;print&quot;</span><br />
<span class="kw2">var</span> r7 = findCSSRule<span class="br0">&#40;</span><span class="st0">'#main div~span'</span>, <span class="st0">'print'</span><span class="br0">&#41;</span>;</div>
	<p>And there you have it!</p>
	<p>Comments, questions, suggestions, complaints? Bring 'em on!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/04/09/programmatically-accessing-the-css-rules-in-your-pages-stylesheets/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>setCapture with Gimme</title>
		<link>http://blog.stchur.com/2007/11/21/setcapture-with-gimme/</link>
		<comments>http://blog.stchur.com/2007/11/21/setcapture-with-gimme/#comments</comments>
		<pubDate>Thu, 22 Nov 2007 04:44:01 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/11/21/setcapture-with-gimme/</guid>
		<description><![CDATA[In my last blog post I talked about how to re-route events in Javascript. It comes in handy from time to time, but some people prefer an alternate paradigm -- one that is probably more familiar to Win32 programmers. It's called setCapture. It's proprietary, and it's native to only the IE browser (as far as [...]]]></description>
			<content:encoded><![CDATA[	<p>In my <a href = "http://blog.stchur.com/2007/11/16/re-routing-events-in-javscript/" title = "Re-routing Events in Javascript">last blog post</a> I talked about how to re-route events in Javascript.  It comes in handy from time to time, but some people prefer an alternate paradigm -- one that is probably more familiar to Win32 programmers.</p>
	<p>It's called <code>setCapture</code>.  It's proprietary, and it's native to only the IE browser (as far as I know).</p>
	<h3>What's .setCapture() good for?</h3>
	<p>Put simply, <code>.setCapture()</code> redirects all <i>mouse</i> events to a specified DOM element until a call to <code>.releaseCapture()</code> is made.  Why would you want this?  I can think of a couple scenarios.</p>
	<ol>
	<li>Drag n' Drop: you wire up mousedown to some element to start the drag operation, but wiring up mousemove and mouseup on that same element could be problematic -- the user may mouse too fast and your code might not be able to "keep up."  Using <code>.setCapture()</code> on said element however, will redirect all mouse events to the appropriate element so that the mousemove and mouseup handlers are guaranteed to execute.</li>
	<li>Dropdown Menus: you want the next mousedown to dismiss a dropdown menu.  A first crack at this might be to wire up mousedown to the <code>&lt;body&gt;</code> element, but if some other element on the page is listening for mousedown and is stopping event propagation, the mousedown may never make it to the <code>&lt;body&gt;</code> element -- <code>.setCapture()</code> will solve this problem.</li>
	</li>
	</ol>
	<p>These aren't the only applications of <code>.setCapture()</code> of course, but they're two of the most common and they're a good illustration of how <code>.setCapture()</code> can be useful.</p>
	<h3>Gimme's version of .setCapture(..)</h3>
	<p>Even though Mozilla/Firefox and other W3C browsers don't natively support <code>.setCapture()</code>, <a href = "http://codeplex.com/gimme" title = "The Gimme Javascript Library">Gimme</a> solves this problem by simulating the capability for browsers  that don't natively support it.  Using Gimme's version is a snap.</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="co1">// just a shortcut for document.getElementById(..)</span><br />
<span class="kw2">var</span> dragElem = Gimme.<span class="me1">id</span><span class="br0">&#40;</span><span class="st0">'dragElem'</span><span class="br0">&#41;</span>;</p>
	<p><span class="co1">// #dragElem will capture all mouse events until</span><br />
<span class="co1">// a call to Gimme.Events.releaseMouse() is made</span><br />
Gimme.<span class="me1">Events</span>.<span class="me1">captureMouse</span><span class="br0">&#40;</span>dragElem<span class="br0">&#41;</span>;</div>
	<p>A simple call to <code>Gimme.Events.captureMouse(myElem)</code> will do the trick (where <code>myElem</code> is the DOM element that should capture all mouse events).</p>
	<p>This example, of course, doesn't accomplish anything very useful, but here's an example that's a bit more practical.</p>
	<p>This snippet gives drag/drop capabilities to all elements marked with the class "draggable" (it looks long but that's just comments and a big font).</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'.draggable'</span><span class="br0">&#41;</span>.<span class="me1">iterate</span><span class="br0">&#40;</span>makeDraggable<span class="br0">&#41;</span>;<br />
<span class="kw2">function</span> makeDraggable<span class="br0">&#40;</span>idx<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// variables to keep track of the drag element's start position</span><br />
&nbsp; &nbsp;<span class="co1">// and the initial mousedown position</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> elemStartPos, mouseStartPos;</p>
	<p>&nbsp; &nbsp;<span class="co1">// wire up mousedown to start the drag operation</span><br />
&nbsp; &nbsp;<span class="co1">// and stop click events from propagating (just in case)</span><br />
&nbsp; &nbsp;<span class="kw1">this</span><br />
&nbsp; &nbsp;.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'mousedown'</span>, mouseDown<span class="br0">&#41;</span><br />
&nbsp; &nbsp;.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'click'</span>, stopEvent<span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;<span class="kw2">function</span> mouseDown<span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// instruct all mouse events to be redirected to the current dragElem</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;Gimme.<span class="me1">Events</span>.<span class="me1">captureMouse</span><span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// prevent the mousedown event from propagating</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">stopPropagation</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// create a gimme object from the element being moused down on</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> gObj = g<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// keep a ref to the dragElem's start position</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// and to the initial mousedown position</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;elemStartPos = gObj.<span class="me1">getPagePosition</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;mouseStartPos = Gimme.<span class="me1">Screen</span>.<span class="me1">getMousePosition</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// now, hook the mousemove and mouseup events</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;gObj<br />
&nbsp; &nbsp;&nbsp; &nbsp;.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'mousemove'</span>, mouseMove<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'mouseup'</span>, mouseUp<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw2">function</span> mouseMove<span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// prevent the mousemove event from propagating</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">stopPropagation</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// get the current mouse position</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> mousePos = Gimme.<span class="me1">Screen</span>.<span class="me1">getMousePosition</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// position the dragElem (element's start position + mouse delta)</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;g<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;.<span class="me1">setStyle</span><span class="br0">&#40;</span><span class="st0">'top'</span>, elemStartPos.<span class="me1">y</span> + <span class="br0">&#40;</span>mousePos.<span class="me1">y</span> - mouseStartPos.<span class="me1">y</span><span class="br0">&#41;</span> + <span class="st0">'px'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;.<span class="me1">setStyle</span><span class="br0">&#40;</span><span class="st0">'left'</span>, elemStartPos.<span class="me1">x</span> + <span class="br0">&#40;</span>mousePos.<span class="me1">x</span> - mouseStartPos.<span class="me1">x</span><span class="br0">&#41;</span> + <span class="st0">'px'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw2">function</span> mouseUp<span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// instruct Gimme to stop capturing mouse events</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;Gimme.<span class="me1">Events</span>.<span class="me1">releaseMouse</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// prevent the mouseup event from propagating</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">stopPropagation</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// remove the mousemove and mouseup handlers</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;g<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;.<span class="me1">removeEvent</span><span class="br0">&#40;</span><span class="st0">'mousemove'</span>, mouseMove<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;.<span class="me1">removeEvent</span><span class="br0">&#40;</span><span class="st0">'mouseup'</span>, mouseUp<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw2">function</span> stopEvent<span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">stopPropagation</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;e.<span class="me1">preventDefault</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
	<p>Before I get into an explanation of the code, the following note is significant:</p>
	<div class = "note">
The current version of Gimme (<a href = "http://www.codeplex.com/gimme/Release/ProjectReleases.aspx?ReleaseId=7638" title = "Gimme (Belisar)">Belisar</a>) doesn't offer <code>Gimme.Events.captureMouse(..)</code>.  This capability is new to Gimme (Caspian) which is currently in a pre-release state.  You can access Caspian now by visiting the <a href = "http://www.codeplex.com/gimme/SourceControl/ListDownloadableCommits.aspx" title = "Gimme Source">Source Code Section</a> on the Gimme Codeplex site, or you can wait for the official release of Caspian, which should be sometime in late January.
</div>
	<h3>Explanation</h3>
	<p>If you understand Gimme, the code here is really pretty straight-forward.</p>
	<p> A mousedown event starts the drag operation by recording the mouse down position and the element's start position.  Then, the <code>mouseMove</code> handler ensures that the element moves along with the mouse delta (delta from the mouse start position).  Finally, the <code>mouseUp</code> handler ends the drag operation by removing event handlers that are no longer needed and releasing capture.</p>
	<p>We prevent events from propagating (bubbling) in all cases, so that we don't get other elements interfering during a drag operation.  And we use Gimme's <code>Gimme.Events.captureMouse(..)</code> capabilities to ensure the the mousemove and mouseup events are directed to the appropriate element.  Otherwise we risk some other element "stealing" the mousemove or mouseup away from the intended element.</p>
	<h3>What does <code>this</code> refer to exactly?</h3>
	<p>Good question; it's the one thing in the Gimme drag/drop code that I can see tripping people up.  The <code>this</code> keyword is somewhat polymorphic in Gimme, so what does it refer to exactly?</p>
	<p>The answer is that is depends on context.  Most of the time in Gimme, you'll be using <code>this</code> inside of an event handler function.  In that case, <code>this</code> refers to the <i>DOM</i> element to which the event was wired up.  For example:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'#myElem'</span><span class="br0">&#41;</span>.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'click'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// alerts &quot;myElem&quot;</span><br />
&nbsp;&nbsp; <span class="co1">// since 'this' refers to #myElem in the current context</span><br />
&nbsp; &nbsp;<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>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
	<p>In some cases though, you may want to use the Gimme <a href = "http://www.codeplex.com/gimme/Wiki/View.aspx?title=.iterate%28callback%29&#038;referringTitle=Complete%20API%20Reference" title = "The Gimme .iterate(..) function">.iterate(..)</a> function.  In that case, <code>this</code> refers to the current Gimme Object being iterated over, <i>not</i> a DOM element, but it's possible to combine both concepts.  For instance:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'#container &gt; .funny'</span><span class="br0">&#41;</span>.<span class="me1">iterate</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>idx<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// here, 'this' refers to the current Gimme Object,</span><br />
&nbsp; &nbsp;<span class="co1">// which is why .addEvent(..) is okay here</span><br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'click'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// here, 'this' refers to the DOM element receiving the click event,</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// so we can access native properties, like .parentNode</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">parentNode</span>.<span class="me1">removeChild</span><span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
	<p>In case you hadn't figured it out, the above snippet makes it so that all elements with the class "funny" that are direct children of <code>#container</code> will be removed from the DOM when clicked -- pretty trivial with Gimme.</p>
	<p>But this is all secondary to the discussion at hand: capturing mouse events, which, thanks to Gimme, is also pretty trivial!</p>
	<p>If you're new to Gimme, check out the <a href = "http://gimme.stchur.com" title = "The Gimme Javascript Library">Gimme Promo Page</a> and the <a href = "http://codeplex.com/gimme">Gimme Codeplex Page</a>.</p>
	<p>You can also download a debug version of Caspian <a href = "http://gimme.stchur.com/src/debug/gimme.caspian.js" title = "Gimme (Caspian) Source">here</a> if you just want to monkey around with it.</p>
	<p>Note once again, that an official (and compressed) version of Caspian will be available sometime in late January.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/11/21/setcapture-with-gimme/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Gimme</title>
		<link>http://blog.stchur.com/2007/06/22/introducing-gimme/</link>
		<comments>http://blog.stchur.com/2007/06/22/introducing-gimme/#comments</comments>
		<pubDate>Fri, 22 Jun 2007 17:08:16 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/06/22/introducing-gimme/</guid>
		<description><![CDATA[It's been quite a while since I've blogged anything significant regarding Javascript. This is largely due to the fact that I've been spending a good bit of my free time working on an open source project I started, called Gimme. Gimme is a Javascript Library designed to make performing common tasks, not only easier, but [...]]]></description>
			<content:encoded><![CDATA[	<p>It's been quite a while since I've blogged anything significant regarding Javascript.  This is largely due to the fact that I've been spending a good bit of my free time working on an open source project I started, called Gimme.</p>
	<p>Gimme is a Javascript Library designed to make performing common tasks, not only easier, but down-right trivial.</p>
	<h3>What does Gimme look like?</h3>
	<p>Gimme is remarkably easy to use and was purposely designed to be very readable.  Take the following snippet.</p>
	<div class="dean_ch" style="white-space: nowrap;">
g<span class="br0">&#40;</span><span class="st0">'.moveable'</span><span class="br0">&#41;</span>.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">'hasBeenMoved'</span><span class="br0">&#41;</span>.<span class="me1">slideToPoint</span><span class="br0">&#40;</span><span class="br0">&#123;</span>x: <span class="nu0">0</span>, y: <span class="nu0">0</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp;</div>
	<p>This code snippet grabs all elements on the page that have the class "moveable", adds to them, the class "hasBeenMoved," and then slides the elements (in a nice accelerated fashion) to the point (0, 0) on the page.  Pretty easy right?</p>
	<p>Believe it not, most tasks in Gimme are this easy (or easier).</p>
	<h3>Get started with Gimme</h3>
	<ul>
	<li>See it in action on the <a href = "http://gimme.stchur.com/demopage.html">Gimme Demo Page</a></li>
	<li>Learn what it can do at the <a href = "http://www.codeplex.com/gimme/Wiki/View.aspx?title=Complete%20API%20Reference&#038;referringTitle=Home">Gimme API Reference Page</a>.</li>
	<li>Download the source on the <a href = "http://www.codeplex.com/gimme/Release/ProjectReleases.aspx">Gimme Releases Page</a>.</li>
	</ul>
	<h3>Your Feedback</h3>
	<p>Gimme is still very young, but I'd love to get your feedback.  Please don't hesitate to try it out and <a href = "mailto:sstchur@yahoo.com">let me know what you think</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/06/22/introducing-gimme/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Optimize your Javascript cross-browser code through branching</title>
		<link>http://blog.stchur.com/2007/04/26/optimize-your-javascript-cross-browser-code-through-branching/</link>
		<comments>http://blog.stchur.com/2007/04/26/optimize-your-javascript-cross-browser-code-through-branching/#comments</comments>
		<pubDate>Thu, 26 Apr 2007 17:24:20 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Javascript basics]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/04/26/optimize-your-javascript-cross-browser-code-through-branching/</guid>
		<description><![CDATA[Dustin Diaz recently published an article outlining seven Javascript techniques that you'd be wise to start using in your scripts. It's a well written article and you should definitely give it read if you haven't already. Whether you're just beginning with Javascript or you consider yourself an expert, Dustin's article surely has something for you. [...]]]></description>
			<content:encoded><![CDATA[	<p><a href = "http://www.dustindiaz.com">Dustin Diaz</a> recently published <a href = "http://www.digital-web.com/articles/seven_javascript_techniques/">an article</a> outlining seven Javascript techniques that you'd be wise to start using in your scripts.  It's a well written article and you should definitely give it read if you haven't already.  Whether you're just beginning with Javascript or you consider yourself an expert, Dustin's article surely has something for you.</p>
	<p>One concept he writes about that I particularly like is that of "branching."  I've never actually heard it called that before, but it's a very sound concept and one that I doubt is being utilized often enough by today's Javascripters.</p>
	<p><span id="more-42"></span></p>
	<h3>What is branching?</h3>
	<p>Put simply, branching (in Javascript) is the use of closures to get the browser to interpret a block of code only one time, when otherwise, it would interpret that block over and over and over again (presumably, each time you call your function).</p>
	<p>Why would you want to do this?  Because, when it comes to cross-browser code, chances are you have a lot object detection code whose primary purpose is to determine if the browser supports a particular feature/property, like this:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">function</span> addEvent<span class="br0">&#40;</span>el, evt, fn<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> elem.<span class="me1">addEventListener</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// w3c event wire up here</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> elem.<span class="me1">attachEvent</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp;&nbsp; &nbsp; &nbsp;<span class="co1">// ie event wire up here...</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
	<p>The above is a very simplified version of a cross-browser <code>addEvent(..)</code> function that takes care of (some of) the differences in event models between IE and W3C browsers.  This is all well and good, but consider what happens when I do the following:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> elems = document.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'div'</span><span class="br0">&#41;</span>; &nbsp; &nbsp; <span class="co1">// assume 5000 &lt;div&gt; elements returned</span><br />
<span class="kw2">var</span> i, len = elems.<span class="me1">length</span>;<br />
<span class="kw1">for</span> <span class="br0">&#40;</span>i = <span class="nu0">0</span>; i &lt; len; i++<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;addEvent<span class="br0">&#40;</span>elems<span class="br0">&#91;</span>i<span class="br0">&#93;</span>, <span class="st0">'click'</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="st0">'Hi there!'</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
	<p>Five thousand times the browser is checking: <code>if (typeof elem.addEventListener !== 'undefined')...</code> -- once for each element in the <code>elems</code> array!  Gosh, that feels like a waste, doesn't it?  Wouldn't it be good if we could somehow tell the browser: <q class = "shout">Hey browser, once you've figured out that .addEventListener(..) is supported, don't bother checking again for the next 4999 iterations!</q>?</p>
	<p>It turns out you <em>can</em> achieve something like this, through the use of branching.</p>
	<h3>Branching in action</h3>
	<p>In a sense, branching is a lot like conditional compilation.  Similarly to the way you can use #ifdef directives to instruct your C-style programs to conditionally compile certain blocks of code into your executable, branching allows you to conditionally "compile" (as it were) certain blocks of code into your Javascript.</p>
	<p>This is accomplished by creating separate functions that contain your cross-browser logic and then wrapping them up inside of another function, which will return the appropriate function when executed.  The nifty part though, is that this outer function will only be executed <em>one time</em> (that's the sort of "conditional compilation" part).</p>
	<p>An example should help illustrate this:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> addEvent = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">function</span> ie_addEvent<span class="br0">&#40;</span>el, evt, fn<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;el.<span class="me1">attachEvent</span><span class="br0">&#40;</span><span class="st0">'on'</span> + evt, fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw2">function</span> w3c_addEvent<span class="br0">&#40;</span>el, evt, fn, useCap<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;el.<span class="me1">addEventListener</span><span class="br0">&#40;</span>evt, fn, useCap<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> window.<span class="me1">addEventListener</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> w3c_addEvent;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> window.<span class="me1">attachEvent</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> ie_addEvent;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; &nbsp; <span class="co1">// &lt;= This is the critical part!</span></div>
	<p>In the preceding example, I've separated out the logic for IE and W3C browsers into two separate functions.  Those functions have been declared within the scope of the <code>addEvent()</code>, so they're not accessible from outside.</p>
	<p>The most critical thing to notice though, is the use of <code>}();</code> at the very end of the code.  It's important to realize what's happening here.  We're declaring a function, <code>addEvent</code>, with the code: <code>var addEvent = function() {</code>, and then we're immediately executing that function at the end of its declaration with <code>}();</code>.</p>
	<h3>What it means for you</h3>
	<p>This means that as the Javascript interpreter is parsing your code, it will execute the <code>addEvent()</code> function right away, whose logic instructs the browser return one of two functions (but not both)!</p>
	<p>The net effect of this is that <code>addEvent</code> will be equal to <code>ie_addEvent</code> when IE is being used, and it will be equal to <code>w3c_addEvent</code> when W3C browsers are being used.  In either case, the browser only needed to execute the if-conditional one time.  Beautiful!</p>
	<p>You can prove to yourself that this works, but simply executing: <code>alert(addEvent.toString())</code> in both IE and in a W3C browser.  Notice that you'll get the proper function for each browser, but that neither function includes any <code>if (typeof blah_blah_blah)...</code> checks.</p>
	<h3>Conclusion</h3>
	<p>It's no surprise that this is going to be <em>much</em> more efficient than the original <code>addEvent(..)</code> function, which did not utilize branching.  After all, it's 4,999 fewer <code>if (typeof ...)</code> checks for the browser to execute!</p>
	<p>This concept isn't necessarily limited to cross-browser code either.  Branching can be useful in lots of situations.  As always, I'd recommend analyzing <em>your particular</em> situation and determining if branching is going to beneficial for you (chances are, it will).</p>
	<p>If you haven't already, be sure to check out <a href = "http://www.digital-web.com/articles/seven_javascript_techniques/">Dustin's article</a>.  Besides branching, he covers six other useful techniques that every Javascripter should be aware of.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/04/26/optimize-your-javascript-cross-browser-code-through-branching/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Serializing Objects in Javascript</title>
		<link>http://blog.stchur.com/2007/04/06/serializing-objects-in-javascript/</link>
		<comments>http://blog.stchur.com/2007/04/06/serializing-objects-in-javascript/#comments</comments>
		<pubDate>Fri, 06 Apr 2007 06:12:06 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/04/06/serializing-objects-in-javascript/</guid>
		<description><![CDATA[It's worth noting that this post is rather old at this point. I don't use the function listed in this post anymore and haven't for a rather long time. If you are using it and it's working for you, great! But as Ron in the comments sections points out, there are a few issues with [...]]]></description>
			<content:encoded><![CDATA[	<div class = "note">It's worth noting that this post is rather old at this point.  I don't use the function listed in this post anymore and haven't for a rather long time.  If you are using it and it's working for you, great!  But as Ron in the comments sections points out, there are a few issues with regards to strings and special characters.  I recommend following the link he posts if your needs merit a very robust version of JSON serialization.  I'm leaving this post up though, as I think it's helpful for folks who want to understand the general concept of recursion and serialization.</div>
	<p>Recently, in a personal project I'm working on, I came across a need to be able to represent any Javascript object as a string.  This isn't a problem since just about every object in Javascript can be represented with <abbr title = "Javascript Object Notation">JSON</abbr> (Javascript Object Notation).  Every modern browser can parse <abbr>JSON</abbr> for you easily enough through <code>eval(..)</code>, and Gecko-based browsers even have the ability to reverse the process ("uneval" if you will) and give you back a string representation of an object through a call to <code>.toSource()</code>.</p>
	<p>If you need this ability in any other browser though, you're gonna have to write it yourself.  I needed this ability, so I wrote it (and posted it here for your enjoyment!)</p>
	<p><span id="more-41"></span></p>
	<h3>Gecko-based browsers, .toSource():</h3>
	<p>Gecko-based browsers provide a handy function: <code>.toSource()</code> that you can call on any object in your Javascript code to get back a JSON-like representation of that object.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">function</span> Cat<span class="br0">&#40;</span><span class="kw3">name</span>, age<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="kw3">Name</span> = <span class="kw3">name</span>;<br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">Age</span> = age;<br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">Speak</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="st0">'Meow!'</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span>;<br />
<span class="br0">&#125;</span></p>
	<p><span class="kw2">var</span> garfield = <span class="kw2">new</span> Cat<span class="br0">&#40;</span><span class="st0">'Garfield'</span>, <span class="nu0">5</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span>garfield.<span class="me1">toSource</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
	<p><span class="coMULTI">/* garfield.toSource() yields:<br />
({Name:&quot;Garfield&quot;, Age:5, Speak:(function () {alert(&quot;Meow!&quot;);})})<br />
*/</span><br />
&nbsp;</div>
	<p>Pretty simple right?  You have an object; you want a string.  Just invoke the object's <code>.toSource()</code> function.</p>
	<h3>Serializing objects in other browsers:</h3>
	<p>Serializing an object manually (as is required by non Gecko-based browsers) requires a bit of <a href = "http://en.wikipedia.org/wiki/Recursion">recursion</a>.  Simple types like integers, booleans, and even functions are trivial to represent as strings.  Objects though, are more complicated because they can contain simple types <em>or</em> custom objects (which would need to be serialized themselves).  Those "inner" objects could in turn, contain <em>more</em> custom objects, which would <em>also</em> need to be serialized, and this pattern could (theoretically) go on forever.</p>
	<p>In practice of course, this pattern <em>will</em> (had better) come to an end.  And we can leverage that fact to write a recursive function that will return a string representation (in <abbr>JSON</sbbr> format) of a given object.</p>
	<h3>The serialize(..) function:</h3>
	<p>First the code, then the explanation.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">function</span> serialize<span class="br0">&#40;</span>_obj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// Let Gecko browsers do this the easy way</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _obj.<span class="me1">toSource</span> !== <span class="st0">'undefined'</span> &amp;&amp; <span class="kw1">typeof</span> _obj.<span class="me1">callee</span> === <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _obj.<span class="me1">toSource</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// Other browsers must do it the hard way</span><br />
&nbsp; &nbsp;<span class="kw1">switch</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _obj<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// numbers, booleans, and functions are trivial:</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// just return the object itself since its default .toString()</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// gives us exactly what we want</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'number'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'boolean'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'function'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _obj;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// for JSON format, strings need to be wrapped in quotes</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'string'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'<span class="es0">\'</span>'</span> + _obj + <span class="st0">'<span class="es0">\'</span>'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'object'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> str;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_obj.<span class="me1">constructor</span> === Array || <span class="kw1">typeof</span> _obj.<span class="me1">callee</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = <span class="st0">'['</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> i, len = _obj.<span class="me1">length</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>i = <span class="nu0">0</span>; i &lt; len<span class="nu0">-1</span>; i++<span class="br0">&#41;</span> <span class="br0">&#123;</span> str += serialize<span class="br0">&#40;</span>_obj<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span class="st0">','</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str += serialize<span class="br0">&#40;</span>_obj<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span class="st0">']'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = <span class="st0">'{'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> key;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>key <span class="kw1">in</span> _obj<span class="br0">&#41;</span> <span class="br0">&#123;</span> str += key + <span class="st0">':'</span> + serialize<span class="br0">&#40;</span>_obj<span class="br0">&#91;</span>key<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span class="st0">','</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = str.<span class="me1">replace</span><span class="br0">&#40;</span><span class="re0">/\,$/</span>, <span class="st0">''</span><span class="br0">&#41;</span> + <span class="st0">'}'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> str;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">default</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'UNKNOWN'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
	<p>Explaining a recursive function can be difficult, but I'll give it shot:</p>
	<p>The function accepts just one parameter: the object (<code>_obj</code>) to be serialized.  If you'll remember, I mentioned previously that simple types (string, boolean, number, etc...) were trivial because they all have an obvious string representation already.  Complex types though, are more difficult because they can be made up of additional complex types, which in turn could be made up of additional complex types (and so on).</p>
	<p>Of course, this pattern will eventually end; ultimately, everything is made up of simple types that have a string representation.  The trick is figuring out how to traverse through this maze of "types within types."  Recursion (simply stated: a function that calls itself) is perhaps the easiest way to solve this "types within types" problem.</p>
	<p>Recursive functions always have a termination case -- something which causes the function to <em>stop</em> calling itself.  Otherwise, the function would go into an infinite loop.  In our function, there are actually four different cases in which the <code>serialize(..)</code> doesn't need to call itself:</p>
	<ol>
	<li>typeof _obj is a number</li>
	<li>typeof _obj is a boolean</li>
	<li>typeof _obj is a function</li>
	<li>typeof _obj is a string</li>
	</ol>
	<p>If any of the above four conditions are met, returning a string representation is trivial, so we simply do it.</p>
	<div class = "note">
You'll notice that strings are treated separately from the other 3 types.  You'd think strings would be the most trivial case, but actually, there is one thing we must do before returning the "string representation" of <code>_obj</code> when it is of type string:  wrap it in quotes.  We need to do this, because JSON expects it, and if we ever want to be able to <code>eval(..)</code> the result of a <code>serialize(..)</code> call, we'll need these quotes.
</div>
	<p>The only other case to deal with is when <code>_obj</code> is of type <code>object</code>.  Within this case though, there are two "sub-cases" we need to deal with.  The first is when <code>_obj</code> is an <code>Array</code>, or when it has a <code>.callee</code> property (more on that later).  The second is well... anything else.</p>
	<h3>Basic Object Types</h3>
	<p>Your every-day, run-of-the-mill, object in Javascript can be represented as JSON with:</p>
	<p><code>{ key1: val1, key2: val2, ... }</code></p>
	<p>Where the keys are strings and the vals can be any simple type, or some custom object you've dreamed up.  The logic I've used is to simply loop through a given object's keys and build a string of comma delimited, <em>serialized</em> key/value pairs that are wrapped in { and }.</p>
	<p>Notice I said <em>serialized</em> key/value pairs.  Here, our function is calling itself as it builds the object representation.  This ensures that any objects within the object being serialized will <em>also</em> be serialized.  If we didn't do this, we'd end up with a lot of strings that looked (something) like this:</p>
	<p><code>{ key1: [object Object], key2: [object Object], etc... }</code></p>
	<p>And that's clearly not what we want.  We want those inner objects to be serialized as well, and that's what the recursive nature of our function will take care of for us.</p>
	<h3>Arrays</h3>
	<p>When <code>_obj</code> happens to be, not just any object, but more specifically, an <code>Array</code>, we have a better way of representing that as a string:</p>
	<p><code>[ val1, val2, val3, ... ]</code></p>
	<p>The logic I used here is to simply iterate through the array building a comma delimited list of <em>serialized</em> values, wrapped in [ and ].  Arrays in Javascript already have a <code>.toString()</code> function, but we can't use it here; if the Array contains objects, then the result of the Array 's <code>.toString()</code> could end up something like:</p>
	<p><code> [ [object Object], [object Object], etc... ]</code></p>
	<p>Again, not what we want, so we need to make sure we recursively serialize all of the elements in the array.</p>
	<h3>Arguments (the .callee "gotcha")</h3>
	<p>There's one bit of code I haven't discussed yet and it deals with the (possible) <code>.callee</code> property of the passed in <code>_obj</code>.  It turns out that <code>.toSource()</code> (native function used by Gecko-based browsers) doesn't do anything very useful when called on an <code>arguments</code> object.</p>
	<p>The <code>arguments</code> object is an array-like (but not an Array) object that is automatically available within the scope of every function.  Unfortunately, no matter what is contained within that <code>arguments</code> object, calling <code>.toSource()</code> on it will always return <code>"({})"</code></p>
	<p>In order to be able to serialize an <code>arguments</code> object then, we need some way to detect it and then treat it like an array.  The <code>.callee</code> property is a good choice because <code>arguments</code> objects have it, but other objects (to the best of my knowledge) do not.</p>
	<p>In the case of the <code>serialize(..)</code> function, I decided to use the native <code>.toSource()</code> function whenever it was available, <em>unless</em> the object were an <code>arguments</code> object, in which case, I send Gecko-based browsers down the same path as all other browsers for serialization.</p>
	<p>Finally, just for good measure, I've added a default case which returns the string <code>UNKNOWN</code> to handle a situation where no other cases applied.  Of course, we probably don't <em>want</em> <code> UNKNOWN</code> showing up in the our serialized strings, but it probably won't do much (immediate) harm if it ever does show up, <em>and</em> its presence would be a helpful indicator that there is some case not being met (that probably needs to be).</p>
	<h3>Conclusion:</h3>
	<p>What would you ever use a function like this for?  Well, In my case, I wanted to use a Javascript object as the key for a hash, but if I tried to do that, Javascript would just represent all of my (different) objects as the same string: <code>[object Object]</code>, which wouldn't do me any good.  By serializing the object, I can then use that serialized representation as a key in the hash.</p>
	<p>It's worked well for my need so far, but I haven't tested it a great deal.  If you find any bugs or short-comings, please let me know.</p>
	<p>As always, comments are welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/04/06/serializing-objects-in-javascript/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>.split(..) broken in IE</title>
		<link>http://blog.stchur.com/2007/03/28/split-broken-in-ie/</link>
		<comments>http://blog.stchur.com/2007/03/28/split-broken-in-ie/#comments</comments>
		<pubDate>Wed, 28 Mar 2007 03:40:40 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Javascript basics]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/03/28/split-broken-in-ie/</guid>
		<description><![CDATA[I discovered last weekend, something about IE which I had previously never known (probably because I use Firefox/Firebug to write and test most of my Javascript). It turns out that the implementation of .split(..) is broken in IE (for more complex cases). If you stick with the simpler cases when using this function, then you [...]]]></description>
			<content:encoded><![CDATA[	<p>I discovered last weekend, something about IE which I had previously never known (probably because I use Firefox/Firebug to write and test most of my Javascript).  It turns out that the implementation of <code>.split(..)</code> is broken in IE (for more complex cases).  If you stick with the simpler cases when using this function, then you probably won't have ever noticed this.  For example, the following works just fine:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> s = <span class="st0">'This-is-a-hyphen-delimited-string'</span>;<br />
<span class="kw2">var</span> split = s.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">'-'</span><span class="br0">&#41;</span>;&nbsp; <span class="co1">// returns &nbsp;['This', 'is', 'a', 'hyphen', 'delimited', 'string']</span></div>
	<p>The above code will work in just about every browser under the sun, including IE, but of course, it's the simplest case scenario for the <code>.split(..)</code> function.  Many programmers will probably be aware that you're not limited to passing in a string; you can also pass in a regular expression, which IE (mostly) supports, but this is where things can start to fall apart on you (in IE anyway).</p>
	<p>Read on to learn more.</p>
	<p><span id="more-33"></span></p>
	<p>The <code>.split(..)</code> function is pretty robust.  You can pass in a simple string, which indicates what character (or characters) you want to use use as a delimiter, or you can pass in a regular expression instead of a string.  Take the following example:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> s = <span class="st0">'My~Silly.Test-String'</span>;<br />
<span class="kw2">var</span> split = s.<span class="me1">split</span><span class="br0">&#40;</span><span class="re0">/~|\.|-/</span><span class="br0">&#41;</span>;&nbsp; &nbsp;<span class="co1">// returns [ 'My', 'Silly', 'Test', 'String' ]</span></div>
	<p>In the above example, the string, <code>s</code> will be split by any of the characters: <code>"~", ".", or "-"</code>.  The regular expression makes this really easy to do.  But one thing you'll notice is that the delimiters themselves are not captured.  This might not be a problem for you; in fact, you might not <em>want</em> the delimiters captured, in which case no problem.  But suppose you do.  Suppose you want the result of your split to be:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="br0">&#91;</span> <span class="st0">'My'</span>, <span class="st0">'~'</span>, <span class="st0">'Silly'</span>, <span class="st0">'.'</span>, <span class="st0">'Test'</span>, <span class="st0">'-'</span>, <span class="st0">'String'</span> <span class="br0">&#93;</span></div>
	<p>In that case, you need to modify your regular expression, and unfortunatly, the needed modification isn't going to work in IE.  Here's how's you'd accomplish it in most other browsers (it's remarkably easy).</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> s = <span class="st0">'My~Silly.Test-String'</span>;<br />
<span class="kw2">var</span> split = s.<span class="me1">split</span><span class="br0">&#40;</span><span class="re0">/<span class="br0">&#40;</span>~|\.|-/</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;&nbsp;<span class="co1">// returns ['My', '~', 'Silly', '.', 'Test', '-', 'String']</span></div>
	<p>You'll notice (or maybe not, since the change was so minor) that I didn't have to do much to get the desired result.  All that was needed was wrapping the contents of my regular expression in parenthesis, thus indicating a <a href = "http://en.wikipedia.org/wiki/Regular_expression">regular expression grouping</a>.</p>
	<p>Unfortunately, in IE's implementation of <code>.split(..)</code>, it completely ignores the grouping request.  So while your result will still be an array split by the requested delimiters, those delimiters won't be included in the array!</p>
	<p>So, what do we do when IE won't cooperate with with us?  Why, we beat it into submission of course, and here's how.</p>
	<h3>The .xSplit(..) function</h3>
	<p>I call it <code>xSplit(..)</code> because it's a sort of "eXtended" version of the native <code>.split(..)</code> function.  Anytime I'm writing/enhancing a version of a function that already exists, I like to use the "x" to help my eyes quickly distinguish between the preferred native function and my own custom implementation (actually, I don't really do that; I just made that up now, but it seems like a reasonable idea, so maybe I'll start!).</p>
	<p>The <code>xSplit(..)</code> function will work more or less like the native function, with just one small difference:  it will only accept regular expressions.  Strings won't be accepted; the native <code>.split(..)</code> function for that.</p>
	<p>Here is the full code, with an explanation to follow.</p>
	<div class="dean_ch" style="white-space: nowrap;">
String.<span class="me1">prototype</span>.<span class="me1">xSplit</span> = <span class="kw2">function</span><span class="br0">&#40;</span>_regEx<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// Most browsers can do this properly, so let them -- they'll do it faster</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="st0">'a~b'</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="re0">/<span class="br0">&#40;</span>~<span class="br0">&#41;</span>/</span><span class="br0">&#41;</span>.<span class="me1">length</span> === <span class="nu0">3</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">split</span><span class="br0">&#40;</span>_regEx<span class="br0">&#41;</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>!_regEx.<span class="me1">global</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> _regEx = <span class="kw2">new</span> RegExp<span class="br0">&#40;</span>_regEx.<span class="me1">source</span>, <span class="st0">'g'</span> + <span class="br0">&#40;</span>_regEx.<span class="me1">ignoreCase</span> ? <span class="st0">'i'</span> : <span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// IE (and any other browser that can't capture the delimiter)</span><br />
&nbsp; &nbsp;<span class="co1">// will, unfortunately, have to be slowed down</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> m, str = <span class="st0">''</span>, arr = <span class="br0">&#91;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;<span class="kw2">var</span> i, len = <span class="kw1">this</span>.<span class="me1">length</span>;<br />
&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>i = <span class="nu0">0</span>; i &lt; len; i++<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;str += <span class="kw1">this</span>.<span class="me1">charAt</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;m = str.<span class="me1">match</span><span class="br0">&#40;</span>_regEx<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>m<span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;arr.<span class="me1">push</span><span class="br0">&#40;</span>str.<span class="me1">replace</span><span class="br0">&#40;</span>m<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, <span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;arr.<span class="me1">push</span><span class="br0">&#40;</span>m<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = <span class="st0">''</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>str != <span class="st0">''</span><span class="br0">&#41;</span> arr.<span class="me1">push</span><span class="br0">&#40;</span>str<span class="br0">&#41;</span>;</p>
	<p>&nbsp; &nbsp;<span class="kw1">return</span> arr;<br />
<span class="br0">&#125;</span></div>
	<h3>Explanation:</h3>
	<p>The code isn't too hard, but it's worth pointing out a few specific points.</p>
	<p>First, I'm extending the native <code>String</code> object using <code>.prototype</code>.  I know some people aren't comfortable with this, and if you're one of them, feel free to write a stand-alone function where you pass in a string variable, as well as the regex.</p>
	<p>Second, Most browsers actually will capture the delimiter when you use regular expression grouping, so if the client happens to be using a browser that can do it, we'll want to use the native implementation, as it will be <em>much</em> faster.  We do it like this:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="st0">'a~b'</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="re0">/<span class="br0">&#40;</span>~<span class="br0">&#41;</span>/</span><span class="br0">&#41;</span>.<span class="me1">length</span> === <span class="nu0">3</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">split</span><span class="br0">&#40;</span>_regEx<span class="br0">&#41;</span>; <span class="br0">&#125;</span></div>
	<p>The above code does a very simple test in which we check to see if the split of "a~b" on the character "~" returns an array of length 3.  If so, we assume support for regular expression grouping with the <code>.split(..)</code> function.  Otherwise, we're forced to do this manually.</p>
	<p>Now, if we <em>do</em> need to do this manually, the regular expression had better have its global (/g) flag set.  Why?  Because we're executing a <code>.match(..)</code> on the <code>_regEx</code> later on in the code, and in order for that to match more than just the first delimiter it finds, that global flag needs to be set.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">if</span> <span class="br0">&#40;</span>!_regEx.<span class="me1">global</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span> _regEx = <span class="kw2">new</span> RegExp<span class="br0">&#40;</span>_regEx.<span class="me1">source</span>, <span class="st0">'g'</span> + <span class="br0">&#40;</span>_regEx.<span class="me1">ignoreCase</span> ? <span class="st0">'i'</span> : <span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span></div>
	<p>This code first checks to see if the global flag is already set.  If so, we're good shape; no need to make any alterations.  If not, we'll need to set it.  Problem is, the <code>.global</code> property of any regular expression object is read-only, so we must construct a new <code>RegExp</code> using the <code>.source</code> of the original <code>_regEx</code> and manually specify the global flag (by passing in a 'g').  Additionally, we need to make sure we maintain any request in the original regular expression to ignore case, which is accomplished with: <code>(_regEx.ignoreCase ? 'i' : '')</code>.</p>
	<p>The rest of the logic is pretty straight-forward.  We loop through the given string, building, character by character, the strings that will make up the individual string elements in the array to be returned.  At each iteration through the loop, we'll test (using <code>.match(..)</code>) to see if the string we've built so far, contains any of the delimiters specified by the passed in <code>_regEx</code>.  If so, we need to push that string into the array, <em>but</em> we need to strip the delimiter out of the string before we do (hence the code: <code>arr.push(str.replace(m[0], ''));</code>).</p>
	<p>We also need to push the delimiter itself into the array and then reset the <code>str</code> variable back to an empty string.</p>
	<div class = "note">
It should be safe to access <code>m[0]</code> (and not bother with other indices).  Since we're testing the match on each iteration, we can expect to receive, at most, one match returned in the <code>m</code> array (even if that match is more than one character).
</div>
	<h3>Final thoughts:</h3>
	<p>It's worth pointing out that compared to the native <code>.split(..)</code>, my implementation is <strong>slow!</strong>  So, whenever you don't need to capture regular expression groupings, stick with the native function.  Of course, for browsers that support the feature natively, we'll be using the native <code>.split(..)</code> under the hood anyway, but regardless... if you know you won't need groupings, don't bother with <code>.xSplit(..)</code>.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/03/28/split-broken-in-ie/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

