<?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"
	>

<channel>
	<title>Incoherent Babble</title>
	<atom:link href="http://blog.stchur.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.stchur.com</link>
	<description>usually about Javascript, but I don't discriminate</description>
	<pubDate>Sat, 07 Mar 2009 06:00:16 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
	<language>en</language>
			<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[CSS Related]]></category>

		<category><![CDATA[Cross-Browser]]></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>
		</item>
		<item>
		<title>My New Blog</title>
		<link>http://blog.stchur.com/2008/11/07/my-new-blog/</link>
		<comments>http://blog.stchur.com/2008/11/07/my-new-blog/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 20:12:47 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/11/07/my-new-blog/</guid>
		<description><![CDATA[	This blog is mostly technical.  I do, from time to time, post about non-technical things, but I try to keep this blog more or less about programming, the web, and javascript.
	But I'm a loud-mouth and I have lots to say.  So rather than clutter up this blog with "too much" incoherent babble, I [...]]]></description>
			<content:encoded><![CDATA[	<p>This blog is mostly technical.  I do, from time to time, post about non-technical things, but I try to keep this blog more or less about programming, the web, and javascript.</p>
	<p>But I'm a loud-mouth and I have lots to say.  So rather than clutter up this blog with "too much" incoherent babble, I decided to start another.</p>
	<p>My new blog is called Stchur on Whatever (<a href = "http://whatever.stchur.com" title = "Stchur on Whatever">http://whatever.stchur.com</a>) and on it, I'll write about whatever the heck I feel like.</p>
	<p>So please check it out.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/11/07/my-new-blog/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hello Old Friend</title>
		<link>http://blog.stchur.com/2008/10/10/hello-old-friend/</link>
		<comments>http://blog.stchur.com/2008/10/10/hello-old-friend/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 12:59:13 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[Beating IE into submission]]></category>

		<category><![CDATA[CSS Related]]></category>

		<category><![CDATA[MiniPosts]]></category>

		<category><![CDATA[Web-related]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[font-size]]></category>

		<category><![CDATA[IE6]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/10/10/hello-old-friend/</guid>
		<description><![CDATA[More evidence that I was right when I wrote this post.

Won't be long now IE6...]]></description>
			<content:encoded><![CDATA[<p>More <a href = "http://orderedlist.com/articles/hello-old-friend" title = "font-size with pixels no longer considered harmful">evidence</a> that I was right when I wrote <a href = "http://blog.stchur.com/2008/01/15/ie5-is-dead-and-ie6-is-on-death-row/" title = "IE5 is Dead (and IE6 is on Death Row)">this post</a>.</p>

<p>Won't be long now IE6...</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/10/10/hello-old-friend/feed/</wfw:commentRss>
		</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 from time to [...]]]></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>
		</item>
		<item>
		<title>Microsoft Releases New Version of Live Maps</title>
		<link>http://blog.stchur.com/2008/09/24/microsoft-releases-new-version-of-live-maps/</link>
		<comments>http://blog.stchur.com/2008/09/24/microsoft-releases-new-version-of-live-maps/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 02:40:34 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Gimme]]></category>

		<category><![CDATA[Live Maps]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/09/24/microsoft-releases-new-version-of-live-maps/</guid>
		<description><![CDATA[	Microsoft released a new version of Live Maps today.  This version features multi-way point routing as well as a number of other nice little updates.
	Another cool thing about this release is that it features Gimme quite prominently.  After getting directions, you'll notice the ability to expand/collapse the directions specific to each point along [...]]]></description>
			<content:encoded><![CDATA[	<p>Microsoft released a new version of <a href = "http://maps.live.com" title = "Live Maps">Live Maps</a> today.  This version features multi-way point routing as well as a number of other nice little updates.</p>
	<p>Another cool thing about this release is that it features <a href = "http://codeplex.com/gimme" title = "The Gimme Javascript Library">Gimme</a> quite prominently.  After getting directions, you'll notice the ability to expand/collapse the directions specific to each point along the route.  That nice, smooth animation you see is Gimme doing what Gimme does best!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/09/24/microsoft-releases-new-version-of-live-maps/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Screw you, financially responsible Americans</title>
		<link>http://blog.stchur.com/2008/07/26/screw-you-financially-responsible-americans/</link>
		<comments>http://blog.stchur.com/2008/07/26/screw-you-financially-responsible-americans/#comments</comments>
		<pubDate>Sat, 26 Jul 2008 22:49:44 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[MiniPosts]]></category>

		<category><![CDATA[Opinions]]></category>

		<category><![CDATA[Politics]]></category>

		<category><![CDATA[housing]]></category>

		<category><![CDATA[real estate]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/07/26/screw-you-financially-responsible-americans/</guid>
		<description><![CDATA[Be irresponsible, spend money you don't have, buy things you can't afford, fail to make the payments.  Not to worry -- just cry foul when it is threatened that it will be taken away from you and big government will come in and rescue you, sending the clear message that being financially responsible is, [...]]]></description>
			<content:encoded><![CDATA[<p>Be irresponsible, spend money you don't have, buy things you can't afford, fail to make the payments.  Not to worry -- just cry foul when it is threatened that it will be taken away from you and big government will come in and rescue you, sending the <a href = "http://seattlebubble.com/blog/2008/07/26/us-government-to-responsible-americans-screw-you/" title = "US Government to Responsible Americans: Screw You">clear message</a> that being financially responsible is, not only unnecessary, but actually stupid, since the tax dollars of those who <em>are</em> financially responsible are the dollars that are going to go towards this crappy legislature.</p>

<p>I've never been so irritated!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/07/26/screw-you-financially-responsible-americans/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Wither IE6?</title>
		<link>http://blog.stchur.com/2008/07/22/wither-ie6/</link>
		<comments>http://blog.stchur.com/2008/07/22/wither-ie6/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 13:00:07 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[Beating IE into submission]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[MiniPosts]]></category>

		<category><![CDATA[Opinions]]></category>

		<category><![CDATA[Web-related]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/07/22/wither-ie6/</guid>
		<description><![CDATA[Welcome aboard guys.  Glad you finally decided to start thinking about what I discussed long ago.]]></description>
			<content:encoded><![CDATA[<p>Welcome aboard <a href = "http://ajaxian.com/archives/pondering-support-of-ie6" title = "Pondering Support for IE6">guys</a>.  Glad you <em>finally</em> decided to start thinking about what <a href = "http://blog.stchur.com/2008/01/15/ie5-is-dead-and-ie6-is-on-death-row/" title = "IE5 is dead (and IE6 is on death row)">I discussed</a> long ago.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/07/22/wither-ie6/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Firefox 3 .pageX / .pageY bug</title>
		<link>http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/</link>
		<comments>http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 17:40:49 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[Advanced Javascript]]></category>

		<category><![CDATA[Firefox Related]]></category>

		<category><![CDATA[Mozilla-specific]]></category>

		<category><![CDATA[bug]]></category>

		<category><![CDATA[dispatchEvent]]></category>

		<category><![CDATA[Firefox 3]]></category>

		<category><![CDATA[pageX]]></category>

		<category><![CDATA[pageY]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/</guid>
		<description><![CDATA[	Firefox 3 has a bug.  It's somewhat obscure, and it probably doesn't affect you, but it did affect me.
	It also affected the Microsoft Virtual Earth MapControl, so if you use the VE MapControl for a mashup, your Firefox 3 users are going to be affected by this issue.
	The issue?  It has to do [...]]]></description>
			<content:encoded><![CDATA[	<p>Firefox 3 has a bug.  It's somewhat obscure, and it probably doesn't affect you, but it did affect me.</p>
	<p>It also affected the Microsoft <a href = "http://msdn.microsoft.com/en-us/virtualearth/default.aspx" title = "Microsoft Virtual Earth">Virtual Earth MapControl</a>, so if you use the VE MapControl for a mashup, your Firefox 3 users are going to be affected by this issue.</p>
	<p>The issue?  It has to do with a mouse event's <code>.pageX</code> and <code>.pageY</code> properties.  The values of those properties are supposed to report the "page" position of the mouse cursor, relative to the upper-left corner of the HTML page.  You can think of it as the absolute (x,y) of the mouse cursor.</p>
	<p>The nice thing about <code>.pageX/Y</code> is that serves as an easy way to get the mouse position, <em>regardless</em> of how much (or even if) the browser window is scrolled.</p>
	<p>Contrast <code>.pageX/Y</code> with <code>.clientX/Y</code>:  the latter reports (x,y) coordinates relative to the upper-left corner of the browser window, so these values <em>will</em> be affected by browser scroll position.</p>
	<p>Anyway, at this point, you're probably thinking that I'm going to tell you that Firefox 3 reports the wrong values for <code>.pageX/Y</code>, and that that's the bug.  It's not that simple though (again, I admit this is a somewhat obscure bug).</p>
	<p><em>Most</em> of the time, Firefox 3 reports the right values for <code>.pageX/Y</code>, but there is one case in which it doesn't.</p>
	<h3>Manually Dispatching Events in Javascript</h3>
	<p>A while back, I wrote a 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>.  In it, I explain how to create an event and initialize it with <code>myEvt.initMouseEvents(..)</code> (which takes a <a href = "http://developer.mozilla.org/en/docs/DOM:event.initMouseEvent" title = "Mozilla Developer Center (initMouseEvent)">boat-load</a> of parameters).</p>
	<p>Of all those parameters sent into <code>.initMouseEvents(..)</code>, 4 are of particular interest: <code>.screenX</code>, <code>.screenY</code>, <code>.clientX</code>, and <code>.clientY</code>.</p>
	<p>Notice that <code>.pageX</code> and <code>.pageY</code> are not in the list.  You don't get the ability to pass in <code>.pageX/Y</code> when manually creating/dispatching an event in Javascipt.  Presumably, the values for these properties are computed based on <code>.clientX/Y</code> and the browser's scroll position.</p>
	<p>So for example, if you initialize a MouseEvent with <code>.clientX</code> = 200 and <code>.clientY</code> = 300, and if the browser is scrolled 50 x 75, then your event's <code>.pageX</code> and <code>.pageY</code> values will be 250 and 375 respectively.</p>
	<p>Oops!  I mean, that's what the values <em>should</em> be.</p>
	<h3>The Bug</h3>
	<p>Firefox 2 actually gets it right, but Firefox 3 doesn't.</p>
	<p>When you're manually dispatching a MouseEvent in Firefox 3, the <code>.pageX/Y</code> property values will <em>always</em> be equal to the <code>.clientX/Y</code> values, <em>regardless</em> of browser scroll position.</p>
	<p>As I previously mentioned, this affects the VE MapControl, so it's easy to see the issue in action.  Just use Firefox 3 and point your browser to <a href = "http://maps.live.com" title = "Microsoft Live Search Maps">http://maps.live.com</a>.  Now make your browser window small enough to cause scroll bars to appear.  Scroll the browser window by some amount (doesn't matter how much) and try panning the map.  You should see the map "jump" during the initial pan.  The amount it "jumps" is going to be equal to the amount by which the browser window is scrolled.</p>
	<h3>The Fix</h3>
	<p>Microsoft has a work-around for this issue that is going to be released with the next version of Virtual Earth, but if you're a mashup dev using the VE MapControl, I've got a solution that you can use right now, and it goes like this:</p>
	<div class="dean_ch" style="white-space: nowrap;"><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> mouseEvt;<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> document.<span class="me1">createEvent</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; mouseEvt = document.<span class="me1">createEvent</span><span class="br0">&#40;</span><span class="st0">'MouseEvents'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>mouseEvt &amp;&amp; mouseEvt.__proto__ &amp;&amp; mouseEvt.__proto__.__defineGetter__<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; mouseEvt.__proto__.__defineGetter__<span class="br0">&#40;</span><span class="st0">'pageX'</span>, <span class="kw2">function</span><span class="br0">&#40;</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> <span class="kw1">this</span>.<span class="me1">clientX</span> + window.<span class="me1">pageXOffset</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; mouseEvt.__proto__.__defineGetter__<span class="br0">&#40;</span><span class="st0">'pageY'</span>, <span class="kw2">function</span><span class="br0">&#40;</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> <span class="kw1">this</span>.<span class="me1">clientY</span> + window.<span class="me1">pageYOffset</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
	<p>Just include the preceding code snippet anywhere in your HTML page.  The code is pretty straight-forward and just relies on the fact that Firefox (and others) have the ability to define getters through the use of <code>.__defineGetter__(..)</code>.</p>
	<p>The <code>.pageX/Y</code> properties are read only, but it turns out that the browser will let you redefine these getters, thereby overriding their return logic.  Since the <code>.clientX/Y</code> properties appear to always report the correct value, all we have to do redefine the <code>.pageX/Y</code> getters to use a combination of <code>.clientX/Y</code> + <code>.pageX/YOffset</code>.</p>
	<p>In other words, we've redefined <code>.pageX/Y</code> to always return the position of the event (in our case, the mouse cursor since we're dealing with MouseEvents), relative to the upper-left corner of the browser window + the scrolled position of the browser -- what it should have been all along!</p>
	<p>This code doesn't hurt IE, as it won't execute in that browser, and it doesn't hurt Firefox 2 or other browsers that understand the code either, because the logic we've defined for the getters is going to be essentially the same as what the browser would have done natively anyway.</p>
	<p>I'd like to file a bug to Mozilla on this issue, but I haven't a clue as to how one goes about doing that.  If anyone knows (or wants to do it for me), feel free to speak up!</p>
	<p>Enjoy the fix!</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/feed/</wfw:commentRss>
		</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>
		</item>
		<item>
		<title>Firefox 3</title>
		<link>http://blog.stchur.com/2008/06/19/firefox-3/</link>
		<comments>http://blog.stchur.com/2008/06/19/firefox-3/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 14:45:50 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
		
		<category><![CDATA[Firefox Related]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[MiniPosts]]></category>

		<category><![CDATA[Mozilla-specific]]></category>

		<category><![CDATA[Web-related]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/06/19/firefox-3/</guid>
		<description><![CDATA[Well unless you've been living under a rock, you know that Firefox 3 was released on Tuesday.  This is a big deal for me. When other browser makers release a new version, it's like eh... ok, that's cool (I guess).  But when Mozilla releases a new Firefox, I've got a brand new shiny [...]]]></description>
			<content:encoded><![CDATA[<p>Well unless you've been living under a rock, you know that <a href = "http://www.getfirefox.com" Title = "Firefox">Firefox 3</a> was released on Tuesday.  This is a big deal for me. When other browser makers release a new version, it's like eh... ok, that's cool (I guess).  But when Mozilla releases a new Firefox, I've got a brand new shiny app to get me through my day to day web browsing.</p>

<p>Besides the new theme (on Windows) being a little bland, FF3 does <em>not</em> disappoint!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/06/19/firefox-3/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
