<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">

	<title type="text">OnWired Blaugh! &amp; Bookmarks</title>
	<subtitle type="text">OnWired Blaugh! &amp; Bookmarks: The Big Combo! Featured articles and bookmarks...what more could you want?</subtitle>
	<link rel="alternate" type="text/html" href="http://onwired.com/blog/" />
	<link rel="self" type="application/atom+xml" href="http://onwired.com/onwired/combo_feed/" />
	<updated>2008-07-16T19:32:59Z</updated>
	<rights>Copyright (c) 2008 OnWired LLC</rights>
	<generator uri="http://expressionengine.com/" version="1.6.1">ExpressionEngine</generator>
	<id>tag:onwired.com,2008:07:16</id>

	
	<entry>
		<title>Cheat sheets for front end web developers</title>
		<link rel="alternate" type="text/html" href="http://sixrevisions.com/resources/cheat_sheets_web_developer/" />
		<id>tag:onwired.com,2008:bookmarks/7.400</id>
		<published>2008-07-16T18:31:00Z</published>
		<updated>2008-07-16T19:32:59Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Great post for the front end folks. Lot&#8217;s of great resources for CSS, HTML, and even jQuery. Grab your printouts while you&#8217;re there.</p>

					]]></content>
	</entry>

	<entry>
		<title>12 Ways to Use Twitter to Increase Your Productivity</title>
		<link rel="alternate" type="text/html" href="http://www.simplehelp.net/2008/05/21/12-ways-to-use-twitter-to-increase-your-productivity/" />
		<id>tag:onwired.com,2008:bookmarks/7.399</id>
		<published>2008-07-08T18:35:00Z</published>
		<updated>2008-07-08T19:36:12Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>I especially like the Group Tweet referenced on this post. </p>

					]]></content>
	</entry>

	<entry>
		<title>OnWired Listed on Web Designer Wall&#8217;s 2008 Design Trends</title>
		<link rel="alternate" type="text/html" href="http://www.webdesignerwall.com/trends/2008-design-trends/" />
		<id>tag:onwired.com,2008:bookmarks/7.398</id>
		<published>2008-07-05T19:36:00Z</published>
		<updated>2008-07-05T20:40:29Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Nick La over at Web Designer Wall referenced us in his 2008 Design Trends post. He&#8217;s got a whopping list of 82 sites, from Best Web Gallery, that showcases the current trends.</p>

					]]></content>
	</entry>

	<entry>
		<title>Name This</title>
		<link rel="alternate" type="text/html" href="http://namethis.com/name_this/" />
		<id>tag:onwired.com,2008:bookmarks/7.397</id>
		<published>2008-06-09T22:32:30Z</published>
		<updated>2008-06-09T22:32:31Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Make the otherwise time consuming process of finding a market ready name quick and easy.</p>

					]]></content>
	</entry>

	<entry>
		<title>Developing Creative Ideas</title>
		<link rel="alternate" type="text/html" href="http://www.alistapart.com/articles/savingthespark" />
		<id>tag:onwired.com,2008:bookmarks/7.396</id>
		<published>2008-06-09T22:22:40Z</published>
		<updated>2008-06-09T22:22:41Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Ideas. They&#8217;re at the heart of every creative process. However, almost no really good ideas are flashes of inspiration. Great article here by Mark Boulton via A List Apart&#8230;</p>

					]]></content>
	</entry>

	<entry>
		<title>&#8226; Here We Grow Again</title>
		<link rel="alternate" type="text/html" href="http://onwired.com/blog/here-we-grow-again/" />
		<id>tag:onwired.com,2008:blog/1.395</id>
		<published>2008-06-03T14:55:00Z</published>
		<updated>2008-06-03T16:07:40Z</updated>
		<author>
			<name>Jon</name>
			<uri>http://onwired.com</uri>
		</author>
		
			<category term="News" scheme="http://onwired.com/blog/archive/archive/news/" label="News" />
		<content type="html"><![CDATA[
							
					A few new guys and gals have joined the ranks at OnWired.
					<p>In the past few weeks, the OnWired team has doubled in size.&nbsp; After reviewing hundreds of resumes and and conducting more than our fair share of interviews, we found a few up-and-coming stars that we just couldn&#8217;t pass up.</p>
<p><a href="/about/megan-richhart/">Megan Richhart</a> is our newest web designer.&nbsp; She recently graduated from Ball State University, where she studied journalism graphics and digital publishing.&nbsp; Given the fact that she was taking a class on designing digital media for the iPhone in her last semester, it&#8217;s safe to say that she&#8217;s on the cutting edge of technology trends.&nbsp; She has a great eye and will be a great asset to our design team.</p>
<p><a href="/about/brett-buddin/">Brett Buddin</a> joins us as a web developer.&nbsp; He is a recent computer science graduate from UNC Wilmington, and his focus is on back-end development.&nbsp; Brett can wrangle PHP and MySQL in his sleep, and we&#8217;re amazed at the knowledge he brings to the team.&nbsp; Funny enough, we&#8217;ve been using one of Brett&#8217;s creations for quite some time &mdash; he is the author of the <a href="http://www.apple.com/downloads/dashboard/email_messaging/gmailinbox.html" rel="external">Gmail Inbox widget</a> for the Mac OS X Dashboard.</p>
<p><a href="/about/patrick-clarke/">Patrick Clarke</a>, an NC State graduate, rounds out our team of web developers.&nbsp; He brings expertise in ExpressionEngine, our CMS of choice, to the table.&nbsp; Patrick also has a strong background in journalism &mdash; he managed a team of 80+ to produce NC State&#8217;s award-winning student newspaper &mdash; so he definitely brings a unique viewpoint to presenting content on the web.</p>
<p><a href="/about/julie-lechner/">Julie Lechner</a> is our new Account Manager.&nbsp; She fills a much-needed place in the team, helping to walk clients through the design and development process all the way from the initial contact to the launch of the new site.&nbsp; Apart from her customer service skills, Julie brings a wealth of marketing experience with her from Hotels.com and Sabre, so she&#8217;ll definitely come in very handy around the office.</p>
<p>Now we just need to move into a bigger office&#8230;
</p>
					
				
					]]></content>
	</entry>

	<entry>
		<title>Two New FF3 Features</title>
		<link rel="alternate" type="text/html" href="http://www.sitepoint.com/blogs/2008/05/23/two-hidden-features-new-in-firefox-3/" />
		<id>tag:onwired.com,2008:bookmarks/7.386</id>
		<published>2008-05-23T21:31:37Z</published>
		<updated>2008-05-23T21:31:38Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Support for &#8220;soft hyphen&#8221; and &#8220;display: inline-block.&#8221;</p>

					]]></content>
	</entry>

	<entry>
		<title>18 New AJaX Programming Patterns</title>
		<link rel="alternate" type="text/html" href="http://softwareas.com/18-new-ajax-programming-patterns" />
		<id>tag:onwired.com,2008:bookmarks/7.385</id>
		<published>2008-05-22T20:05:05Z</published>
		<updated>2008-05-22T20:05:06Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>I do all my AJaX with jQuery.</p>

					]]></content>
	</entry>

	<entry>
		<title>What&#8217;s Next in jQuery?</title>
		<link rel="alternate" type="text/html" href="http://vimeo.com/984675" />
		<id>tag:onwired.com,2008:bookmarks/7.384</id>
		<published>2008-05-22T02:50:38Z</published>
		<updated>2008-05-22T02:50:40Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Mr Resig on jQuery Core 1.3.</p>

					]]></content>
	</entry>

	<entry>
		<title>On PHP, Again</title>
		<link rel="alternate" type="text/html" href="http://www.codinghorror.com/blog/archives/001119.html" />
		<id>tag:onwired.com,2008:bookmarks/7.383</id>
		<published>2008-05-21T18:57:53Z</published>
		<updated>2008-05-21T18:57:55Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>&#8220;It&#8217;s a galactic supernova of incomprehensibly colossal, mind-bendingly awful suck.&#8221; Wow.</p>

					]]></content>
	</entry>

	<entry>
		<title>35 Useful Source Code Editors Reviewed</title>
		<link rel="alternate" type="text/html" href="http://www.smashingmagazine.com/2008/05/07/35-useful-source-code-editors-reviewed/" />
		<id>tag:onwired.com,2008:bookmarks/7.382</id>
		<published>2008-05-15T15:38:16Z</published>
		<updated>2008-05-15T15:38:18Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>Coda and TextMate are tops, naturally.</p>

					]]></content>
	</entry>

	<entry>
		<title>An Argument for PHP</title>
		<link rel="alternate" type="text/html" href="http://firsttube.com/read/An-Argument-for-PHP" />
		<id>tag:onwired.com,2008:bookmarks/7.381</id>
		<published>2008-05-14T17:10:51Z</published>
		<updated>2008-05-14T17:10:53Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<p>&#8220;If you can&#8217;t concede that PHP can be the right tool some of the time for some situations, you shouldn&#8217;t be trusted to code or make adult decisions.&#8221;</p>

					]]></content>
	</entry>

	<entry>
		<title>&#8226; Using jQuery to Produce Rich User Interfaces</title>
		<link rel="alternate" type="text/html" href="http://onwired.com/blog/using-jquery-to-produce-rich-user-interfaces-onwired-portfolio-example/" />
		<id>tag:onwired.com,2008:blog/1.380</id>
		<published>2008-05-13T07:05:00Z</published>
		<updated>2008-05-30T14:43:53Z</updated>
		<author>
			<name>Nathan</name>
			<uri>http://onwired.com</uri>
		</author>
		
			<category term="The Very Best of OnWired" scheme="http://onwired.com/blog/archive/archive/best-of/" label="The Very Best of OnWired" />
		
			<category term="Development" scheme="http://onwired.com/blog/archive/archive/development/" label="Development" />
		<content type="html"><![CDATA[
							
					Curious about our portfolio slider? Learn about how we pulled it off with the jQuery framework, which powers all the animations on the site.
					<p>Since we launched our new company site back in November, we&#8217;ve gotten a lot of positive feedback from visitors and well-wishers about the novel approach to our <a href="/portfolio/">portfolio</a>.  And while we expected to hear from other designers and developers, I was somewhat surprised to learn the impact it has on potential clients:  often, via email or in person, I hear that seeing the stages of our creative process presented as a zippy polaroid left a lasting impression in their mind.  And when a prospective client is evaluating a dozen (or more) vendors to tackle their next big project, this becomes extremely valuable &mdash; it helps us stand out!  So it&#8217;s easy to make a case that rich animations are more than just eye candy; together with our deliberately-whimsical copywriting they become an important part of our brand identity.</p>

<p>All the animations used throughout the company site I&#8217;ve written with <a href="http://jquery.com/">jQuery</a>, the greatest JavaScript library on the planet (yeah, I went there).  jQuery makes client-side scripting not only super-easy but a blast to write. I&#8217;ve <a href="http://onwired.com/blog/my-development-workflow/">written about jQuery before</a> and how much I like it (I even recently gave a talk <a href="http://refreshthetriangle.org/posts/006_meeting_recap/">to that effect</a>) but have long wanted to break down how it powers our little portfolio slider.  (I won&#8217;t go into too much detail about jQuery itself &mdash; I leave finding introductory tutorials elsewhere on the intertubes as an exercise to the reader.)</p>

<h4>First, A Little Background</h4>

<p>We decided early to let visitors in on our creative process.  But the question remained how exactly to execute it:  we only have so much screen real estate and it&#8217;s important to maximize the size of the screenshot (too often these days I&#8217;m squinting at portfolio entries &mdash; get with it, people!) without cluttering the design with too many extraneous visual elements.  Where I ultimately got the idea from was the <a href="http://demos.mootools.net/Fx.Scroll">Fx.Scroll</a> demo for the <a href="http://mootools.net/">Mootools</a> JavaScript <a href="http://demos.mootools.net/">effects library</a>:  at first my plan was to use one giant image composed of all the individual screenshots and, instead of moving up and down, just move back and forth within the &#8220;polaroid&#8221; viewport image that Jon created.  I started working on some demos of it, teaching myself Mootools along the way.  </p>

<p>Thing is, I kept running into problems.  I&#8217;m still not sure why, but I kept getting significantly inconsistent results across browsers and in some cases no results at all.  And not just the usual suspects, but also between Safari and Firefox, which is much more difficult to pinpoint (if you think CSS rendering differences between browsers is sticky, wait till you try JavaScript).  Moreover, the Mootools syntax I&#8217;m not crazy about:  I find it kind of awkward and less intuitive than jQuery.  Now, much of this I&#8217;m sure can be chalked up to my inexperience with it and doubtless Mootools defenders are going to write me an earful, but it was actually frustration that drove me to jQuery as an alternative and I got the results I was looking for with less effort in less time.  Make of it what you will, but that was my subjective experience.</p>

<p>I began re-writing the Mootools scripts using jQuery and had much better luck.  But even though other parts of the site became easier, I no longer had a plugin already written that did what I was looking for.  Fortunately, though &mdash; and this is kind of the whole point &mdash; I was able to write my own, total n00b that I was (er, still am).  </p>

<h4>Enough, Dude, Let&#8217;s Dive In Already</h4>

<p>First, let&#8217;s take a look at the portfolio markup.  The whole thing is achieved with a single container <code>division</code> called &#8220;portfolio&#8221; that contains four child elements:  two unordered lists, an image and an anchor (i.e., link).  In other words:</p>

<ol class="code">
<li><pre>&lt;div id="portfolio"&gt;</pre></li>
<li><pre>   &lt;ul id="gallery"&gt;</pre></li>
<li><pre>      &lt;li&gt;&lt;img src="/{client}/before.jpg" /&gt;&lt;/li&gt;</pre></li>
<li><pre>      &lt;li&gt;&lt;img src="/{client}/sketch.jpg" /&gt;&lt;/li&gt;</pre></li>
<li><pre>      &lt;li&gt;&lt;img src="/{client}/wireframe.jpg" /&gt;&lt;/li&gt;</pre></li>
<li><pre>      &lt;li&gt;&lt;img src="/{client}/after.jpg" /&gt;&lt;/li&gt;</pre></li>
<li><pre>   &lt;/ul&gt;</pre></li>
<li><pre>   &lt;img id="frame" width="580" height="415" src="frame.png" /&gt;</pre></li>
<li><pre>   &lt;ul id="sequence"&gt;</pre></li>
<li><pre>      &lt;li id="before"&gt;&lt;a href="/{client}/before.jpg"&gt;&lt;a&gt;&lt;/li&gt;</pre></li>
<li><pre>      &lt;li id="sketch"&gt;&lt;a href="/{client}/sketch.jpg"&gt;&lt;a&gt;&lt;/li&gt;</pre></li>
<li><pre>      &lt;li id="wireframe"&gt;&lt;a href="/{client}/wireframe.jpg"&gt;&lt;a&gt;&lt;/li&gt;</pre></li>
<li><pre>      &lt;li id="after"&gt;&lt;a href="/{client}/after.jpg"&gt;&lt;a&gt;&lt;/li&gt;</pre></li>
<li><pre>   &lt;/ul&gt;</pre></li>
<li><pre>   &lt;a id="launch" rel="external" href="{url}"&gt;</pre></li>
<li><pre>      &lt;img src="launch.png" alt="Launch this site" /&gt;</pre></li>
<li><pre>   &lt;/a&gt;</pre></li>
<li><pre>&lt;/div&gt;</pre></li>
</ol>

<p>The first list (&#8220;gallery&#8221;) contains four items:  these are the actual screenshots that go zooming by.  The image that follows on line 8, called &#8220;frame&#8221;, <a href="/images/portfolio/frame.png">looks like this</a>:  it&#8217;s a 580px wide PNG illustration drawn by Jon and it contains a gigantic, transparent center portion.  It sits <em>in front of</em> the previous list, following it in the flow of the markup and using a <code>z-index</code> to ensure it stays that way.  The screenshot images of the list behind it show through the center window but are obscured when outside it.  </p>

<p>Next comes the second list (&#8220;sequence&#8221;) beginning on line 9, which accounts for the four navigation items at the bottom that you rollover with your mouse to fire the script.  Finally, there&#8217;s a transparent image (<code>launch.png</code>) inside an anchor called &#8220;launch&#8221; that sits on top of the image &#8220;frame&#8221; and takes you to the website in question.  (Interestingly, the button originally said &#8220;Launch the site&#8221;, but after some user testing we determined that the language was too obscure for the average visitor and I had Jon re-export it saying &#8220;View the site&#8221; instead. The image name and markup, though, remained unchanged, since it&#8217;s easier just to upload an image with the same name.  Yes, I&#8217;m a little lazy.)</p>

<p>At the heart of it, all you need to focus on is the initial unordered list with <code>id="gallery"</code>:  that&#8217;s where the action occurs.  I mentioned before that the image &#8220;frame&#8221; sits in front of the list.  What happens is, when you hover over one of the nav items, the <strong>entire unordered &#8220;gallery&#8221; list</strong> shifts to the side <em>behind the polaroid border image</em>, leaving the screenshot of interest (sketch, wireframe, etc.) showing through the transparent center frame.  Here&#8217;s a simplified visual representation:</p>

<div class="screenshot-big"><p><img src="/images/blog/screenshots/diagram.png" alt="Big Screenshot" />Fig. 1 Whoosh!</p></div>

<p>And here&#8217;s what it looks like in the context of the <a href="/images/blog/screenshots/ul_highlighted.png" rel="external">actual page</a>. (Note that the <code>&lt;ul&gt;</code> extends well past the right column.)</p>

<h4>I Thought He&#8217;d Never Get to the jQuery</h4>

<p>Easy, tiger.  So, what makes it move?  It all comes down to one simple, flexible function jQuery makes available called <code><a href="http://docs.jquery.com/Effects/animate">animate()</a></code>. <code>animate()</code> lets you take any element and change things about it <em>over time</em>:  that&#8217;s all an animation is, really, just a regularly occurring change over time.</p>

<p>Let&#8217;s say, for example, that you had a box and that box is located 50px from the left side of your browser window because you assigned it <code>left: 50px</code>.  When you grab that box with <code>animate()</code>, you can pass a value to <code>animate()</code> that you want that <code>left</code> number <em>to arrive at over time</em>.  So if you told it to <code>animate({left: "100px"});</code>, it would increase that value of the box to 100px over 4 seconds (that&#8217;s the default), and you&#8217;d see it slide across your screen.  But you can give it any duration you want:  care to speed it up?  Try <code>animate({left: "100px"}, "fast")</code>.  Instead of &#8220;slow&#8221;, &#8220;normal&#8221;, and &#8220;fast&#8221;, you can specify any number you want, in milliseconds.  We could write <code>animate({left: "100px"}, 2000);</code> if we wanted that <code>left</code> value to change from 50px to 100px in 2 seconds.</p>

<p>That&#8217;s all I&#8217;m doing with the portfolio slider:  when you hover over one of the nav items, it triggers jQuery to reassign the <code>left</code> value of the <code>&lt;ul id="gallery"&gt;</code> to some new number, over time, and this is how it moves.  </p>

<p>Got all that?  Let&#8217;s have a look at the jQuery used to trigger the behavior (wrapped lines marked with &#8617;):</p>

<ol class="code">
<li><pre>$(window).bind("load", function() {</pre></li>
<li><pre>   $("div#portfolio").prepend('&lt;img src="loading.gif" &#8617;</pre></li>
<li><pre>      class="loading" alt="loading..." /&gt;');</pre></li>
<li><pre>   $("ul#gallery").hide().portfolio();</pre></li>
<li><pre>});</pre>
</ol>

<p>I call this in the <code>&lt;head&gt;</code> of every portfolio page.  The first line assigns or &#8220;binds&#8221; the behavior that follows to the completed loading of the browser window, which is functionally equivalent to writing <code>&lt;body onload="function();"&gt;</code> with classic JavaScript.  In line 2, by grabbing the division with an <code>id</code> of &#8220;portfolio&#8221; using the <code>$()</code> function, we &#8220;wrap&#8221; a jQuery object around it, and this is what lets us apply cool things like <code>animate()</code> to it and is what I mean when I talk about &#8220;grabbing&#8221; DOM elements.  In this case, we want to prepend an <a href="/images/portfolio/loading.gif">image</a> using markup <em>that we&#8217;ve created on the fly</em> into <code>div#portfolio</code>.  </p>

<p>Why do this?  Because if a portfolio screenshot image hasn&#8217;t finished loading but the rest of the page has been displayed in the browser, this image will stand in its place until it has.  It&#8217;s not actually calculating anything, it&#8217;s just an endless animated GIF that gives the <em>illusion</em> of a progress bar.  (You can also <a href="http://www.ajaxload.info/">make your own</a>, it&#8217;s easy!) Beginning with line 3, first we grab the unordered list of interest (&#8220;gallery&#8221;), hide it with jQuery (this is a shortcut to changing its CSS to <code>"display: none"</code>) and then fire the portfolio script &mdash; in that order.  jQuery lets you stack or &#8220;chain&#8221; multiple commands together in a row.</p>

<p>(As an aside, if you&#8217;re wondering why I chose the less common <code>$(window).bind("load")</code> syntax instead of the more common <code>$(document).ready()</code> to fire the script on page load, it&#8217;s for an important reason:  in the latter example, jQuery waits until the DOM is loaded before executing the script, which includes all text but <em>excludes</em> images.  In this example it&#8217;s crucial to wait until all the screenshot images have been downloaded to the browser because we have to manipulate them later in the script.  The former example, the one I used here, does that:  it waits not only until the DOM has finished loading <em>but also</em> until all the images have loaded, and that&#8217;s the difference.  Other than that, they&#8217;re functionally equivalent; but if you&#8217;re having trouble with your script as I was, this may be the reason why and took me ages to figure out, since it&#8217;s not well-documented.)</p>

<p>That&#8217;s all well and good, but what does the <code>.portfolio()</code> bit do?  And where does that function come from?  To find out, we turn to an external script.  Let&#8217;s look at what we&#8217;re triggering when we call it:</p>

<p>(Note: wrapped lines marked with &#8617;):</p>

<ol class="code">
<li>jQuery.fn.portfolio = function() {</li>
<li><pre>    var $polaroid = $(this);</pre></li>
<li><pre>    $polaroid.parent().find("img.loading").remove();</pre></li>
<li><pre>    $polaroid.show();</pre></li>
<li><pre>    var imgWidth = $polaroid.children("li").width();</pre></li>
<li><pre>    var imgNum = $polaroid.children("li").length;</pre></li>
<li><pre>    var galleryWidth = imgWidth * imgNum;</pre></li>
<li><pre>    $polaroid.css("width", galleryWidth);</pre></li>
<li><pre>    $polaroid.children('li').css("width", imgWidth);</pre></li>
<li><pre>    $("ul#sequence a").each(function(i) {</pre></li>
<li><pre>        $(this).bind("mouseover", function(){</pre></li>
<li><pre>            var margin = - (imgWidth * i);</pre></li>
<li><pre>            $(this).addClass("current").parent().parent()  &#8617;</pre></li>
<li><pre>                 .find("a:not($(this))").removeClass("current");</pre></li>
<li><pre>            $polaroid.animate({left: margin}, 500, "easeInOutExpo");</pre></li>
<li><pre>            console.log("i = "+i+" and margin = "+margin+"px");</pre></li>
<li><pre>        });</pre></li>
<li><pre>        $(this).click(function() {return false});</pre></li>
<li><pre>    });</pre></li>
<li>};</li>

</ol>

<p>(You can also view it for real <a href="/scripts/portfolio.js">here</a>, with inline comments.)  Got all that?  If not, how about we &#8230;</p>

<h4>Tackle That in Stages</h4>

<h5>Lines 1&ndash;4</h5>

<ul class="code">
<li>jQuery.fn.portfolio = function() {</li>
<li><pre>    var $polaroid = $(this);</pre></li>
<li><pre>    $polaroid.parent().find("img.loading").remove();</pre></li>
<li><pre>    $polaroid.show();</pre></li>
</ul>

<p>The first line you can safely ignore for now:  you need that whenever you&#8217;re writing a jQuery plug-in, which is how I approached this example, but explaining it is beyond the scope of this piece.  Suffice it to say, writing it like this lets me call that <code>.portfolio()</code> function on the gallery list that we say earlier, which executes all the code that follows, even though I made that up and it isn&#8217;t a core jQuery function.</p>

<p>In line 2, we create a new variable called <code>$polaroid</code> and we assign it the value of whatever element we passed to the anonymous function declared in line 2 &mdash; in this case, the same <code>&lt;ul&gt;</code> with <code>id="gallery"</code> we saw earlier.  This lets us use <code>$portfolio</code> as a reference or alias to that list&#8230; I usually like to use dollar signs in front of jQuery instance variables because it helps me tell them apart from pure JavaScript variables (i.e., things we haven&#8217;t &#8220;grabbed&#8221; with jQuery).  Line 3 then removes that &#8220;loading&#8221; GIF we saw earler.  We do this first by using <code>$polaroid.parent()</code>, which gives us a reference to <code>&lt;div id="portfolio"&gt;</code>, the parent of <code>&lt;ul id="gallery"&gt;</code>.  We then look for any image(s) with a class of &#8220;loading&#8221; anywhere within the division and scoop it out of the page.  Finally, we &#8220;show&#8221; the unordered list, which we&#8217;d hidden previously.</p>

<h5>Lines 5&ndash;9</h5>

<ul class="code">
<li><pre>    var imgWidth = $polaroid.children("li").width();</pre></li>
<li><pre>    var imgNum = $polaroid.children("li").length;</pre></li>
<li><pre>    var galleryWidth = imgWidth * imgNum;</pre></li>
<li><pre>    $polaroid.css("width", galleryWidth);</pre></li>
<li><pre>    $polaroid.children('li').css("width", imgWidth);</pre></li>
</ul>

<p>Next, we need to find out how wide each of the screenshot images is. So line 5 sets a variable &#8220;imgWidth&#8221; equal to the width of the list items within the &#8220;gallery&#8221; list. (In this example, they&#8217;re always going to be 580px and that&#8217;s not going to change, so I could have simply used that.  But I didn&#8217;t know that at the time, since we hadn&#8217;t finalized the design, and besides it&#8217;s good coding practice in general to avoid hard-coding a value in case you want to use it for something else later.) Line 6 calls a property of the jQuery object <code>$polaroid</code> (&#8220;length&#8221;) that returns the number of all the items in it (like a JavaScript array)&#8230; four, in this case.  (Usually <code>.length</code> is faster than the equivalent jQuery <code>.size()</code>, so use it unless you have a compelling reason otherwise. <strong>UPDATE:</strong> It appears that <code>.size()</code> has been deprecated, so stick with <code>.length</code>) Line 7 sets a variable &#8220;galleryWidth&#8221; to the product of these numbers (2320px) that we then use to set the width of the <code>&lt;ul&gt;</code> &#8220;gallery&#8221; as well as the individual list items contained inside.</p>

<h5>Lines 10&ndash;12</h5>

<ul class="code">
<li><pre>    $("ul#sequence a").each(function(i) {</pre></li>
<li><pre>        $(this).bind("mouseover", function(){</pre></li>
<li><pre>           var margin = - (imgWidth * i);</pre></li>
</ul>

<p>In line 10 we open a code block that iterates over each of the links within the <code>&lt;ul&gt;</code> &#8220;sequence&#8221;.  In it, we first assign a <code>mouseover</code> event handler to each one and, upon mouseover, set a variable equal to <em>minus</em> 580px multiplied by our loop counter (<code>0</code> through <code>3</code>), which gives us <code>0</code>, <code>&ndash;580</code>, <code>&ndash;1160</code> and <code>&ndash;1740</code>, respectively.  So depending on which link you hover over, you assign the &#8220;margin&#8221; variable to one of those four numbers.  This is one of the crucial bits, since that number gets passed to another function later, whereby the <code>&lt;ul&gt;</code> that moves knows by how much to move.</p>

<h5>Lines 13&ndash;20</h5>

<ul class="code">
<li><pre>            $(this).addClass("current").parent().parent()  &#8617;</pre></li>
<li><pre>                 .find("a:not($(this))").removeClass("current");</pre></li>
<li><pre>            $polaroid.animate({left: margin}, 500, "easeInOutExpo");</pre></li>
<li><pre>            console.log("i = "+i+" and margin = "+margin+"px");</pre></li>
<li><pre>        });</pre></li>
<li><pre>        $(this).click(function() {return false});</pre></li>
<li><pre>    });</pre></li>
<li>};</li>
</ul>

<p>You&#8217;ll notice that one of the links in the &#8220;sequence&#8221; list always has an underline to indicate current status:  before, sketch, etc.  This is accomplished by assigning a class called &#8220;current&#8221; to the link within the list, which re-assigns the background image on mouseover (actually, it uses the same background image but moves it, using a technique called <a href="http://www.alistapart.com/articles/sprites">CSS Sprites</a>).  But when you hover over another link, we need to remove whichever link <em>has</em> the class &#8220;current&#8221; and add it to whichever one you&#8217;re currently hovering over.  Lines 13 and 14 take care of this.</p>

<p>First, we start with <code>$(this)</code> which, in jQuery terms, refers to the link we&#8217;ve hovered over.  We then add the class &#8220;current&#8221; to it and traverse the DOM two levels up (first to the parent <code>&lt;li&gt;</code>, then to <em>its</em> parent <code>&lt;ul&gt;</code>).  From there, we scan through all of the DOM elements within the list &#8220;sequence&#8221; and identify any links that have the class &#8220;current&#8221; and remove the class <em>excepting the one we&#8217;re currently hovered over and just added the new class to</em>.  It most certainly would not do to remove that one!  This is a great example of jQuery showing its magic, via the expression <code>.find("a:not($(this))")</code>, which employs the <code>:not()</code> <a href="http://docs.jquery.com/Selectors/not#selector">pseudo-selector</a>.  Simply. Marvelous.</p>

<p>Lastly, after all this, we finally get to the bit that actually makes the movement happen, in line 15.  All we need to do is assign the value of the variable &#8220;margin&#8221; to the <code>left</code> value of the &#8220;gallery&#8221; <code>&lt;ul&gt;</code> &mdash; recall that &#8220;margin&#8221; changes depending on which link we&#8217;ve moused over.  In the case of the &#8220;Before&#8221; link, our loop counter &#8220;i&#8221; is <code>0</code> and therefore &#8220;margin&#8221; equals <code>0</code>, so the list gallery will get its <code>left</code> value set to <code>0</code> and the whole slider lines up along the left side.  If we hover over &#8220;Wireframe&#8221; instead, our loop counter is <code>2</code> and &#8220;margin&#8221; equates to <code>&ndash;1160</code>.  </p>

<p>As you&#8217;ll recall, a negative margin in CSS has the reverse effect as a positive one:  instead of increasing the distance between the left side of the image frame and the &#8220;gallery&#8221; element, it <em>decreases</em> it, and the net result is to shift the screenshot <strong>to the left</strong>.  We use the <code>.animate()</code> method here as described previously and pass it two other arguments:  500 is the speed (in ms, so half a second), while &#8220;easeInOutExpo&#8221; is a kind of mathematical transition curve that makes the screenshot move more slowly at the beginning and at the end of the slide.  (The curious reader can learn more about it at its <a href="http://gsgd.co.uk/sandbox/jquery/easing/">creator&#8217;s website</a>.)</p>

<p>Line 16 you may not recognize, which is a <a href="http://getfirebug.com/logging.html">custom function</a> that <a href="http://getfirebug.com/">Firebug</a> provides that lets you output info to the console.  It&#8217;s a handy way of seeing what&#8217;s going on, without using a goofy &#8220;<code>alert()</code>&#8221; call to find out the value of a variable. If you have Firebug installed, go to our portfolio page and open up the console, then try out the mouseovers in the little polaroid and you&#8217;ll see what I mean.  The final bit, <code>return false</code>, disables the default behavior of a link, which is to load another document in your browser.  Since these links function only to be targets for mouseover, there&#8217;s no point in keeping that.</p>

<h4>So That&#8217;s It in a Nutshell</h4>

<p>When you really boil it down, the whole thing doesn&#8217;t seem like much, but it sure was a hassle at the time to get working right&#8230; as you can imagine, IE6 gave me no small amount of grief getting all the transparent PNG&#8217;s to render properly. (Thanks, <a href="http://www.twinhelix.com/css/iepngfix/">Twin Helix</a> folks!) Surprisingly, I had less trouble with the JavaScript problems cross-browser than I thought I would, since jQuery automatically compensates for the differences when executing scipts between browser vendors:  the core library abstracts all the problems away.  What that means is, when you write code in jQuery, it will work everywhere, which is a <strong>huge</strong> advantage over classic DOM scripting, for which many CSS-like JavaScript hacks and workarounds exist.</p>

<p>Could you have written this in Mootools or <a href="http://www.prototypejs.org/">Prototype</a>?  Undoubtedly.  But this easily and by someone totally new to it?  That I&#8217;m less certain about, and speaks volumes about how simple and intuitive I find jQuery.  Your mileage may vary, of course, and this article is not meant as a knock on the great work these other JavaScript framework developers are doing.  I just like jQuery a whole lot.</p>

<p>(Mad props also go to Gian Carlo Mingati, whom I discovered later arrived at a <a href="http://www.gcmingati.net/wordpress/wp-content/lab/jquery/imagestrip/imageslide-plugin.html">similar solution</a>, and whose idea to use the &#8220;preloading&#8221; image I totally ganked.) </p>

					
				
					]]></content>
	</entry>

	<entry>
		<title>&#8226; Web Developer Wanted</title>
		<link rel="alternate" type="text/html" href="http://onwired.com/blog/web-developer-wanted/" />
		<id>tag:onwired.com,2008:blog/1.336</id>
		<published>2008-05-12T19:59:00Z</published>
		<updated>2008-05-14T18:56:36Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
			<category term="News" scheme="http://onwired.com/blog/archive/archive/news/" label="News" />
		<content type="html"><![CDATA[
							
					OnWired is looking for a few good men and women to join our crack team of web developers.
					<h4>We&#8217;re Looking for the Best Web Developer in Town</h4>
<p> Are you a web standards evangelist? Do you despise table-based layouts as much as we do? Can you wrestle CSS into submission and coerce PHP to do your bidding? Do you get that special tingly feeling when you roll out a shiny new site with a fancy CMS on the back end? If so, please keep reading.</p>

<p> OnWired, a full-service web design/development firm and all-around cool place to work, is on the hunt for web developers. We&#146;re looking for someone with a creative mind, a keen understanding of user experience, exceptional communication skills, attention to detail, self-motivation, and the ability to hit the deadline every time. You must be responsive &#151; no 48 hour delays in responding to emails &#151; and you can&#146;t be afraid to talk to clients.</p>

<p> On the technical side, you should be able to wrangle CSS, XHTML, PHP, and MySQL along with the occasional jQuery. If you&#146;re familiar with ExpressionEngine and CodeIgniter, that&#146;s a huge plus. We&#146;re not sticklers for fancy degrees. We just want someone who can get the job done.</p>

<p> You&#8217;ll get to work with a small, highly talented team of people who are incredibly passionate about what they do. We&#146;ve got a full-time gig waiting for the right person in our Cary, NC office, and we really need someone who can hit the ground running.</p>

<h5>World&#8217;s Greatest Cover Letter Needed</h5>
<p>Now we come to the pay-off. Your mission, should you choose to accept it, is to send your resume along with the world&#8217;s greatest cover letter to <a href="mailto:hireme@onwired.com">HireMe@OnWired.com</a>. Explain your love affair with web standards. Dazzle and amaze us with your past work. Promise us that if we hire you, all of our wildest dreams will come true. If you are convincing enough, we&#8217;ll be in touch.</p>

<p> By the way, as we said, this position is based in our Cary, NC office.  If you&#146;re not already in town or if you&#146;re not willing to relocate, we&#146;re going to have to pass.  If you run one of those outsourcing firms in India, please don&#146;t email us offering to span the globe with your low-cost coding skills. And if you happen to be the widow of a deposed Nigerian military officer, we kindly decline your offer to share your immense wealth with us. </p>

<p><strong>Please include your hourly rate when applying.</strong></p>
					
				
					]]></content>
	</entry>

	<entry>
		<title>50 Ways to Help the Planet</title>
		<link rel="alternate" type="text/html" href="http://www.50waystohelp.com/" />
		<id>tag:onwired.com,2008:bookmarks/7.376</id>
		<published>2008-04-30T18:13:00Z</published>
		<updated>2008-04-30T18:13:02Z</updated>
		<author>
			<name>Tony</name>
			<uri>http://onwired.com</uri>
		</author>
		
		<content type="html"><![CDATA[
							<h1>20 - Use your cruise control. You paid for those extra buttons in your car, so put them to work! When using cruise control your vehicle could get up to 15% better mileage. Considering today&#8217;s gasoline prices, this is a boon not only for the environment but your budget as well.</h1>

					]]></content>
	</entry>


</feed>