<?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>stchur-BLOG</title>
	<atom:link href="http://blog.stchur.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.stchur.com</link>
	<description>web / programming / javascript / css / html</description>
	<lastBuildDate>Sat, 16 Jan 2010 01:09:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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>0</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[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>
		<slash:comments>2</slash:comments>
		</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>
		<slash:comments>2</slash:comments>
		</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>
		<slash:comments>0</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 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>
		<slash:comments>6</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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>
		<slash:comments>7</slash:comments>
		</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>
		<slash:comments>0</slash:comments>
		</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>
		<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>
	</channel>
</rss>
