<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>thyncology</title>
	
	<link>http://www.thynctank.com</link>
	<description>The Science of Thynctank.</description>
	<lastBuildDate>Thu, 05 Aug 2010 07:57:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/thyncology" /><feedburner:info uri="thyncology" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Productivity Proclivity</title>
		<link>http://feedproxy.google.com/~r/thyncology/~3/WEYjA5VI7No/</link>
		<comments>http://www.thynctank.com/software/2010/08/productivity-proclivity/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 04:11:23 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[commands]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[mac_apps]]></category>
		<category><![CDATA[os_x]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[quicksilver]]></category>
		<category><![CDATA[snippets]]></category>
		<category><![CDATA[software review]]></category>
		<category><![CDATA[textmate]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/?p=202</guid>
		<description><![CDATA[So I&#8217;ve begun reading O&#8217;Reilly&#8217;s &#8220;The Productive Programmer&#8221; and am trying to put ideas and apps mentioned in its text. I&#8217;m learning Unix commands here and there I was never familiar with, like pushd and popd. I&#8217;m also learning about quite a few apps I never would have used otherwise. While I myself am focusing [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve begun reading O&#8217;Reilly&#8217;s <a href="http://www.amazon.com/Productive-Programmer-Theory-Practice-OReilly/dp/0596519788/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1280976618&amp;sr=1-1">&#8220;The Productive Programmer&#8221;</a> and am trying to put ideas and apps mentioned in its text. I&#8217;m learning Unix commands here and there I was never familiar with, like <a href="http://en.wikipedia.org/wiki/Pushd_and_popd">pushd and popd</a>. I&#8217;m also learning about quite a few apps I never would have used otherwise. While I myself am focusing on Unix commands and Mac apps, the book features coverage for Windows as well.</p>

<p>As far as Mac apps go&#8230;</p>

<p>I&#8217;ve been doubling my efforts to use <a href="http://blacktree.com/?quicksilver">QuickSilver</a>, especially in terms of avoiding guis like iTunes and Finder. The book talks about the importance of not disrupting flow and train of thought. While I&#8217;ve read about how damaging this can be in <a href="http://www.amazon.com/Pragmatic-Thinking-Learning-Refactor-Programmers/dp/1934356050">Pragmatic Thinking &amp; Learning</a>, I never stopped to examine just how much they affect me in particular. I seem to have attention deficit like a madman. I start and stop tasks several times a minute at my worst. I&#8217;ve flirted with using apps like <a href="http://freeverse.com/mac/product/?id=7013">Think</a> and WriteRoom (or the free <a href="http://www.codealchemists.com/jdarkroom/">JDarkRoom</a>) to try avoiding distraction, neither have stuck very well. It seems I&#8217;m more inclined to manage my own time, but I still need to figure the best way to do so.</p>

<p>What <em>has</em> stuck as far as productivity already is Spaces, OS X&#8217;s built-in virtual desktop; Exposé, the likewise built-in window management tool; the aforementioned QuickSilver; <a href="http://jumpcut.sourceforge.net/">JumpCut</a>; <a href="http://github.com/rupa/j2">j2</a> and assorted custom aliases in-shell. I&#8217;m a biggish user of TextMate&#8217;s macros, snippets and columnar/multiline editing, as well as the Git/SVN bundles.</p>

<p>Now I&#8217;m adding <a href="http://www.smileonmymac.com/TextExpander/">Text Expander</a> to my list of must-have apps. I&#8217;d played with Typinator (a similar app) before, but it didn&#8217;t suit me. Text Expander absolutely does. Being able to customize not only your snippets but how and when they&#8217;ll trigger is great. I find myself adding new words while talking to friends on AIM. I&#8217;m up to almost 300 words now, hopefully I&#8217;ll plateau around 400 or so. Haven&#8217;t even used it for development work yet but it&#8217;s cutting back on time wasted typing in chats! Also check <a href="http://www.lachoseinteractive.net/en/products/doodim/">Doodim</a>, an easier version of Think.app.</p>

<p>Can&#8217;t wait to see what apps, commands and ideas I discover going forward, reading the book and on my own!</p>

<p>Another app I&#8217;m interested in but haven&#8217;t used much yet is <a href="http://www.cocoatech.com/">Path Finder</a>, a Finder alternative with built-in terminal and lots more.</p>

<p>Anyone with ideas, app reviews or advice, please do contribute!</p>
<img src="http://feeds.feedburner.com/~r/thyncology/~4/WEYjA5VI7No" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/software/2010/08/productivity-proclivity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.thynctank.com/software/2010/08/productivity-proclivity/</feedburner:origLink></item>
		<item>
		<title>Mojo Madness</title>
		<link>http://feedproxy.google.com/~r/thyncology/~3/Supf7T14PAg/</link>
		<comments>http://www.thynctank.com/javascript/2010/08/mojo-madness/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 03:40:42 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ares]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[mojo]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/?p=187</guid>
		<description><![CDATA[The last 10 months or so has been a blur of JavaScript code and forum posts as I&#8217;ve tinkered on the job and off with Palm&#8217;s webOS, as well as their amazing in-browser IDE, Ares. A post or two is sure to follow, here or elsewhere, regarding the Ares experience itself, but I wanted to [...]]]></description>
			<content:encoded><![CDATA[<p>The last 10 months or so has been a blur of JavaScript code and forum posts as I&#8217;ve tinkered on the job and off with Palm&#8217;s webOS, as well as their amazing in-browser IDE, Ares. A post or two is sure to follow, here or elsewhere, regarding the Ares experience itself, but I wanted to comment a bit on Palm&#8217;s Mojo app framework and the Palm dev and support staff who work the forums, run their Twitter account, fix and improve their library and their toolkit, and generally kick ass.</p>

<p>While nothing is perfect, Mojo has a lot of things going for it: consistency of API let&#8217;s users quickly ramp up to speed any time a new widget is added or simply learn more of the large existing set; a deep, thorough set of events for every widget allows you to hook behaviors on widgets at any point in their lifecycles; a growing list of services on the device means you have access to almost all the functionality you see Palm&#8217;s own apps exhibiting; and Prototype is quite powerful in its own right.</p>

<p>That last point is as good a place as any to dive in. Prototype is, like MooTools or Base, essentially a class system and set of utility functions. While libraries like jQuery focus solely on DOM, Prototype and its kin exist to facilitate extension of existing classes and the creation of new ones. It&#8217;s this presentation of the classical inheritance pattern that allows Prototype to shine. Prototype and similar libraries allow you to inherit from existing classes much more easily than with raw JavaScript.</p>

<p>Palm&#8217;s Mojo framework takes distinct advantage of this functionality by building a vast library of classes you can make use of: from the most important widget, list, to buttons, spinners and WebViews, Mojo has a lot of UI elements available for developers to take advantage of when building applications. In addition to the set of widgets available, Mojo presents most of its additional functionality through a unique twist on the MVC paradigm.</p>

<p>The view, of course, is represented in the DOM. Controllers manipulate the DOM as well as manage all the scenes and data management assistance for the closest thing to Ruby on rails is controllers. Assistants have various lifecycle phases such as setup activate, deactivate. You can hook into these phases and fire off whatever functionality you need. For instance, making a request of the GPS service. Once this on-device service has responded, you can make additional requests. For instance hitting a web service and passing in the GPS data as part of the parameters. In Mojo models are represented by the transient in memory objects connected to widgets. A model might contain, for instance, an array of elements which is used to populate the DOM in terms of the list widget. By updating the status of these structures in memory and then calling the modelChanged method widgets will automatically rearrange the DOM as needed.</p>

<p>Ares is an in-browser IDE (think Eclipse or Visual Studio in the browser!) that let&#8217;s you drag and drop to design scene layouts, hookup widgets, and assign initial model properties and attributes for these widgets. It also contains a full- fledged debugger (hooking into the emulator via Java applet) with breakpoints and interactive console a la Firebug. These tools are amazing, and sped up the development of Taxi Magic for webOS significantly. There&#8217;s even a standalone version of the debugger, which let&#8217;s you debug non-Ares projects!</p>

<p>This kind of advanced functionality is what Mojo is all about. I&#8217;ll be blogging about Palm, Mojo, the future of webOS (thank you, HP!), and my own experience with Mojo and Ares and related topics more soon.</p>
<img src="http://feeds.feedburner.com/~r/thyncology/~4/Supf7T14PAg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/javascript/2010/08/mojo-madness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.thynctank.com/javascript/2010/08/mojo-madness/</feedburner:origLink></item>
		<item>
		<title>All That Jazz</title>
		<link>http://feedproxy.google.com/~r/thyncology/~3/UxhJ1__a4g0/</link>
		<comments>http://www.thynctank.com/javascript/2009/03/all-that-jazz/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 21:41:29 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jazzrecord]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/?p=169</guid>
		<description><![CDATA[I&#8217;d been toying with the idea of expanding JazzRecord into a full MVC stack for building Javascript apps, and I finally spent enough time thinking and obsessing about it to get some work done. I&#8217;m calling it JazzFusion. It&#8217;s not well-organized yet, but the ideas are there, and it&#8217;s going to be very modular. You&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d been toying with the idea of expanding <a href="http://www.jazzrecord.org">JazzRecord</a> into a full <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> stack for building Javascript apps, and I finally spent enough time thinking and obsessing about it to get some work done.</p>

<p>I&#8217;m calling it <strong>JazzFusion</strong>.</p>

<p>It&#8217;s <em>not</em> well-organized yet, but the ideas are there, and it&#8217;s going to be <strong>very modular</strong>. You&#8217;ll be able to use JazzRecord <em>or any other data component</em> for handling the database, and <strong>view templating will also be easily extensible</strong>. The goal for views is to allow simple string-replacement templating with a few macros out of the gate (for calling helper methods, etc), as well as supporting Markdown through <a href="http://attacklab.net/showdown/">Showdown</a>, which I discovered thanks to <a href="http://funkatron.com">Ed Finkler</a>, author of Spaz.</p>

<p>The controller methodology is very much inspired by Rails (like JazzRecord&#8217;s models), so anyone coming from a Rails background will feel right at home. It supports lazy loading of views and eager loading of controllers out of the gate, with minimal configuration hassle. Control routing will be handled by another modular piece, and documentation will be available on how to easily override the router and view renderer, and detailed docs on writing DRY controllers with features like <strong>before/after filters</strong> and the ability to <strong>render/redirect</strong> from one controller/action to other controllers and actions.</p>

<p>I&#8217;m playing with the idea now of building a Ruby-based set of <strong>generator tools</strong> for JazzFusion modeled after Rails&#8217; script/generator tools.</p>

<p>More details to follow, and as soon as the library is in somewhat of a ready state the website/Google Group/Twitter/Github for it will be made available.</p>
<img src="http://feeds.feedburner.com/~r/thyncology/~4/UxhJ1__a4g0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/javascript/2009/03/all-that-jazz/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.thynctank.com/javascript/2009/03/all-that-jazz/</feedburner:origLink></item>
		<item>
		<title>Gracefully Degrading Widgets, Part 2: Navbars &amp; jQuery Plugins</title>
		<link>http://feedproxy.google.com/~r/thyncology/~3/9TwZORNebfE/</link>
		<comments>http://www.thynctank.com/javascript/2009/03/gracefully-degrading-widgets-part-2-navbars-jquery-plugins/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 10:42:14 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[graceful degradation]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[progressive enhancement]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[widgets]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/?p=145</guid>
		<description><![CDATA[I recently met up with a friend and former coworker to help him ramp up his jQuery skills quickly. In the process I got to play with a few things I hadn&#8217;t bothered to pick up previously myself! First of these was Google&#8217;s Ajax Libraries API. While worthless for when you need to be offline [...]]]></description>
			<content:encoded><![CDATA[<p>I recently met up with a friend and former coworker to help him ramp up his jQuery skills quickly. In the process I got to play with a few things I hadn&#8217;t bothered to pick up previously myself!</p>

<p>First of these was <a href="http://code.google.com/apis/ajaxlibs/">Google&#8217;s Ajax Libraries API</a>. While worthless for when you need to be offline (as I ended up being, since the Borders where we met has no free wifi, and <strong>I am cheap/skint</strong>), it&#8217;s nice and easy to include scripts on your pages without needing to maintain the files yourself. Luckily I thought to download local copies and installed Google Docs offline shortly before leaving to meet with the dude.</p>

<p>The second interesting thing I picked up, I actually picked up <em>after</em> the meeting, as I both wanted to learn it and wanted to share with my friend. That something is <em>How to Author a jQuery Plugin</em>, which is what we&#8217;re going to look at today. We&#8217;ll be building a flexible drop-down navigation menu which will work <em>with or without</em> JavaScript thanks to CSS.</p>

<p>Here&#8217;s the working example: <a href="http://www.thynctank.com/nav.html">MultiNav</a></p>

<p><a href="http://www.thynctank.com/javascript/2008/02/gracefully-degrading-widgets-part-1-tabs/">Previously</a>, I discussed some of the fundamental ideas behind <strong>Gracefully Degrading Widgets</strong>, but let&#8217;s quickly delineate them again here:</p>

<ul>
<li>Focus on content above interactivity &#8211; if that means sacrificing the latter for the former, so be it</li>
<li>Present most important content first &#8211; sometimes it is necessary to hide some content to maintain page layout, the most important still shows</li>
<li>Write minimalist markup &#8211; this leads to fewer chances of screwing up and makes it easier on any consumers of your code</li>
<li>Write stylesheets to hide interactive content by default, and override in your JavaScript</li>
</ul>

<p>We&#8217;ll also be focusing on <strong>reusability</strong> and <strong>flexibility</strong>, and we&#8217;ll discover that part of this is covered by virtue of the fact we&#8217;re creating our widget as a jQuery plugin. jQuery plugins are automatically applicable to any selector style available in jQuery, and so our widget will immediately be available to instantiate among common classes of a page, or to elements with individually unique IDs. You can even apply multiple instances on the page at simultaneously. In addition to these flexible instantiation capabilities, we&#8217;ll be building the widget to take a number of options to use different effects, use different classes if the default class names are not appropriate or would conflict with existing names on the page, and so on.</p>

<p>On with the show already! First off let&#8217;s create some simple markup for our drop down menu and style it w/ CSS:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;nav&quot;</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Top Level<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Submenus<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Are Much<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Less Prominent<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Menus Are<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Most Noticeable<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>But Still<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Quite Useful<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></pre></div></div>


<p>Nice and simple!</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">  <span style="color: #00AA00;">*</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50px</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#ccccee</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50px</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">line-height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">2em</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">relative</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li ul <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50px</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li a<span style="color: #3333ff;">:hover </span><span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">underline</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li<span style="color: #3333ff;">:hover </span>ul <span style="color: #00AA00;">&#123;</span><span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li ul li <span style="color: #00AA00;">&#123;</span><span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">130px</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span></pre></div></div>


<p><em>Still</em> simple!</p>

<p>Even with this alone, the example code will show simple hover-over submenus via CSS, in browsers that support it (all but IE6, I believe). This is where degradation comes into play. We want things to fail gracefully, so each of those top-level menus should be a link in and of itself, rather than slamming all the links into the submenus. This is a good failover.</p>

<p>So now that we&#8217;ve got simple menus, let&#8217;s add some action!</p>

<p>To animate a single submenu&#8217;s intro into the page, we might use code similar to the following:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.nav:first &gt; ul &gt; li:first &gt; ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Which uses an advanced CSS3 selector to grab the very first submenu (a <em>ul</em> element) of the first top-level menu item of the first nav. <code>fadeIn()</code> is a call to a nice pre-defined function of any element(s) returned by jQuery.</p>

<p>That&#8217;s all well and good, but what we really need to do is setup a hover effect to fade this menu in and out given the user&#8217;s interaction with it.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.nav:first &gt; li:first&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>This sets up two anonymous functions to be triggered on <em>mouseOver</em> and on <em>mouseOut</em>. jQuery takes care of all of this. What&#8217;s important is understanding the selectors and the event assignment. We won&#8217;t go into detail about the selectors here, but definitely read the <a href="http://docs.jquery.com/Selectors">documentation</a> and play with it. The <em>hover</em> function takes two parameters, each a function. The first will be run on mouseOver, and the second will be run on mouseOut.</p>

<p>So that&#8217;s a start. Our submenu is fading in and out. But what if you accidentally mouse off the submenu? The damned thing fades away instantly! To get around this limitation, we&#8217;ll use a handy built-in feature of JavaScript, <code>setTimeout</code>. This function takes as its parameters a function literal to be called after a specified number of milliseconds, followed by a timeout value in milliseconds. On mouseOver, we&#8217;ll set a class on the element, let&#8217;s call it &#8220;over&#8221;. On mouseOut, we&#8217;ll remove the class, and call <code>setTimeout</code>. After a specified amount of time, let&#8217;s say 500ms, we&#8217;ll check whether the class &#8220;over&#8221; is present on the top-level nav, and if it isn&#8217;t, we&#8217;ll fade it out. If it is (indicating the nav item has been hovered over again), we do nothing.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.nav:first &gt; li:first&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> li <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>li.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
          li.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>This new code sets it up exactly as we&#8217;d like it for the first submenu content alone.</p>

<p>What we want to do is make this reusable, as much as possible, and also make it versatile. That&#8217;s where jQuery&#8217;s plugin system comes in.</p>

<p>jQuery plugins are like any other widget initializer code, only they automatically get to take advantage of jQuery&#8217;s fancy schmancy selector system. They should also be written using the function name <em>jQuery</em> rather than <em>$</em>, because jQuery optionally allows itself to be alternately aliased so that it can sit along side other libraries, which might also define a global function <em>$</em>. Both <a href="http://www.prototypejs.org">Prototype</a> and <a href="http://www.mootools.net/">MooTools</a> do this, and still jQuery can run in combination with these libraries. If you were to use the $ function, you could likely be unintentionally calling the Prototype or MooTools selector function rather than jQuery&#8217;s.</p>

<p>Instructions on authoring jQuery plugins can be found <a href="http://docs.jquery.com/Plugins/Authoring">on jQuery&#8217;s Web site</a>. It all boils down to:</p>

<ol>
<li>Respecting the &#8220;jQuery&#8221; function name over &#8220;$&#8221;</li>
<li>Defining your function as a property of <code>jQuery.fn</code>, and</li>
<li>Returning the jQuery object that it is called on. (this allows chaining calls, something near and dear to jQuery developers&#8217; hearts)</li>
<li>To be incorporated as an official plugin, the plugin should be defined in a standalone file, named &#8220;jquery.[plugin name].js&#8221; where &#8220;[plugin name]&#8221; is your plugin&#8217;s name.</li>
</ol>

<p>Let&#8217;s take a look at the next version of our code, the first as a plugin:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">nav</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> nav <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      nav.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &gt; li&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> li <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>li.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            li.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<p>This is a very suitable, fine piece of code, and it&#8217;s even a plugin now. It&#8217;s even reusable, because it&#8217;s no longer tied to the &#8220;.nav&#8221; class. You can actually call it multiple times on a page, and using multiple selectors, and all will work just fine, independently:</p>

<ul>
<li><code>$(".nav").nav()</code> works just like our old code, only now it&#8217;s a <em>lot</em> shorter.</li>
<li><code>$("#topNav").nav()</code> also works, only this is for a single unique element</li>
</ul>

<p>However, it&#8217;s not very versatile beyond the selector bit. For that, we&#8217;ll need to introduce the concept of <em>default options</em> and overrides. jQuery provides a simple means of setting up default settings for a plugin that can be overridden in any call to it by passing in an options object. The options object concept is an echo of similar functionality in other programming languages: Ruby (via Hashes), Python (via named arguments) and other languages via similar constructs such as associative arrays. The idea behind it is that no one wants to have to memorize the order of parameters for a function, so don&#8217;t make them! Object literals allow you to specify their component properties in any order.</p>

<p>To obtain this functionality in jQuery, simply call <code>jQuery.extend()</code>, passing in an object literal for the default values, and the options object parameter from the plugin&#8217;s function. Through this, we can specify faster or slower fade effects, as well as change the actual effects called. This is the final version of our plugin, and the code is quite a bit longer.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">multinav</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> settings <span style="color: #339933;">=</span> jQuery.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
      effect<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;fade&quot;</span><span style="color: #339933;">,</span>
      duration<span style="color: #339933;">:</span> <span style="color: #CC0000;">250</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> fade <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      over<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      out<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> slide <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      over<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">slideDown</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      out<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">slideUp</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> size <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      over<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      out<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> effect <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">effect</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;slide&quot;</span><span style="color: #339933;">:</span>
        effect <span style="color: #339933;">=</span> slide<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;size&quot;</span><span style="color: #339933;">:</span>
        effect <span style="color: #339933;">=</span> size<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;fade&quot;</span><span style="color: #339933;">:</span>
      <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
        effect <span style="color: #339933;">=</span> fade<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// iterate over the elements obtained from the selector</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> nav <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      nav.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &gt; li &gt; ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      nav.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &gt; li&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        effect.<span style="color: #660066;">over</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> li <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">removeClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>li.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            effect.<span style="color: #660066;">out</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Though this code is longer, it&#8217;s still quite legible. We&#8217;ve changed the plugin&#8217;s name to <em>multinav</em> to reflect it&#8217;s new, multi-functional nature The new benefit is that we are able to call on the plugin with alternate effects and timing, simply by passing in an object literal with alternate values from the defaults. Here are a few examples:</p>

<ul>
<li><code>$(".nav:first").multinav();</code> &#8211; this is the default behavior</li>
<li><code>$(".nav:nth(1)").multinav({effect: "slide", duration: 100});</code> &#8211; this selects the second nav-classed element and performs a fast slideIn on hover</li>
<li><code>$(".nav:last").multinav({effect: "size", duration: 1000});</code> &#8211; this selects the last nav-classed element and performs a slow size-in on hover</li>
</ul>

<p>Using these ideas, you can build any number of plugins which, when handled correctly, can <em>work alongside other libraries</em>, can <em>work under a variety of conditions</em> and <em>present different functionality based on the needs of the job at hand</em>. Calling on a plugin is <strong>typically only one line of code</strong>. That&#8217;s a lot of power in one line. Not only that, but when using the practices of graceful degradation, your page will look and behave appropriately when interactivity is not possible in the browser.</p>

<p>Remember that any widget with interactive elements (form controls, ajax links, tabs, content which moves around or hides/reveals&#8230;) should either hide those interactive elements in the CSS and reveal in the JavaScript, or find a way to make use of the elements using the backend. This ensures the page does not contain any confusing, ineffectual controls which look as though they&#8217;ll bring about change on the page. In the case of ajax tabs, for instance, you have two choices: Hide the tabs altogether (certainly the easier route), or organize your content and backend technology so that the tabs work as static links to reload the page showing the appropriate (newly-clicked) tab content and hiding the other tabs. This is a bit more trouble, and if you can get away with showing only the most-important content in the first tab, I suggest taking that route.</p>

<p>Have fun writing gracefully-degrading jQuery plugins!</p>
<img src="http://feeds.feedburner.com/~r/thyncology/~4/9TwZORNebfE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/javascript/2009/03/gracefully-degrading-widgets-part-2-navbars-jquery-plugins/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.thynctank.com/javascript/2009/03/gracefully-degrading-widgets-part-2-navbars-jquery-plugins/</feedburner:origLink></item>
		<item>
		<title>SafariWatir Nuisances</title>
		<link>http://feedproxy.google.com/~r/thyncology/~3/iUBoWPwc1yA/</link>
		<comments>http://www.thynctank.com/ruby-rails/2009/03/safariwatir-nuisances/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 06:04:34 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[Ruby & Rails]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[front end]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[watir]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/?p=157</guid>
		<description><![CDATA[The place where I work (RideCharge) is a Rails shop. As such, we&#8217;ve embraced numerous Ruby technologies, including several ActiveRecord plugins, test frameworks, and other components used at various points in the stack. I deal with a lot of view-side and presentational stuff, including having embraced Sass for stylesheets (I even use them in some [...]]]></description>
			<content:encoded><![CDATA[<p>The place where I work (<a href="http://www.ridecharge.com">RideCharge</a>) is a Rails shop. As such, we&#8217;ve embraced numerous Ruby technologies, including several ActiveRecord plugins, test frameworks, and other components used at various points in the stack. I deal with a lot of view-side and presentational stuff, including having embraced Sass for stylesheets (I even use them in some non-Rails/Ruby projects via CLI), making use of AssetPackager and so on.</p>

<p>One thing RideCharge has used, but which I&#8217;ve only recently expressed interest in, is Watir. Watir is a cool testing toolkit that allows you to control and get feedback from various Web browsers using Ruby. You can use it, or variations of it, with IE (the original Watir was IE-only) Firefox, Safari, or even Flash using the various <a href="http://wtr.rubyforge.org/platforms.html">variations</a>. I&#8217;ve only spent enough time with it to get it installed and tinker a bit, so this post only deals with real in-the-field experience. As such, I&#8217;ve only played with the FireWatir and SafariWatir variations.</p>

<p>One thing I&#8217;ve noticed already are some nuisances in SafariWatir and FireWatir, and perhaps Watir in general in some cases:</p>

<ul>
<li>SafariWatir&#8217;s <code>goto</code> method requires the protocol as part of the URL whereas FireWatir does not. This is a minor complaint.</li>
<li>Links in SafariWatir appear to have no href or url property (among others), despite <a href="http://wiki.openqa.org/display/WTR/Methods+supported+by+Element">this table</a> showing that they should.</li>
<li>SafariWatir has no url to determine the current page.</li>
<li>No support for CSS selectors that I&#8217;m aware. This could be brought in from one of at least two Ruby projects (<a href="http://wiki.github.com/why/hpricot">Hpricot</a> or <a href="http://github.com/tenderlove/nokogiri/tree/master">Nokogiri</a>). XPath is a bore.</li>
<li>Confusingly it only selects the first matching element if multiple elements match. There&#8217;s no way to verify the # of elements, etc. Selecting a different matching element is accomplished through the <code>:index</code> parameter.</li>
<li>Having a different &#8220;selector&#8221; method for almost every element type seems strange, but perhaps this is just bias from having used JavaScript selector engines so much.</li>
<li>Having the browser &#8220;click&#8221; a link where JavaScript is supposed to intercept the click fails to trigger the JavaScript, or may simply have no effect (in one case in SafariWatir).</li>
<li>No convenient &#8220;click the back button&#8221; method. This would be useful for testing state-saving in Ajax-focused applications where browser history is an issue.</li>
</ul>
<img src="http://feeds.feedburner.com/~r/thyncology/~4/iUBoWPwc1yA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/ruby-rails/2009/03/safariwatir-nuisances/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.thynctank.com/ruby-rails/2009/03/safariwatir-nuisances/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 0.917 seconds -->
