<?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 &#187; Gimme</title>
	<atom:link href="http://blog.stchur.com/category/gimme/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.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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>In Honor of Caspian (enhancing Gimme)</title>
		<link>http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/</link>
		<comments>http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/#comments</comments>
		<pubDate>Sat, 17 May 2008 03:47:53 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[Useful Functions]]></category>
		<category><![CDATA[]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[John Resig]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Shaun Inman]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/</guid>
		<description><![CDATA[	The Chronicles of Narnia: Prince Caspian arrived in theaters today, and for those of you who haven't noticed, all of the Gimme codename releases are named after characters from the Chronicles of Narnia, since it is the greatest fantasy series ever written (sorry Lord of the Rings and Harry Potter fans, but I'm afraid that [...]]]></description>
			<content:encoded><![CDATA[	<p><a href = "http://en.wikipedia.org/wiki/Prince_Caspian" title = "Prince Caspian">The Chronicles of Narnia: Prince Caspian</a> arrived in theaters today, and for those of you who haven't noticed, all of the Gimme codename releases are named after characters from the <a href = "http://www.narniaweb.com" title = "Narnia Web">Chronicles of Narnia</a>, since it is the greatest fantasy series ever written (sorry Lord of the Rings and Harry Potter fans, but I'm afraid that yes, Narnia, <em>is</em> better).</p>
	<p>Anyway, since the current beta release of Gimme is "Caspian" I figured I'd do a post today in honor of Gimme and the movie (ok, it helps that I also have something worth writing about too).</p>
	<p>So anyway, on to what this post is really about: enhancing Gimme.</p>
	<p>Not too long ago, <a href = "http://www.shauninman.com" title = "Shaun Inman">Shaun Inman</a> wrote about his proposal for <a href = "http://shauninman.com/archive/2008/05/05/css_qualified_selectors" title = "CSS Qualified Selectors">CSS Qualified Selectors</a>.</p>
	<p>It's a good idea; I've actually had the same idea and thought briefly about making it part of Gimme's core CSS selector engine.  Only, in my model, I have the left-hand-side and the right-hand-side of the <code><</code> symbol switched.  It feels more natural to me that way, because in most CSS selector rules, you can simply look to the far right of the selector rule and know what type of "thing" you're going to be selecting.</p>
	<p>Thus, I feel that this:</p>
	<div class="dean_ch" style="white-space: nowrap;">img &lt; a&nbsp; &nbsp; &nbsp;<span class="coMULTI">/* select all &lt;a&gt; elements that contain an &lt;img&gt; element */</span></div>
	<p>feels more natural than this:</p>
	<div class="dean_ch" style="white-space: nowrap;">a &lt; img&nbsp; &nbsp; &nbsp;<span class="coMULTI">/* same logic as above -- Shaun's approach */</span></div>
	<p>But this is just details; the idea is the same either way.</p>
	<p>So anyway, after Shaun published his idea, <a href = "http://www.ejohn.com" title = "John Resig">John Resig</a> chimed in and mentioned that <a href = "http://www.jquery.com" title = "jQuery">jQuery</a> supports this already via <a href = "http://ejohn.org/blog/qualified-selectors-in-jquery/" title = "jQuery :has(..)">pseudo :has(..)</a>.</p>
	<p>Well that's pretty cool, but since <a href = "http://codeplex.com/gimme" title = "The Gimme Javascript Library">Gimme</a> is my library, naturally, I feel compelled to make sure it stacks up against the competition, so I thought to myself: "self, can Gimme do this?" to which a mental reply came back "No, remember? You decided no to implement it."</p>
	<p>And I would have just left it at that, because after all, I decided not to implement it for a reason (and I figured that's where I <em>would</em> leave it).</p>
	<p>But then, today, my officemate surprised me by asking "Hey, I have a question about Gimme.  I'm working with a page where I need to select a &lt;table&gt; element that has an &lt;h1&gt;.  Can Gimme do this?"</p>
	<p>Well crap!  What are the odds that this would come up again so quickly?</p>
	<p>Not being one to disappoint, I said "You know what? I decided not to implement it, but I did put significant effort into making Gimme's selector engine extensible.  I bet we can write an extension really easily."</p>
	<p>So a few minutes later, we came up with this little gem:</p>
	<div class="dean_ch" style="white-space: nowrap;">Gimme.<span class="me1">Selectors</span>.<span class="me1">addPseudo</span><span class="br0">&#40;</span><span class="st0">'has'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>_elem, _pseudo<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> children = Gimme.<span class="me1">query</span><span class="br0">&#40;</span>_pseudo.<span class="me1">param</span>, _elem<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">return</span> children.<span class="me1">length</span> &gt; <span class="nu0">0</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
	<p>Which means you can now use Gimme to do something like:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'p:has(img.funny)'</span><span class="br0">&#41;</span>;&nbsp; <span class="co1">// select all &lt;p&gt;s that contain &lt;img&gt;s with class &quot;funny&quot;</span></div>
	<p>Unlike what John did, I didn't bother to map this back to the <code><</code> symbol.  I thought about it, and you could do it easily enough, but the more I think about it, the more I like how <code>:has(..)</code> reads.</p>
	<p>It's not likely that I'll make something like this part of the core Gimme library unless it start popping up everywhere.  It comes up occasionally, but not enough to warrant making it part of the core (at least, not enough in my personal experiences so far anyway).</p>
	<p>So there ya go!  Think of this as edition 1 of "Gimme can do that too" with (hopefully) many more editions to come.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fresh Nuggets of Gimme Awesomeness</title>
		<link>http://blog.stchur.com/2008/04/01/fresh-nuggets-of-gimme-awesomeness/</link>
		<comments>http://blog.stchur.com/2008/04/01/fresh-nuggets-of-gimme-awesomeness/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 20:58:45 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Gimme]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/04/01/fresh-nuggets-of-gimme-awesomeness/</guid>
		<description><![CDATA[	Some really cool stuff happening with Gimme lately, especially with regards to its animation capabilities.
	I whipped together something that started off (in my head anyway) as a sort of copy of CoverFlow on Mac OS.  However, before I was finished, it had morphed into a general purpose animation-along-an-arbitrary-path-type-routine.
	This code isn't yet checked into the [...]]]></description>
			<content:encoded><![CDATA[	<p>Some really cool stuff happening with Gimme lately, especially with regards to its animation capabilities.</p>
	<p>I whipped together something that started off (in my head anyway) as a sort of copy of CoverFlow on Mac OS.  However, before I was finished, it had morphed into a general purpose animation-along-an-arbitrary-path-type-routine.</p>
	<p>This code isn't yet checked into the repository, but for anyone who is interested in taking a look, here are two different demo pages to see the "bleeding edge" of what is going on with Gimme:</p>
	<ul>
	<li><a href = "http://gimme.stchur.com/gimmeflow4.html" title = "Animation along an arbitrary path using Gimme">Animation along an arbitrary path using Gimme</a></li>
	<li><a href = "http://gimme.stchur.com/animationdemo.html" title = "Gimme Animation Demo Page">Gimme Animation Demo Page</a></li>
	</ul>
	<p>There are a few things worth nothing.  The first link is a really quick-n-dirty prototype, so there are bound to be bugs.  The page takes a few seconds to load as it is pulling remote photos from my Spaces photo album.  You'll have to wait until everything is loaded and in place to try out the demo.  Just click on any image and you'll get the idea.  You can also change the shape of the curve that the images follow by clicking on the "S Shape" button.</p>
	<p>The second link is a general animation demo page.  By providing a set of Bezier control points (comma separated coordinates / spaces separated points), you can instruct the script to plot any curve and then have the red block follow that curve.  You can also chose the AccelerationLine you want to use with the animation (note that Linear is a bad name, and should really be None -- I will fix this one day).</p>
	<p>You can even use the text area on the right side of the page to execute arbitrary custom code.  I've provided a sample that animates the red block counter-clockwise around an ellipse 2 and 1/2 times.</p>
	<p>As you can see, it doesn't take much code at all to achieve some fairly sophisticated animation with Gimme.</p>
	<p>In a future blog entry, I hope to polish up this code and provide a deeper explanation of the samples (as well as get this code checked into the repository).</p>
	<p>Comments welcome</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/04/01/fresh-nuggets-of-gimme-awesomeness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE quirk with onload event for &lt;img&gt; elements</title>
		<link>http://blog.stchur.com/2008/02/26/ie-quirk-with-onload-event-for-img-elements/</link>
		<comments>http://blog.stchur.com/2008/02/26/ie-quirk-with-onload-event-for-img-elements/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 17:50:26 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[Javascript basics]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/02/26/ie-quirk-with-onload-event-for-img-elements/</guid>
		<description><![CDATA[	I rediscovered something yesterday that I know I've come across in the past.  Still, it was driving me crazy until I finally did a little web searching and found what I needed.  It was one of those "oh right! I've encountered that before" moments.
	I was writing a script that dealt with images and [...]]]></description>
			<content:encoded><![CDATA[	<p>I rediscovered something yesterday that I know I've come across in the past.  Still, it was driving me crazy until I finally did a little web searching and found what I needed.  It was one of those "oh right! I've encountered that before" moments.</p>
	<p>I was writing a script that dealt with images and I needed to know when an image had finished loading.  Simple enough.  Using Gimme (or your favorite addEvent(..)) equalizer the code looks something like:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> myImage = document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'img'</span><span class="br0">&#41;</span>;<br />
myImage.<span class="me1">src</span> = <span class="st0">'http://source.to.image/image.jpg'</span>;<br />
g<span class="br0">&#40;</span>myImage<span class="br0">&#41;</span>.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'load'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'Image is done loading!'</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
	<p>It turns out that my load handler wasn't always firing in IE (in Firefox it worked consistently). The solution though is super simple.</p>
	<p>You just need to make sure that you wire up the load handler <em>before</em> setting the image element's <code>.src</code> property.  Why?  Because if the image is being loaded from cache, IE (and Opera too) will load the image instantly.  In fact, it will have finished loading the image before your load event handler is even wired up, which means, it won't fire!</p>
	<p>Just change the code to something like this:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> myImage = document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">'img'</span><span class="br0">&#41;</span>;<br />
myImage.<span class="me1">addEvent</span><span class="br0">&#40;</span><span class="st0">'load'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'Image is done loading!'</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
myImage.<span class="me1">src</span> = <span class="st0">'http://source.to.image/image.jpg'</span>;</div>
	<p>And there you have it.</p>
	<p>Nothing earth-shattering and probably common knowledge for a lot of scripters, but a little refresher never hurts.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/02/26/ie-quirk-with-onload-event-for-img-elements/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>setCapture with Gimme</title>
		<link>http://blog.stchur.com/2007/11/21/setcapture-with-gimme/</link>
		<comments>http://blog.stchur.com/2007/11/21/setcapture-with-gimme/#comments</comments>
		<pubDate>Thu, 22 Nov 2007 04:44:01 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[Useful Functions]]></category>

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

		<guid isPermaLink="false">http://stchur.com/blog2/2007/07/22/managing-animations-with-gimme-a-fade-demo/</guid>
		<description><![CDATA[	Animation can be a tricky business in Javascript, particularly if the animation is invoked by some user action (such as moving the mouse over an element).  Users cannot be trusted to behave in a calm, rational manner.  For instance, instead of clicking the mouse button just once, they'll click it 25 times.  [...]]]></description>
			<content:encoded><![CDATA[	<p>Animation can be a tricky business in Javascript, particularly if the animation is invoked by some user action (such as moving the mouse over an element).  Users cannot be trusted to behave in a calm, rational manner.  For instance, instead of clicking the mouse button just once, they'll click it 25 times.  Instead of pressing a key just once, they'll mash the key a dozen times in a row.  Instead of smoothly mousing from one element to the next, they'll frantically move the mouse around as though it's being chased by a hungry cat.</p>
	<p>If your animation is invoked by a user action like those described above, then there is good chance that the animation may come off looking sort of silly (at best) or even causing seizures (at worst).  I've written animations before, that didn't account for unpredictable user behavior, and the result was a chaotic mess of flickering DOM elements.  An animation to be sure, but not the one I was aiming for.</p>
	<p>No, users should not be trusted, and we should never fall into the trap of letting ourselves believe they can.  Of course, this makes our job as UI designers more difficult, but that's no reason to whimp out!</p>
	<h3>Gimme to the rescue</h3>
	<p>Gimme has an extension called Gimme Effects which, when combined with the Gimme Animation Module offers a sophisticated set of tools for creating and managing Javascript-based animations.  Besides several, useful, stock effects, Gimme also offers developers the ability to create custom animations quickly and easily (but that's another blog entry).</p>
	<h3>Focus on the fade!</h3>
	<p>One of the stock effects available in Gimme Effects is the fade (in, out, or to/from arbitrary values).  It's super easy to invoke a fade too.  Take the following:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'#nav &gt; a'</span><span class="br0">&#41;</span>.<span class="me1">fadeOut</span><span class="br0">&#40;</span><span class="st0">'quickly'</span><span class="br0">&#41;</span>;</div>
	<p>This snippet quickly fades out all <code>&lt;a&gt;</code> elements that are direct children of the <code>#nav</code> element.  How quick is 'quickly'?  750 milliseconds to be precise, but you're not limited.  Pass in a keyword like 'quickly' or 'slowly', pass in a numeric value in milliseconds, or even pass in nothing at all (default is 'quickly'); Gimme will handle it all just fine.</p>
	<h3>Specifying more parameters</h3>
	<p>All animation effects in Gimme take at least 3 parameters (some take more).  These 3 parameters, which are all always optional are:</p>
	<ol>
	<li>duration: positive integer value indicating the duration of the animation in milliseconds.</li>
	<li>guid: a string value that uniquely identifies this animation (you'll see later, why this can be useful).  Note that this value can be null.</li>
	<li>callback: a function to be executed when the animation completes.</li>
	</ol>
	<p>Suppose I wanted to alert a message that the fade operation was done.  I could do the following:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'#nav &gt; a'</span><span class="br0">&#41;</span>.<span class="me1">fadeOut</span><span class="br0">&#40;</span><span class="nu0">2000</span>, <span class="kw2">null</span>, <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'all done!'</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
	<p>There is a problem here though.  Remember back at the beginning of this post, I said that users could not be trusted to behave in calm and predictable ways?  Well, suppose the above code snippet is executed whenever the users clicks on a button that says "Fade the navigation."  What happens if the user clicks on that button 15 times in a rows?  The animation takes 2 full seconds to complete, so if the user invokes it 15 times, that's 15 <em>different</em> animation requests, all on the same DOM elements.</p>
	<p>The result will be a night-club-strobe-light-flickering effect that might give your users a seizure (or a head-ache at the very least).</p>
	<h3>Unique Animations with Gimme</h3>
	<p>With Gimme, it's pretty easy to avoid this kind of flickering.  You simply specify a GUID when invoking the animation, and this instructs  Gimme to make sure that an animation with the specified GUID is not already running.  If it is, the request to start the animation will be ignored until the animation is no longer running.  Take the following example:</p>
	<div class="dean_ch" style="white-space: nowrap;">
g<span class="br0">&#40;</span><span class="st0">'body'</span><span class="br0">&#41;</span>.<span class="me1">fadeOut</span><span class="br0">&#40;</span><span class="nu0">1000</span><span class="br0">&#41;</span>;<br />
g<span class="br0">&#40;</span><span class="st0">'body'</span><span class="br0">&#41;</span>.<span class="me1">fadeOut</span><span class="br0">&#40;</span><span class="nu0">500</span><span class="br0">&#41;</span>;</div>
	<p>The code above doesn't specify any GUID; the animations are not uniquely identified and therefore Gimme will happily attempt to execute both of them, even though they operate on the same element (the <code>&lt;body&gt;</code> element) and will cause flickering.</p>
	<p>One solution, is to give both animations the same GUID, as in:</p>
	<div class="dean_ch" style="white-space: nowrap;">
g<span class="br0">&#40;</span><span class="st0">'body'</span><span class="br0">&#41;</span>.<span class="me1">fadeOut</span><span class="br0">&#40;</span><span class="nu0">1000</span>, <span class="st0">'FADE'</span><span class="br0">&#41;</span>;<br />
g<span class="br0">&#40;</span><span class="st0">'body'</span><span class="br0">&#41;</span>.<span class="me1">fadeOut</span><span class="br0">&#40;</span><span class="nu0">500</span>, <span class="st0">'FADE'</span><span class="br0">&#41;</span>;</div>
	<p>When Gimme encounters the second <code>.fadeOut(..)</code> call, it will ignore it since an animation with the GUID "FADE" is already running.  Once the animation finishes though, it will once again be eligible for invocation.</p>
	<p> Of course, you wouldn't ever write code like what I've written above -- that was just to illustrate a point.  But think again about the possibility of a user repeatedly clicking a button to invoke some animation, and you'll see how the GUID can help.</p>
	<h3>Stopping an animation</h3>
	<p>The fact that Gimme can ignore subsequent requests to start an animation that already started is nice, but it begs the question: "what if I don't <em>want</em> to ignore subsequent requests?  What if I want subsequent requests to cause the currently running animation to abort in favor of the new request?"</p>
	<p>Gimme can do this too; it's just not the default behavior, so it take a couple extra lines of code on your part.  Nothing major though, and it's still super easy:</p>
	<div class="dean_ch" style="white-space: nowrap;">Gimme.<span class="me1">Animation</span>.<span class="me1">end</span><span class="br0">&#40;</span><span class="st0">'GUID'</span><span class="br0">&#41;</span>;</div>
	<p>This instructs Gimme to abruptly stop the animation uniquely identified by the GUID, "GUID" (not a very good name for a GUID by the way), provided it exists and is running.  Need to stop more than one animation at a time?  No problem; just pass in a comma delimited list of GUIDS as in:</p>
	<div class="dean_ch" style="white-space: nowrap;">Gimme.<span class="me1">Animation</span>.<span class="me1">end</span><span class="br0">&#40;</span><span class="st0">'FADEIN'</span>, <span class="st0">'FADEOUT'</span><span class="br0">&#41;</span>;</div>
	<p>Gimme will stop any animations that are uniquely identified by either "FADEIN" or "FADEOUT."</p>
	<p>It's worth noting that all animations have a GUID, even if you don't specify one.  For animations where you fail to specify a GUID, one is auto generated for you.  It's a good idea to specify your own though, as this allows you to manually stop the animation at will.</p>
	<h3>.fadeTo(startOpacity, endOpacity, duration, guid, callback)</h3>
	<p>Besides <code>.fadeIn(..)</code> and <code>.fadeOut(..)</code> (which are somewhat restrictive since they're "all or nothing"), Gimme also offer <code>.fadeTo(..)</code>.  This function works like its in/out couterparts, but it allows you to specify the starting and ending opacity for the fade.  As an added bonus, you can pass in <code>null</code> for either value. A <code>null</code> value for startOpacity indicates that you want the starting opacity to be the object's current opacity, while a <code>null</code> value for endOpacity means zero.</p>
	<p>For example:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'#btn1'</span><span class="br0">&#41;</span>.<span class="me1">fadeTo</span><span class="br0">&#40;</span><span class="kw2">null</span>, .<span class="nu0">5</span>, <span class="st0">'slowly'</span>, <span class="st0">'PARTIAL_FADE'</span><span class="br0">&#41;</span>;</div>
	<p>This code snippet will fade the element, <code>#btn1</code> starting at its current opacity (which is most likely 1, but doesn't have to be) and decreasing to .5 (or 50%) opacity.</p>
	<h3>A working Gimme demo involving fade</h3>
	<p>To help tie everything I've been writing about together, I've created a snazzy little fade demo for all to enjoy.  In it there is a <code>#navigation</code> <code>&lt;div&gt;</code> with a few <code>&lt;button&gt;</code> elements inside of it.  Whenever the user mouses over a button, all <em>other</em> buttons should partially fade out.  When the user mouses out of the <code>#navigation</code> <code>&lt;div&gt;</code> completely, all buttons should return to their full opacity.</p>
	<p>With Gimme, this turned out to be pretty darn easy.  It's only about 12 lines of code in all:</p>
	<p>View the <a href = "/blogcode/gimme-fade-demo/" target = "_new">Gimme Fade Demo</a> (source is visible on the page)</p>
	<h3>New to Gimme?</h3>
	<p>If you're new to Gimme, you should know that it's free and open source!  Check out these links for more information:</p>
	<ul>
	<li><a href = "http://gimme.stchur.com">The Gimme Home Page</a></li>
	<li><a href = "http://codeplex.com/gimme/release/projectreleases.aspx">Official Gimme Releases on CodePlex</a></li>
	<li><a href = "http://codeplex.com/gimme/Wiki/View.aspx?title=Complete%20API%20Reference">The Gimme API Reference</a></li>
	</ul>
	<p>Comment welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/07/22/managing-animations-with-gimme-a-fade-demo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
