<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-3844503025396284551</atom:id><lastBuildDate>Fri, 14 Nov 2008 16:17:18 +0000</lastBuildDate><title>Polyesterhat.js</title><description>love live code</description><link>http://blog.polyesterhat.com/</link><managingEditor>noreply@blogger.com (Daniel W)</managingEditor><generator>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-2877295437329324867</guid><pubDate>Fri, 14 Nov 2008 16:10:00 +0000</pubDate><atom:updated>2008-11-14T08:17:19.017-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>leopard</category><category domain='http://www.blogger.com/atom/ns#'>mac</category><category domain='http://www.blogger.com/atom/ns#'>screenshot</category><title>ziggy quicklook</title><description>&lt;span style="font-size:130%;"&gt;no spiders from mars though&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/iRI4M95Zno8rsRn283W_dQ?authkey=lvFa8DXMOT0"&gt;&lt;img src="http://lh3.ggpht.com/_MQ1jAsBAeFc/SR2i45le0bI/AAAAAAAAAH0/hbJ12_GcB0o/s400/Picture%2015.png" /&gt;&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.polyesterhat.com/2008/11/ziggy-quicklook.html</link><author>noreply@blogger.com (Daniel W)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_MQ1jAsBAeFc/SR2i45le0bI/AAAAAAAAAH0/hbJ12_GcB0o/s72-c/Picture%2015.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-4246353914400246549</guid><pubDate>Wed, 02 Jul 2008 05:58:00 +0000</pubDate><atom:updated>2008-07-17T21:17:02.226-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>cross-browser-compliance</category><category domain='http://www.blogger.com/atom/ns#'>The Living Web Series</category><category domain='http://www.blogger.com/atom/ns#'>css</category><title>Centering</title><description>This is Part 2 in my Series on &lt;em&gt;the Living Web&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;There are many ways of centering things in a webpage. We'll start with the basics: say we've got a div for some reason:&lt;pre class=""&gt;&lt;br /&gt;&amp;lt;div id="blob"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The blob is shown as the cirlce in this diagram:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/BlogImages/photo?authkey=lvFa8DXMOT0#5224141490177075714"&gt;&lt;img src="http://lh3.ggpht.com/polyesterhat/SH_hAbJiagI/AAAAAAAAAFY/b3wTKFzutS4/s800/blobDefault.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now, we must place it somewhere. There are two easy ways to do this:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;1.&lt;/span&gt; We could float it, and use margins to control it's placement. The css could be:&lt;pre class=""&gt;&lt;br /&gt;div#blob {&lt;br /&gt;    float: left;&lt;br /&gt;    width: 151px;&lt;br /&gt;    height: 151px;&lt;br /&gt;    margin-left: 200px;&lt;br /&gt;    margin-top: 200px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;2.&lt;/span&gt; We could use absolute or relative positioning.&lt;pre class=""&gt;&lt;br /&gt;div#blob {&lt;br /&gt;    position: absolute;&lt;br /&gt;    width: 151px;&lt;br /&gt;    height: 151px;&lt;br /&gt;    top: 200px;&lt;br /&gt;    left: 200px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is what that would look like positioned absolutely or floated with margins:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/BlogImages/photo?authkey=lvFa8DXMOT0#5224141499666933394"&gt;&lt;img src="http://lh5.ggpht.com/polyesterhat/SH_hA-gGJpI/AAAAAAAAAFo/9azyB83Vpyg/s800/blobFloat.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.polyesterhat.com/examples/Centering/placing_blob.html"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Here is an example page showing this in real life&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Please note that if the window is resized, the offsets stay the same; in other words, when you make your browser window really big, the blobs will stay put:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/BlogImages/photo?authkey=lvFa8DXMOT0#5224141498740328210"&gt;&lt;img src="http://lh6.ggpht.com/polyesterhat/SH_hA7DLRxI/AAAAAAAAAFw/FrIp1ZHUt0U/s800/blobFloatResized.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Centering the Blob&lt;pre class=""&gt;&lt;br /&gt;div#blob {&lt;br /&gt;    /* we do not float it this time */&lt;br /&gt;    width: 151px;&lt;br /&gt;    height: 151px;&lt;br /&gt;    &lt;br /&gt;    /* the 0 is for top and bottom&lt;br /&gt;      * while the auto gets assigned to either side */&lt;br /&gt;    margin: 0 auto;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The margin: 0 auto; method only centers within the parent element. One great use for it would be to center a container div in the browser window. Interestingly, another way to do practically the same thing is:&lt;pre class=""&gt;&lt;br /&gt;div#blob {&lt;br /&gt;    position: relative;&lt;br /&gt;    left: 50%;&lt;br /&gt;    top: 15px;&lt;br /&gt;    margin-left: -75px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The other way is using absolute positioning. If you need to keep something, like an overlay in the middle of the window, then take the code above, and change relative to absolute:&lt;pre class=""&gt;&lt;br /&gt;div#blob {&lt;br /&gt;    position: absolute;&lt;br /&gt;    left: 50%;&lt;br /&gt;    top: 15px;&lt;br /&gt;    margin-left: -75px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We are telling the blob to align itself to the top left corner of the window; then we make it offset to the left by 50%, halfway across. But then we must do a margin-left of negative half of the width of the blob. In this case our blob is 151px so half is about 75px. Using this method, the blob will always stay in the middle, on top of other elements. Like this:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/BlogImages/photo?authkey=lvFa8DXMOT0#5224171142388598562"&gt;&lt;img src="http://lh4.ggpht.com/polyesterhat/SH_7-aPrRyI/AAAAAAAAAGI/TASpKgm73r4/s800/blobCenteredResized.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Remember to account for any padding and borders in the negative margin-left. Now we have a div which is always centered horizontally relative to the browser window.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.polyesterhat.com/examples/Centering/centering_blob.html"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Here is a real life example.&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;THE CRUX!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sometimes you want your overlay to stay relative to the content. An example. Image you have a div with a scrollbar; but instead of a scrollbar, you have a javascript scroller, which controls the scrolling via animations, like the black triangles in this screenshot:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/PortfolioCodeImages/photo#5224041221477500306"&gt;&lt;img src="http://lh6.ggpht.com/polyesterhat/SH-F0BIqBZI/AAAAAAAAAEo/Z4AhR5_z_lA/s800/scrollers.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;(for the programatical side of these scrollers read &lt;a href="http://portfolio.polyesterhat.com/code/2008/07/animated-scrolling.html"&gt;my article&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;When Javascript places the scroll buttons on the page, it could just position them absolutely where they need to go. This would be fine; however, if the div they need to scroll for is centered to the window, we'll need to figure something else out. If a user stretches the window, this is what happens:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/BlogImages/photo?authkey=lvFa8DXMOT0#5224181163927032978"&gt;&lt;img src="http://lh3.ggpht.com/polyesterhat/SIAFFvYoVJI/AAAAAAAAAGQ/XqiKie7j5s4/s800/scrollersResized.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In the above diagram, the scrollers are represented by the little blue rectangle inside of the larger blue rectangle. The faded scroller is the ghost image of where the scroller should end up after a window resize.&lt;br /&gt;&lt;br /&gt;So, we must extend the centering method mentioned above which used the absolute positioning and the negative margin. We need to have some logic which will figure out the right margin-left so that our scroller div will always stay relative to the middle of the window or document. Here is a diagram:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/polyesterhat/BlogImages/photo?authkey=lvFa8DXMOT0#5224189090954603090"&gt;&lt;img src="http://lh6.ggpht.com/polyesterhat/SIAMTJ3R6lI/AAAAAAAAAGk/gVmbv6u4ZUE/s800/scrollersSafeCentered.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here is the Javascript code I came up with. It's a method called safeCenter; if anyone else has already thought of this, and furthermore named this method something else, too bad.&lt;pre class="prettyprint"&gt;&lt;br /&gt;dw.safeCenter = function(item, region) {&lt;br /&gt;    var halfWidth = Dom.getViewportWidth() / 2;&lt;br /&gt;    var sWidth = cos.stripPx(Dom.getStyle(item, 'width'));&lt;br /&gt;    var sHeight = cos.stripPx(Dom.getStyle(item, 'height'));&lt;br /&gt;    var right = region['right'];&lt;br /&gt;&lt;br /&gt;    /* item on right half of window                                                 : or item on left half */&lt;br /&gt;    var marginLeft = ((right-sWidth) &amp;gt; halfWidth) ? ((right-sWidth) - halfWidth) : (0 - (halfWidth - (right-sWidth)));&lt;br /&gt;&lt;br /&gt; var marginalAdjustments = {&lt;br /&gt;     'vert'    : dw.stripPx(Dom.getStyle(item, 'marginBottom')),&lt;br /&gt;     'horz'    : dw.stripPx(Dom.getStyle(item, 'marginRight'))&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; dw.setStyles(item, {&lt;br /&gt;     'top'         : (region['bottom'] - sHeight  - marginalAdjustments['vert']) + 'px',&lt;br /&gt;     'marginLeft'  : (Math.floor(marginLeft) - marginalAdjustments['horz']) + 'px'&lt;br /&gt; });&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It has some dependancies (some are obvious):&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;var dw = {};&lt;br /&gt;var Dom = YAHOO.util.Dom;&lt;br /&gt;&lt;br /&gt;dw.stripPx = function(str) {&lt;br /&gt;    return parseInt(str.substring(0, str.indexOf('p')));&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;dw.setStyles = function(el, style) {&lt;br /&gt;    for(var i in style) {&lt;br /&gt;        Dom.setStyle(el, i, style[i]);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You may not be able to tell by looking, but dw.safeCenter has some odd qualities.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It takes an element as a parameter (item)&lt;/li&gt;&lt;li&gt;It also takes the region of another element, the 2&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;nd&lt;/span&gt; param (region)&lt;/li&gt;&lt;li&gt;It checks whether item has margin on bottom or right&lt;/li&gt;&lt;li&gt;It will place the item in the lower right hand corner of the region it's given&lt;/li&gt;&lt;li&gt;Item will be offset from region by marginalAdjustments&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Oddly, my favorite line is&lt;pre class="prettyprint"&gt;&lt;br /&gt;    /* item on right half of window                                                 : or item on left half */&lt;br /&gt;    var marginLeft = ((right-sWidth) &amp;gt; halfWidth) ? ((right-sWidth) - halfWidth) : (0 - (halfWidth - (right-sWidth)));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Number one, this is a &lt;a href="http://en.wikipedia.org/wiki/Ternary_operation"&gt;ternary operator&lt;/a&gt;. But also, it's a pretty cool math operation which determines whether to make the margin-left negative or positive. sWidth is the width of the item which the function was given. The reason the second argument is a region is just in case you need to modify the region first (otherwise I would have made the function get the region for you). The type of region I am talking about is YAHOO.util.Dom.getRegion(), which returns a &lt;a href="http://developer.yahoo.com/yui/docs/YAHOO.util.Region.html"&gt;region object&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.polyesterhat.com/examples/Centering/centering_safely.html"&gt;Here is a live example of safeCentering&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Make sure to look at the examples. As always, let me know if you have any questions about this stuff (or if you find an error).&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Enjoy.&lt;/span&gt;</description><link>http://blog.polyesterhat.com/2008/07/centering.html</link><author>noreply@blogger.com (Daniel W)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/polyesterhat/SH_hAbJiagI/AAAAAAAAAFY/b3wTKFzutS4/s72-c/blobDefault.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-2619882280472552505</guid><pubDate>Thu, 05 Jun 2008 05:32:00 +0000</pubDate><atom:updated>2008-06-05T00:21:31.017-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xhtml</category><category domain='http://www.blogger.com/atom/ns#'>dustin diaz</category><category domain='http://www.blogger.com/atom/ns#'>strict</category><title>XHTML 1.0 Strict</title><description>Everyone needs to be denied freedom at some point. Here is your chance, with my new &lt;a href="http://code.polyesterhat.com/examples/XHTML/"&gt;XHTML 1.0 Strict&lt;/a&gt; template set.&lt;br /&gt;&lt;br /&gt;There is a:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.polyesterhat.com/examples/XHTML/DW_XHTML_1.0_Strict.html"&gt;Fancy Version&lt;/a&gt; (97 kilobytes)&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.polyesterhat.com/examples/XHTML/XHTML_1.0_Strict.html"&gt;Basic Version&lt;/a&gt; (376 bytes)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Now, it is a fact; everyone and their mom has their own strict template.&lt;br /&gt;&lt;br /&gt;It would be sin to leave you without the corresponding &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; snippet:&lt;br /&gt;&lt;br /&gt;&lt;pre class=""&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;&lt;br /&gt;    &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;en&amp;quot; lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;meta http-equiv=&amp;quot;Content-type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;title&amp;gt;${1:Title}&amp;lt;/title&amp;gt;&lt;br /&gt;    &lt;br /&gt;    ${2:&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;/css/base/base.css&amp;quot; type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot; charset=&amp;quot;utf-8&amp;quot; /&amp;gt;}&lt;br /&gt;    &amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;!--&lt;br /&gt;        body { background-color: #f0f0f0; color: #333; font: 12px &amp;#x27;trebuchet ms&amp;#x27;, sans-serif; }&lt;br /&gt;        h1 { font: 300% &amp;#x27;trebuchet ms&amp;#x27;, verdana; }&lt;br /&gt;        a { color: #3875D7; font-size: 14px; }&lt;br /&gt;        a:hover { color: orange; }&lt;br /&gt;        pre { width: 100%; }&lt;br /&gt;    --&amp;gt;&lt;br /&gt;    &amp;lt;/style&amp;gt;&lt;br /&gt;&lt;br /&gt;    ${3:&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/js/base/base.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;}&lt;br /&gt;    ${4:&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;!--&lt;br /&gt;        $0&lt;br /&gt;    //--&amp;gt;&lt;br /&gt;    &amp;lt;/script&amp;gt;}&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;div id=&amp;quot;doc&amp;quot;&amp;gt;&lt;br /&gt;        &lt;br /&gt;        &amp;lt;div id=&amp;quot;hd&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;h1&amp;gt;$1&amp;lt;/h1&amp;gt;&lt;br /&gt;        &amp;lt;/div&amp;gt;&lt;br /&gt;        &lt;br /&gt;        &amp;lt;div id=&amp;quot;bd&amp;quot;&amp;gt;&lt;br /&gt;            &lt;br /&gt;        &amp;lt;/div&amp;gt;&lt;br /&gt;        &lt;br /&gt;        &amp;lt;div id=&amp;quot;ft&amp;quot;&amp;gt;${5:&lt;br /&gt;            &amp;lt;a href=&amp;quot;http://blog.polyesterhat.com&amp;quot;&amp;gt;Polyesterhat&amp;#x27;s Blog&amp;lt;/a&amp;gt;&lt;br /&gt;        }&amp;lt;/div&amp;gt;&lt;br /&gt;        &lt;br /&gt;    &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I got this idea from &lt;a href="http://www.dustindiaz.com/textmate-page-snippet/"&gt;a post by Dustin Diaz&lt;/a&gt;. The Basic XHTML Strict template is already built into TextMate; that's where I got it.</description><link>http://blog.polyesterhat.com/2008/06/xhtml-10-strict.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-6279010878859096488</guid><pubDate>Tue, 11 Mar 2008 20:13:00 +0000</pubDate><atom:updated>2008-06-04T23:20:38.228-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>hunlock</category><category domain='http://www.blogger.com/atom/ns#'>cross-browser-compliance</category><category domain='http://www.blogger.com/atom/ns#'>css</category><title>CSSStyleRule DOM Object Helpers</title><description>&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;a href="http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript"&gt;"Totally PWN CSS with Javascript"&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I found this article after realizing that &lt;a href="http://extjs.com/deploy/dev/docs/?class=Ext.util.CSS"&gt;EXT-JS's CSS class&lt;/a&gt; really was not what I wanted. There was some problem in the IE's (of course I forget now what it was). I found this guy &lt;a href="http://www.hunlock.com/"&gt;Patrick Hunlock&lt;/a&gt; who writes some awesome code (I would suggest reading the article I linked to, and not stopping there). I like really clean-looking code, sorry Pat; so I cleaned it a bit and minimized it for you all.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Here is the &lt;a href="http://code.polyesterhat.com/js/css/css.object.js"&gt;file&lt;/a&gt;.&lt;br /&gt;Here is the class api:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;var CSS = {&lt;br /&gt;  [CSSStylerule] addCSSRule  : function([selector]),&lt;br /&gt;  [CSSStylerule] getCSSRule  : function([selector]),&lt;br /&gt;  [boolean]      killCSSRule : function([selector])&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, when you say:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;   var pBold = CSS.addCSSRule('p.bold');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;pBold will literally be a CSSStyleRule (as the DOM calls it). Furthermore to modify it:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;   pBold.style.fontWeight = 'bold';&lt;br /&gt;   pBold.style.fontSize = '115%';&lt;br /&gt;&lt;/pre&gt;Hunlock has even more examples on his &lt;a href="http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript"&gt;original post&lt;/a&gt;; I also will urge you to &lt;span style="font-weight: bold;"&gt;Go Forth In Style!&lt;/span&gt;</description><link>http://blog.polyesterhat.com/2008/03/css-rule-object-helpers.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-5001663066912837502</guid><pubDate>Sat, 16 Feb 2008 20:03:00 +0000</pubDate><atom:updated>2008-02-16T12:18:02.817-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>dustin diaz</category><category domain='http://www.blogger.com/atom/ns#'>firebug</category><title>Console dot what?</title><description>By now we have all began to use console.log. Today, I want to remind you that there is more to&lt;a href="http://www.getfirebug.com/"&gt; Firebug's&lt;/a&gt; console function. Here is a &lt;a href="http://www.getfirebug.com/console.html"&gt;list&lt;/a&gt; from the documentation. Joe Hewitt has provided us with a treasure chest of web development goodies; but not everyone has firebug. I like to test my scripts on other browsers in parallel with Firefox, and sometimes my console statements stay in the code. Calling console.log will give a fatal error if console is not found, so put this snippet somewhere in your base javascript file:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/*****************************&lt;br /&gt;*&lt;br /&gt;* window.console fix&lt;br /&gt;*&lt;br /&gt;****************************/&lt;br /&gt;window.console = (typeof console == 'undefined') ? {&lt;br /&gt; log: function(t) { alert(t); },&lt;br /&gt; info: function() { },&lt;br /&gt; debug: function() { }&lt;br /&gt;} : console;&lt;br /&gt;&lt;/pre&gt;From what I have seen, it is the most reliable way to accomplish this. If you use such methods as console.count, simply add that function into my snippet. I got this idea from &lt;a href="http://www.dustindiaz.com/"&gt;dustin diaz&lt;/a&gt; in &lt;a href="http://www.dustindiaz.com/roll-out-your-own-interface/"&gt;this post&lt;/a&gt; in his comment to Felix. He said to use:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;window.console = console || {&lt;br /&gt;   log: function() { },&lt;br /&gt;   info: function() { },&lt;br /&gt;   debug: function() { }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, this does not work, as it tries to access console before his custom object, giving fatal errors in browsers such as IE 6.&lt;br /&gt;&lt;br /&gt;I encourage you to find new ways to let firebug help you, because to become great, you must build on the work of others.</description><link>http://blog.polyesterhat.com/2008/02/console-dot-what.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-3575986203013280836</guid><pubDate>Thu, 14 Feb 2008 00:31:00 +0000</pubDate><atom:updated>2008-02-13T17:36:42.275-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>YUI</category><category domain='http://www.blogger.com/atom/ns#'>closure</category><category domain='http://www.blogger.com/atom/ns#'>design pattern</category><category domain='http://www.blogger.com/atom/ns#'>The Living Web Series</category><title>Exciting Frontend Form Validation</title><description>This is part one in my new series, &lt;span style="font-weight: bold;"&gt;The Living Web: &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;bringing the boring to life&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is my idea. When a user enters information into a contact form, or some other form, (like a survey) if they screw up, I want red arrows to fly down and show them what they messed up on. This will happen every time they hit the submit button until they figure out what the crap they are doing wrong.&lt;br /&gt;&lt;br /&gt;The design pattern:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The form submit button gets hi-jacked by custom validation methods&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Each input is assigned a new red arrow which is hidden from view&lt;/li&gt;&lt;li&gt;User hits submit button&lt;/li&gt;&lt;li&gt;The form submit event is stopped with YAHOO.util.Event.stopEvent(e);&lt;/li&gt;&lt;li&gt;Each input's value is checked against a unique validation method&lt;/li&gt;&lt;li&gt;If they all check out, the form is submitted&lt;/li&gt;&lt;li&gt;If even one input's value is invalid, the red arrow flies down&lt;/li&gt;&lt;li&gt;The input flashes red&lt;/li&gt;&lt;li&gt;A new event is made waiting for focus on the input box&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When the new event is fired, the arrow disappears, we assume user will fix problem&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The arrow is reset&lt;/li&gt;&lt;li&gt;The new event waiting  for focus on that input box must be deleted&lt;/li&gt;&lt;li&gt;The user "fixes" the problem&lt;/li&gt;&lt;li&gt;The user tries submitting the form again&lt;/li&gt;&lt;/ul&gt;This must work unlimited times in a row.&lt;br /&gt;&lt;br /&gt;Here is the code I came up with:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;(function(el) {&lt;br /&gt;&lt;br /&gt;    /* GLOBAL Variables&lt;br /&gt;     * invalid : will be an array of id's of inputs which did not validate&lt;br /&gt;     * form: will contain name of form i.e. document.formName */&lt;br /&gt;    var invalid, form;&lt;br /&gt;    &lt;br /&gt;    /* these are the properties of our red arrow image */&lt;br /&gt;    var arrowImage = {&lt;br /&gt;        'url' : 'images/arrow.png',&lt;br /&gt;        'width' : 66,&lt;br /&gt;        'height' : 28&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* inputs is the set of unique validation methods */&lt;br /&gt;    var inputs = {&lt;br /&gt;        'input_1': {&lt;br /&gt;            'message': 'string',&lt;br /&gt;            'validates': function(value) {&lt;br /&gt;                return (value.length &gt; 0);&lt;br /&gt;            }&lt;br /&gt;        },&lt;br /&gt;&lt;br /&gt;        'input_2': {&lt;br /&gt;            'message': 'string',&lt;br /&gt;            'validates': function(value) {&lt;br /&gt;                return (value.length &gt; 0);&lt;br /&gt;            }&lt;br /&gt;        },&lt;br /&gt;&lt;br /&gt;        'input_3': {&lt;br /&gt;            'message': 'must be an email address',&lt;br /&gt;            'validates': function(value) {&lt;br /&gt;                /* taken from http://www.quirksmode.org/js/mailcheck.html, thankyou! */&lt;br /&gt;                var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;&lt;br /&gt;                return filter.test(value);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    var validateForm = function(e) {&lt;br /&gt;        &lt;br /&gt;        /* we can't have the form submitting yet */&lt;br /&gt;        Event.stopEvent(e);&lt;br /&gt;&lt;br /&gt;        /* reset this array, because each time the&lt;br /&gt;         * user clicks submit, we assume there is&lt;br /&gt;         * nothing wrong */&lt;br /&gt;        invalid = [];&lt;br /&gt;        &lt;br /&gt;        for(var i in inputs) {&lt;br /&gt;            /* save a reference to actual html element */&lt;br /&gt;            inputs[i]['el'] = $(i);&lt;br /&gt;            &lt;br /&gt;            /* clearly, this is the value of the curent input */&lt;br /&gt;            var value = inputs[i]['el']['value'];&lt;br /&gt;            &lt;br /&gt;            /* this is where we test each input's value with that&lt;br /&gt;             * input's specific validation method */&lt;br /&gt;            if(!inputs[i]['validates'](value)) {&lt;br /&gt;                invalid.push(i);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        /* if invalid is empty&lt;br /&gt;         * i.e. it's length is 0,&lt;br /&gt;         * there was nothing wrong,&lt;br /&gt;         * meaning form can be submitted */&lt;br /&gt;        if(invalid.length &gt; 0) {&lt;br /&gt;            &lt;br /&gt;            /* announce is another word meaning&lt;br /&gt;             * red arrows will fly down */&lt;br /&gt;            announceErrors();&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;            /* we got the form name in the&lt;br /&gt;             * Event.onAvailable callback earlier (below),&lt;br /&gt;             * so submit the form */&lt;br /&gt;            document.eval(form).submit();&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    var announceErrors = function() {&lt;br /&gt;        for(var i = 0; i &lt; invalid.length; i++) {&lt;br /&gt;    &lt;br /&gt;            /* get the id of the input which has the invalid value */&lt;br /&gt;            var input = inputs[invalid[i]];&lt;br /&gt;            var region = Dom.getRegion(input['el']);&lt;br /&gt;            &lt;br /&gt;            /* begin to show the arrow to the user */&lt;br /&gt;            Dom.setStyle(input['arrow'], 'visibility', 'visible');&lt;br /&gt;    &lt;br /&gt;            /* use math to figure out where the arrow should go */&lt;br /&gt;            var slideArrow = new Anim(input['arrow'], {&lt;br /&gt;                'top' : { 'to' : region['top'] - (arrowImage['height'] * 3/4)},&lt;br /&gt;                'left' : { 'to' : region['left'] - arrowImage['width']}&lt;br /&gt;            }, 0.25, YAHOO.util.Easing.bounceOut);&lt;br /&gt;    &lt;br /&gt;            /* when the arrow stops sliding, the input box should flash red */&lt;br /&gt;            slideArrow.onComplete.subscribe(flashInputs, i);&lt;br /&gt;            slideArrow.animate();&lt;br /&gt;    &lt;br /&gt;            /* here is where we make the new&lt;br /&gt;             * event to wait for user's focus&lt;br /&gt;             * please study what is happening here&lt;br /&gt;             * we are saying, when the html element gets focus,&lt;br /&gt;             * call fadeArrow, because the arrow should go away not, &lt;br /&gt;             * because we assume the user will fix the issue&lt;br /&gt;             * Then we say, when you call fadeArrow, give it some stuff&lt;br /&gt;             * give it an object with two things,&lt;br /&gt;             * 1) the html element itself&lt;br /&gt;             *    (so we can remove it's focus listener)&lt;br /&gt;             * 2) give it the arrow element&lt;br /&gt;             * then the true signifies that that object&lt;br /&gt;             * with the two things should be the scope of&lt;br /&gt;             * fadeArrow, in other words, when fadeArrow gets&lt;br /&gt;             * called, this['arrow'] will be same as saying,&lt;br /&gt;             * input['arrow'] here, whew */&lt;br /&gt;            Event.on(input['el'], 'focus', fadeArrow, {&lt;br /&gt;                'obj': input['el'],&lt;br /&gt;                'arrow': input['arrow']&lt;br /&gt;            }, true);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    var flashInputs = function(e, o, i) {&lt;br /&gt;        &lt;br /&gt;        /* we allow e,o, and i,&lt;br /&gt;         * only because we need to use i,&lt;br /&gt;         * can you figure out why we did not want&lt;br /&gt;         * i to be the scope aka, 'this' ? */&lt;br /&gt;        var id = invalid[i];&lt;br /&gt;        &lt;br /&gt;        var red = new ColorAnim(inputs[id]['el'], {&lt;br /&gt;            'backgroundColor': { 'to' : '#B91309' },&lt;br /&gt;            'color' : {'to' : '#FFF'}&lt;br /&gt;        }, 0.2);&lt;br /&gt;        &lt;br /&gt;        red.onComplete.subscribe(function() {&lt;br /&gt;            var white = new ColorAnim(inputs[id]['el'], {&lt;br /&gt;                'backgroundColor': { 'to' : '#FFF' },&lt;br /&gt;                'color' : {'to' : '#000'}&lt;br /&gt;            }, 0.2);&lt;br /&gt;            white.animate();&lt;br /&gt;        });&lt;br /&gt;        red.animate();&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;    var fadeArrow = function() {&lt;br /&gt;        &lt;br /&gt;        /* input box has recieved focus,&lt;br /&gt;         * recall that 'this' refers to&lt;br /&gt;         * the object with 'obj' and 'arrow'&lt;br /&gt;         * remove that listener */&lt;br /&gt;        Event.removeListener(this['obj'], 'focus', fadeArrow);&lt;br /&gt;        &lt;br /&gt;        var fadeOut = new Anim(this['arrow'], {&lt;br /&gt;            'opacity' : { 'to' : 0 }&lt;br /&gt;        }, 0.5);&lt;br /&gt;        &lt;br /&gt;        fadeOut.onComplete.subscribe(resetArrow, this['arrow'], true);&lt;br /&gt;        fadeOut.animate();&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    var resetArrow = function() {&lt;br /&gt;        setStyles(this, {&lt;br /&gt;            'top' : '0px',&lt;br /&gt;            'left': '0px',&lt;br /&gt;            'visibility': 'hidden',&lt;br /&gt;            'opacity' : 1&lt;br /&gt;        });&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    var setStyles = function(el, styles) {&lt;br /&gt;        for(var s in styles) {&lt;br /&gt;            Dom.setStyle(el, s, styles[s]);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    /* basically the constructor */&lt;br /&gt;    Event.onAvailable(el, function() {&lt;br /&gt;&lt;br /&gt;        for(var i in inputs) {&lt;br /&gt;            /* give each input its own arrow element */&lt;br /&gt;            var arrow = document.createElement('div');&lt;br /&gt;            $('doc').appendChild(arrow);&lt;br /&gt;            Dom.addClass(arrow, 'arrow');&lt;br /&gt;            setStyles(arrow, {&lt;br /&gt;                'width': arrowImage['width'] + 'px',&lt;br /&gt;                'height': arrowImage['height'] + 'px',&lt;br /&gt;                'backgroundImage' : 'url(\''+ arrowImage['url'] +'\')'&lt;br /&gt;            });&lt;br /&gt;            inputs[i]['arrow'] = arrow;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /* note that el is html element id (a string)&lt;br /&gt;         * of the submit button, but we temporarily&lt;br /&gt;         * reference it with form, this save a tiny bit&lt;br /&gt;         * of processing time */&lt;br /&gt;        form = $(el);&lt;br /&gt;        Event.on(form, 'click', validateForm);&lt;br /&gt;        &lt;br /&gt;        /* bubble up the dom tree to find the html form element&lt;br /&gt;         * starting at the submit button */&lt;br /&gt;        while(form.tagName.toUpperCase() != 'FORM') {&lt;br /&gt;            form = form.parentNode;&lt;br /&gt;        }&lt;br /&gt;        /* get name of form */&lt;br /&gt;        form = form['name'];&lt;br /&gt;    });&lt;br /&gt;/* this anonymous function self-invokes itself, and gives itself a string&lt;br /&gt; * this string becomes el, which is the html element id of the submit button */&lt;br /&gt;}('submit_button'))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://code.polyesterhat.com/examples/Exciting_Form_Validator"&gt;working example&lt;/a&gt;. My questions for you:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Why is the whole thing an anonymous function?&lt;/li&gt;&lt;li&gt;If it were not anonymous, what public properties or methods could it offer for interaction with other javascript classes?&lt;/li&gt;&lt;li&gt;What css rules would need to be applied to the arrow, for the class div.arrow?&lt;/li&gt;&lt;li&gt;Do you like the way I got the name of the form in order to call the submit() method, is there a better way?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;How could the code be modified to enable multiple forms?&lt;/li&gt;&lt;li&gt;How could the code be modified to allow abstracted validation methods?&lt;/li&gt;&lt;li&gt;What would you have done differently?&lt;/li&gt;&lt;/ol&gt;Feel free to leave comments answering any or all of my questions for you. Also, if you want, I can explain more of a certain part for you, no matter who you are.&lt;br /&gt;&lt;br /&gt;Thank you!</description><link>http://blog.polyesterhat.com/2008/02/exciting-frontend-form-validation.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-7331147889615965529</guid><pubDate>Wed, 13 Feb 2008 23:12:00 +0000</pubDate><atom:updated>2008-02-13T17:11:30.928-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>YUI</category><category domain='http://www.blogger.com/atom/ns#'>closure</category><category domain='http://www.blogger.com/atom/ns#'>snippets</category><category domain='http://www.blogger.com/atom/ns#'>singleton</category><category domain='http://www.blogger.com/atom/ns#'>self invoke</category><title>SetStyles</title><description>Among my favorite snippets: setStyles(). Say we have an html div element, and you have the urge to make it fill up the entire width and height of the screen using only YUI's dom class.  Meet setStyles(), use it on your html element to modify more than one of its' styles at once.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;var setStyles = function(el, styles) {&lt;br /&gt;    for(var s in styles) {&lt;br /&gt;        YAHOO.util.Dom.setStyle(el, s, styles[s]);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, in practice, if we have a loading icon from &lt;a href="http://ajaxload.info/"&gt;http://ajaxload.info/&lt;/a&gt;:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;setStyles('some_id', {&lt;br /&gt;    'top' : '0px',&lt;br /&gt;    'left': '0px',&lt;br /&gt;    'position' : 'absolute',&lt;br /&gt;    'zIndex' : 100, /* make sure it is on top of everything */&lt;br /&gt;    'width' : YAHOO.util.Dom.getViewportWidth() + 'px',&lt;br /&gt;    'height' : YAHOO.util.Dom.getViewportHeight() + 'px',&lt;br /&gt;    'backgroundImage' : 'url("images/loader.gif")',&lt;br /&gt;    'backgroundPosition' : 'center center',&lt;br /&gt;    'backgroundRepeat' : 'no-repeat',&lt;br /&gt;    'backgroundColor' : '#000'&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;Here is a &lt;a href="http://code.polyesterhat.com/examples/SetStyles/"&gt;working example&lt;/a&gt;. There you have it. Wonderful</description><link>http://blog.polyesterhat.com/2008/02/setstyles.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-5364372692248879767</guid><pubDate>Sat, 08 Dec 2007 18:33:00 +0000</pubDate><atom:updated>2007-12-08T10:47:00.933-08:00</atom:updated><title>Cheating at life!</title><description>I found some amazing websites this afternoon, via stumble upon.&lt;br /&gt;&lt;br /&gt;The first is the one which prompted me to post,&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.edocr.com/tags/cheat-sheet"&gt;cheat sheets&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.forwebdesigners.com/"&gt;list of helpful web 2 stuff&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.welie.com/patterns/index.php"&gt;design patterns&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cos.ucf.edu/buildings/physicalSciences"&gt;&lt;/a&gt;</description><link>http://blog.polyesterhat.com/2007/12/cheating-at-life.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-3806489361904776627</guid><pubDate>Thu, 18 Oct 2007 05:12:00 +0000</pubDate><atom:updated>2007-10-30T14:02:23.240-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>YUI</category><category domain='http://www.blogger.com/atom/ns#'>closure</category><category domain='http://www.blogger.com/atom/ns#'>yui anywhere</category><category domain='http://www.blogger.com/atom/ns#'>self invoke</category><title>Portable Image Viewer</title><description>Like I said, I planned to work on some fun applications of the YUI Anywhere idea.&lt;br /&gt;&lt;br /&gt;I sat down after school for a minute and decided it would be cool to be able to click a button on my bookmarks bar which would give me a slideshow of all the images on any  web page. Then I discovered the &lt;a href="http://developer.yahoo.com/yui/yuiloader/"&gt;yui-loader&lt;/a&gt;, which is designed to load the other yui modules, such as the animation utility. The yui-loader is still in beta phase, but it works fine in Firefox.&lt;br /&gt;&lt;br /&gt;Here is what I came up with: (&lt;a href="http://code.walkerstyle.ws/examples/Portable_Image_Viewer/imageViewerTest.html"&gt;working example&lt;/a&gt;)&lt;pre class="prettyprint"&gt;&lt;br /&gt;var DW = (typeof DW == 'undefined') ? {} : DW;&lt;br /&gt;&lt;br /&gt;/* When someone clicks the bookmark, if the class is already defined, it will display the viewer */&lt;br /&gt;if(typeof DW.imageViewer != 'undefined') {&lt;br /&gt;    DW.imageViewer.show();&lt;br /&gt;} else {&lt;br /&gt;    DW.imageViewer = function() {&lt;br /&gt;        &lt;br /&gt;        var Event;&lt;br /&gt;        var Anim;&lt;br /&gt;        var Dom;&lt;br /&gt;        var Overlay;&lt;br /&gt;        &lt;br /&gt;        var _item;&lt;br /&gt;        var _image;&lt;br /&gt;        var _src;&lt;br /&gt;        var _current;&lt;br /&gt;        var _imageViewer;&lt;br /&gt;        &lt;br /&gt;        var init = function() {&lt;br /&gt;            Event = YAHOO.util.Event;&lt;br /&gt;            Anim = YAHOO.util.Anim;&lt;br /&gt;            Dom = YAHOO.util.Dom;&lt;br /&gt;            Overlay = YAHOO.widget.Overlay;&lt;br /&gt;&lt;br /&gt;            _src = Dom.batch(_item, function(o){&lt;br /&gt;                return o.src;&lt;br /&gt;            });&lt;br /&gt;&lt;br /&gt;            _current = 0;&lt;br /&gt;&lt;br /&gt;            _imageViewer = new Overlay('imageViewer', {&lt;br /&gt;                effect: {effect:YAHOO.widget.ContainerEffect.FADE,duration:0.30},&lt;br /&gt;                zIndex: 90,&lt;br /&gt;                width: Dom.getViewportWidth() + 'px',&lt;br /&gt;                height: Dom.getDocumentHeight() + 'px',&lt;br /&gt;                visible: false,&lt;br /&gt;                x: 0,&lt;br /&gt;                y: 0&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            setUpHeader();&lt;br /&gt;            setUpBody();&lt;br /&gt;            &lt;br /&gt;            _imageViewer.render(document.body);&lt;br /&gt;            &lt;br /&gt;            setStyles('imageHolder', {&lt;br /&gt;                'width': '100%',&lt;br /&gt;                'textAlign': 'center',&lt;br /&gt;                'marginTop': '10px'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            setStyles(_image, {&lt;br /&gt;                'padding': '5px',&lt;br /&gt;                'border': '1px solid #7E7E7E'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            setStyles('imageViewer', {&lt;br /&gt;                'textAlign': 'center',&lt;br /&gt;                'backgroundColor': '#000'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            Event.on(_image, 'click', linked);&lt;br /&gt;            Event.on(_image, 'mouseover', checkLinked);&lt;br /&gt;            &lt;br /&gt;            setUpButtons();&lt;br /&gt;            putCurrentImage();&lt;br /&gt;            show();&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var setUpHeader = function() {&lt;br /&gt;            &lt;br /&gt;            var closeButton = newEl({&lt;br /&gt;                'el': 'input',&lt;br /&gt;                'id': 'closeButton',&lt;br /&gt;                'type': 'button',&lt;br /&gt;                'value': 'close'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            _imageViewer.appendToHeader(closeButton);&lt;br /&gt;            &lt;br /&gt;            var headerButtons = newEl({&lt;br /&gt;                'el': 'div',&lt;br /&gt;                'id': 'headerButtons'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            var prevButton = newEl({&lt;br /&gt;                'el': 'input',&lt;br /&gt;                'type': 'button',&lt;br /&gt;                'value': 'previous',&lt;br /&gt;                'id': 'previousButton'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            var nextButton = newEl({&lt;br /&gt;                'el': 'input',&lt;br /&gt;                'type': 'button',&lt;br /&gt;                'value': 'next',&lt;br /&gt;                'id': 'nextButton'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            headerButtons.appendChild(prevButton);&lt;br /&gt;            headerButtons.appendChild(nextButton);&lt;br /&gt;            &lt;br /&gt;            _imageViewer.appendToHeader(headerButtons);&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var setUpBody = function() {&lt;br /&gt;            var imageHolder = newEl({&lt;br /&gt;                'el': 'div',&lt;br /&gt;                'id': 'imageHolder'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            _image = newEl({&lt;br /&gt;                'el': 'img',&lt;br /&gt;                'id': 'currentImage',&lt;br /&gt;                'src': _src[0]&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            imageHolder.appendChild(_image);&lt;br /&gt;            &lt;br /&gt;            _imageViewer.appendToBody(imageHolder);&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var newEl = function(attrs) {&lt;br /&gt;            var el = document.createElement(attrs.el);&lt;br /&gt;            for(var i in attrs) {&lt;br /&gt;                el[i] = attrs[i];&lt;br /&gt;            };&lt;br /&gt;            return el;&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var setStyles = function(el, style) {&lt;br /&gt;            for(var i in style) {&lt;br /&gt;                Dom.setStyle(el, i, style[i]);&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var setUpButtons = function() {&lt;br /&gt;            var b = ['previousButton', 'nextButton', 'closeButton'];&lt;br /&gt;            Event.on(b[0], 'click', changeImage, {delta: -1});&lt;br /&gt;            Event.on(b[1], 'click', changeImage, {delta: 1});&lt;br /&gt;            Event.on(b[2], 'click', hide);&lt;br /&gt;            &lt;br /&gt;            setStyles(b[2], {&lt;br /&gt;                'position': 'absolute',&lt;br /&gt;                'top': '10px',&lt;br /&gt;                'left': '10px'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            setStyles('headerButtons', {&lt;br /&gt;                'marginTop': '10px'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            setStyles(b, {&lt;br /&gt;                'color': '#2C2C2C',&lt;br /&gt;                'border': '1px solid #2C2C2C',&lt;br /&gt;                'backgroundColor': '#000',&lt;br /&gt;                'padding': '5px',&lt;br /&gt;                'margin': '5px'&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            Event.on(b, 'mouseover', function() {&lt;br /&gt;                Dom.setStyle(b, 'color', '#FFF');&lt;br /&gt;                Dom.setStyle(b, 'border', '1px solid #FFF');&lt;br /&gt;            });&lt;br /&gt;&lt;br /&gt;            Event.on(b, 'mouseout', function() {&lt;br /&gt;                Dom.setStyle(b, 'color', '#2C2C2C');&lt;br /&gt;                Dom.setStyle(b, 'border', '1px solid #2C2C2C');&lt;br /&gt;            });&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var changeImage = function(e, o) {&lt;br /&gt;            _current += o.delta;&lt;br /&gt;&lt;br /&gt;            if(_current &lt; 0) {&lt;br /&gt;                _current = (_src.length - 1);&lt;br /&gt;            }&lt;br /&gt;            else if(_current &gt; (_src.length - 1)) {&lt;br /&gt;                _current = 0;&lt;br /&gt;            }&lt;br /&gt;            putCurrentImage();&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var putCurrentImage = function() {&lt;br /&gt;            var fadeOut = new Anim(_image, {&lt;br /&gt;                opacity: { to: 0 }&lt;br /&gt;            }, 0.25, YAHOO.util.Easing.easeOut);&lt;br /&gt;            fadeOut.onComplete.subscribe(putCurrentImageHelper);&lt;br /&gt;            fadeOut.animate();&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var putCurrentImageHelper = function() {&lt;br /&gt;            _image.src = _src[_current];&lt;br /&gt;&lt;br /&gt;            var fadeIn = new Anim(_image, {&lt;br /&gt;                opacity: { to: 1 }&lt;br /&gt;            }, 0.25, YAHOO.util.Easing.easeOut);&lt;br /&gt;&lt;br /&gt;            fadeIn.animate();&lt;br /&gt;        };&lt;br /&gt;        &lt;br /&gt;        var flashBack = function() {&lt;br /&gt;            var flashBack = new YAHOO.util.ColorAnim(_image, {&lt;br /&gt;                backgroundColor: { to: '#000'}&lt;br /&gt;            }, 0.30);&lt;br /&gt;            flashBack.animate();&lt;br /&gt;        };&lt;br /&gt;        &lt;br /&gt;        var getPar = function() {&lt;br /&gt;            return Dom.getAncestorByTagName(_item[_current], 'A');&lt;br /&gt;        };&lt;br /&gt;        &lt;br /&gt;        var checkLinked = function() {&lt;br /&gt;            var found = false;&lt;br /&gt;            var par = getPar();&lt;br /&gt;            if(par !== null) {&lt;br /&gt;                for(var i = 0; i &lt; extensionTest.length; i++) {&lt;br /&gt;                    if(extensionTest[i].test(par.href)) {&lt;br /&gt;                        found = true;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                if(!found) {&lt;br /&gt;                    /* yellow */&lt;br /&gt;                    var flashYellow = new YAHOO.util.ColorAnim(_image, {&lt;br /&gt;                        backgroundColor: { to: '#FAEB31'}&lt;br /&gt;                    }, 0.30);&lt;br /&gt;                    flashYellow.onComplete.subscribe(flashBack);&lt;br /&gt;                    flashYellow.animate();&lt;br /&gt;                }&lt;br /&gt;                else {&lt;br /&gt;                    /* green */&lt;br /&gt;                    var flashGreen = new YAHOO.util.ColorAnim(_image, {&lt;br /&gt;                        backgroundColor: { to: '#54A14E'}&lt;br /&gt;                    }, 0.30);&lt;br /&gt;                    flashGreen.onComplete.subscribe(flashBack);&lt;br /&gt;                    flashGreen.animate();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            else {&lt;br /&gt;                /* blue */&lt;br /&gt;                var flashBlue = new YAHOO.util.ColorAnim(_image, {&lt;br /&gt;                    backgroundColor: { to: '#06e'}&lt;br /&gt;                }, 0.30);&lt;br /&gt;                flashBlue.onComplete.subscribe(flashBack);&lt;br /&gt;                flashBlue.animate();&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;        &lt;br /&gt;        var extensionTest = [new RegExp('.jpg$', 'i'), new RegExp('.gif$', 'i'), new RegExp('.png$', 'i'), new RegExp('.jpeg$', 'i')];&lt;br /&gt;        &lt;br /&gt;        var linked = function() {&lt;br /&gt;            var found = false;&lt;br /&gt;            var par = getPar();&lt;br /&gt;            if(par !== null) {&lt;br /&gt;                for(var i = 0; i &lt; extensionTest.length; i++) {&lt;br /&gt;                    if(extensionTest[i].test(par.href)) {&lt;br /&gt;                        found = true;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                if(!found) {&lt;br /&gt;                    window.location = par.href;&lt;br /&gt;                }&lt;br /&gt;                else {&lt;br /&gt;                    _image.src = par.href;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            else {&lt;br /&gt;                /* blue */&lt;br /&gt;                var flashBlue = new YAHOO.util.ColorAnim(_image, {&lt;br /&gt;                    backgroundColor: { to: '#06e'}&lt;br /&gt;                }, 0.30);&lt;br /&gt;                flashBlue.onComplete.subscribe(flashBack);&lt;br /&gt;                flashBlue.animate();&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var stripPx = function(str) {&lt;br /&gt;            return parseInt(str.substring(0, str.indexOf('p')));&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        /* resizeImage is not used */&lt;br /&gt;        var resizeImage = function(ratio) {&lt;br /&gt;            var w = stripPx(Dom.getStyle(_item[_current], 'width')) * ratio;&lt;br /&gt;            var h = stripPx(Dom.getStyle(_item[_current], 'height')) * ratio;&lt;br /&gt;            Dom.setStyle(_item[_current], 'width', w + 'px');&lt;br /&gt;            Dom.setStyle(_item[_current], 'height', h + 'px');&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var show = function() {&lt;br /&gt;            Dom.setStyle('imageViewer', 'display', '');&lt;br /&gt;            _imageViewer.show();&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var hide = function() {&lt;br /&gt;            Dom.setStyle('imageViewer', 'display', 'none');&lt;br /&gt;            _imageViewer.hide();&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var loaded = function() {&lt;br /&gt;            _item = YAHOO.util.Dom.getElementsBy(function(){return true;},'img');&lt;br /&gt;            if(_item.length !== 0) {&lt;br /&gt;                init();&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        return function() {&lt;br /&gt;            loader = new YAHOO.util.YUILoader();&lt;br /&gt;            loader.require('animation', 'container');&lt;br /&gt;            loader.loadOptional = true;&lt;br /&gt;            loader.insert(loaded);&lt;br /&gt;            &lt;br /&gt;            return {&lt;br /&gt;                show : show,&lt;br /&gt;                hide : hide&lt;br /&gt;            };&lt;br /&gt;        }();&lt;br /&gt;    }();&lt;br /&gt;}&lt;/pre&gt;Don't let me hog all the fun! Just drag these links to your bookmarks bar, or make a bookmarks group for "YUI Anywhere"; that may be a wise approach, because I feel that these types of things are going to get very popular.&lt;br /&gt;&lt;br /&gt;&lt;a href="javascript:(function(){var s = document.createElement('script');s.src='http://yui.yahooapis.com/2.3.1/build/yuiloader/yuiloader-beta-min.js';document.getElementsByTagName('head')[0].appendChild(s);})()"&gt;YUI Loader&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="javascript:(function(){var DW=(typeof DW=='undefined')?{}:DW;if(typeof DW.imageViewer!='undefined'){DW.imageViewer.show()}else{DW.imageViewer=function(){var f;var g;var j;var k;var l;var m;var n;var p;var q;var r=function(){f=YAHOO.util.Event;g=YAHOO.util.Anim;j=YAHOO.util.Dom;k=YAHOO.widget.Overlay;n=j.batch(l,function(o){return o.src});p=0;q=new k('imageViewer',{effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.30},zIndex:90,width:j.getViewportWidth()+'px',height:j.getDocumentHeight()+'px',visible:false,x:0,y:0});s();t();q.render(document.body);v('imageHolder',{'width':'100%','textAlign':'center','marginTop':'10px'});v(m,{'padding':'5px','border':'1px solid #7E7E7E'});v('imageViewer',{'textAlign':'center','backgroundColor':'#000'});f.on(m,'click',F);f.on(m,'mouseover',D);x();z();I()};var s=function(){var a=u({'el':'input','id':'closeButton','type':'button','value':'close'});q.appendToHeader(a);var b=u({'el':'div','id':'headerButtons'});var c=u({'el':'input','type':'button','value':'previous','id':'previousButton'});var d=u({'el':'input','type':'button','value':'next','id':'nextButton'});b.appendChild(c);b.appendChild(d);q.appendToHeader(b)};var t=function(){var a=u({'el':'div','id':'imageHolder'});m=u({'el':'img','id':'currentImage','src':n[0]});a.appendChild(m);q.appendToBody(a)};var u=function(a){var b=document.createElement(a.el);for(var i in a){b[i]=a[i]};return b};var v=function(a,b){for(var i in b){j.setStyle(a,i,b[i])}};var x=function(){var b=['previousButton','nextButton','closeButton'];f.on(b[0],'click',y,{delta:-1});f.on(b[1],'click',y,{delta:1});f.on(b[2],'click',J);v(b[2],{'position':'absolute','top':'10px','left':'10px'});v('headerButtons',{'marginTop':'10px'});v(b,{'color':'#2C2C2C','border':'1px solid #2C2C2C','backgroundColor':'#000','padding':'5px','margin':'5px'});f.on(b,'mouseover',function(){j.setStyle(b,'color','#FFF');j.setStyle(b,'border','1px solid #FFF')});f.on(b,'mouseout',function(){j.setStyle(b,'color','#2C2C2C');j.setStyle(b,'border','1px solid #2C2C2C')})};var y=function(e,o){p+=o.delta;if(p&lt;0){p=(n.length-1)}else if(p&gt;(n.length-1)){p=0}z()};var z=function(){var a=new g(m,{opacity:{to:0}},0.25,YAHOO.util.Easing.easeOut);a.onComplete.subscribe(A);a.animate()};var A=function(){m.src=n[p];var a=new g(m,{opacity:{to:1}},0.25,YAHOO.util.Easing.easeOut);a.animate()};var B=function(){var a=new YAHOO.util.ColorAnim(m,{backgroundColor:{to:'#000'}},0.30);a.animate()};var C=function(){return j.getAncestorByTagName(l[p],'A')};var D=function(){var a=false;var b=C();if(b!==null){for(var i=0;i&lt;E.length;i++){if(E[i].test(b.href)){a=true}}if(!a){var c=new YAHOO.util.ColorAnim(m,{backgroundColor:{to:'#FAEB31'}},0.30);c.onComplete.subscribe(B);c.animate()}else{var d=new YAHOO.util.ColorAnim(m,{backgroundColor:{to:'#54A14E'}},0.30);d.onComplete.subscribe(B);d.animate()}}else{var e=new YAHOO.util.ColorAnim(m,{backgroundColor:{to:'#06e'}},0.30);e.onComplete.subscribe(B);e.animate()}};var E=[new RegExp('.jpg$','i'),new RegExp('.gif$','i'),new RegExp('.png$','i'),new RegExp('.jpeg$','i')];var F=function(){var a=false;var b=C();if(b!==null){for(var i=0;i&lt;E.length;i++){if(E[i].test(b.href)){a=true}}if(!a){window.location=b.href}else{m.src=b.href}}else{var c=new YAHOO.util.ColorAnim(m,{backgroundColor:{to:'#06e'}},0.30);c.onComplete.subscribe(B);c.animate()}};var G=function(a){return parseInt(a.substring(0,a.indexOf('p')))};var H=function(a){var w=G(j.getStyle(l[p],'width'))*a;var h=G(j.getStyle(l[p],'height'))*a;j.setStyle(l[p],'width',w+'px');j.setStyle(l[p],'height',h+'px')};var I=function(){j.setStyle('imageViewer','display','');q.show()};var J=function(){j.setStyle('imageViewer','display','none');q.hide()};var K=function(){l=YAHOO.util.Dom.getElementsBy(function(){return true},'img');if(l.length!==0){r()}};return function(){loader=new YAHOO.util.YUILoader();loader.require('animation','container');loader.loadOptional=true;loader.insert(K);return{show:I,hide:J}}()}()}})();"&gt;DW.imageViewer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a direct link to the &lt;a href="http://code.walkerstyle.ws/examples/Portable_Image_Viewer/imageViewer.html"&gt;bookmark page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Originally I wanted to only have to click one button, but it turned out to be complicated. Plus, the two buttons provide greater extendability. The first button prepares the loader to load in the scripts that other modules will need. Then, the DW.imageViewer button will simply load itself, nothing more.&lt;br /&gt;&lt;br /&gt;In the code, you may notice that all quotes are single quotes or escaped single quotes, this was for when I minified it to make it a link.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;DW.imageViewer :&lt;br /&gt;&lt;span style="font-size:100%;"&gt;I thought I would list some features:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;It sets the mood by fading in a dark screen.&lt;/li&gt;&lt;li&gt;If there are no images on the page, it bluntly does nothing, bluntly.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It allows you next/previous your way through each image on the screen.&lt;/li&gt;&lt;li&gt;When you hover the mouse over the image it will flash one of three colors:&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Green, the image was inside of a link&lt;/li&gt;&lt;li&gt;Clicking a green flashing image will load the linked image into the viewer&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Yellow: The image links to an external page&lt;/li&gt;&lt;li&gt;Clicking a yellow flashing image will go to that page&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Blue: When there is no link, the image will flash blue&lt;/li&gt;&lt;li&gt;To close the viewer, click close in the top left&lt;/li&gt;&lt;li&gt;To reopen it, click the bookmark again.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There you have it.</description><link>http://blog.polyesterhat.com/2007/10/portable-image-viewer.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-1553307518887657992</guid><pubDate>Mon, 15 Oct 2007 14:33:00 +0000</pubDate><atom:updated>2007-10-16T23:32:28.021-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>YUI</category><category domain='http://www.blogger.com/atom/ns#'>singleton</category><category domain='http://www.blogger.com/atom/ns#'>self invoke</category><title>YUI Anywhere</title><description>This is among the coolest items I have lately seen. My buddy &lt;a href="http://www.lovemikeg.com/blog/"&gt;Mike G.&lt;/a&gt; showed it to me, and it was originally posted on &lt;a href="http://www.phpied.com/category/yui/"&gt;phpied.com&lt;/a&gt;. Now, you can bring your web2 tool kit with you everywhere.&lt;br /&gt;&lt;pre class="prettyprint"&gt;(function(){&lt;br /&gt;var yui = document.createElement('script');&lt;br /&gt;yui.src='http://yui.yahooapis.com/2.3.1/build/utilities/utilities.js';&lt;br /&gt;yui.type='text/javascript';&lt;br /&gt;document.getElementsByTagName('head')[0].appendChild(yui);&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Drag this to your bookmarks bar: &lt;a class="buttonLink" href="javascript:(function(){var yui=document.createElement('script');yui.src='http://yui.yahooapis.com/2.3.1/build/utilities/utilities.js';yui.type='text/javascript';document.getElementsByTagName('head')[0].appendChild(yui);})()"&gt;YUI Anywhere&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The question is... what can we do with this?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The famous example: Make everything draggable:&lt;br /&gt;&lt;pre class="prettyprint"&gt;var all = document.getElementsByTagName('*');&lt;br /&gt;&lt;br /&gt;for(var i = 0; i &lt; all.length; i++) {&lt;br /&gt;    new YAHOO.util.DD(all[i]);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The point is to run this code in &lt;a href="http://www.getfirebug.com/"&gt;firebug&lt;/a&gt; after clicking your new YUI Anywhere button.&lt;br /&gt;&lt;br /&gt;I am currently working on a fun example of what can be done with YUI Anywhere.</description><link>http://blog.polyesterhat.com/2007/10/yui-anywhere.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3844503025396284551.post-9126156216148723267</guid><pubDate>Mon, 15 Oct 2007 03:57:00 +0000</pubDate><atom:updated>2008-02-16T15:33:10.482-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>dustin diaz</category><category domain='http://www.blogger.com/atom/ns#'>YUI</category><category domain='http://www.blogger.com/atom/ns#'>closure</category><category domain='http://www.blogger.com/atom/ns#'>crockford</category><category domain='http://www.blogger.com/atom/ns#'>interface</category><category domain='http://www.blogger.com/atom/ns#'>singleton</category><category domain='http://www.blogger.com/atom/ns#'>self invoke</category><category domain='http://www.blogger.com/atom/ns#'>instance</category><title>My Singleton Instance Dom Hijacker</title><description>&lt;pre class="prettyprint"&gt;var DomHijacker = function(el) {&lt;br /&gt;&lt;br /&gt; var init = function() {&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; return function() {&lt;br /&gt;&lt;br /&gt;     Event.onAvailable(el, init);&lt;br /&gt;&lt;br /&gt;     return {&lt;br /&gt;&lt;br /&gt;         /* public functions here */&lt;br /&gt;&lt;br /&gt;     };&lt;br /&gt;&lt;br /&gt; }();&lt;br /&gt;&lt;br /&gt;}('htmlElementId');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is so special about this? &lt;/span&gt;After all, it looks just like what we are all used to. It uses &lt;span style="font-style: italic;"&gt;closure&lt;/span&gt;, it uses &lt;span style="font-style: italic;"&gt;self invoking functions&lt;/span&gt;, and like everything else, it uses the &lt;span style="font-style: italic;"&gt;YUI&lt;/span&gt;. The only new and cool thing about it is that it is completely self contained. It calls its own init function. Note: A full example of this function is posted &lt;a href="http://code.polyesterhat.com/examples/My_Singleton_Instance_Dom_Hijacker/customList.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The point of the whole thing is that the function will only begin to modify DOM elements after they are ready. Allow me to explain each line:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var DomHijacker = function(el) {&lt;br /&gt;&lt;/pre&gt;This line simply declares a variable DomHijacker, which will be a function. It takes one parameter, a string called el (element) which is the id of a Dom element on the page.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var init = function() {&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Within DomHijacker, there is an init function. Init stands for initialize, because this function will run procedures on the Dom element with the id 'el'&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;return function(){&lt;br /&gt;&lt;/pre&gt;The function, or 'class' in this case called DomHijacker will return a function. This is called closure. Any objects that are not in this returned function will not be given back so to speak. For instance, you could not try DomHijacker.init() somewhere else. Now, DomHijacker is actually this anonymous function. This function will not be called until someone says DomHijacker(); it will simply be stored in DomHijacker, but not invoked.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;Event.onAvailable(el, init);&lt;br /&gt;&lt;/pre&gt;We will use YUI's event utility to wait for our html element with the id 'el'. You can see how onAvailable works &lt;a href="http://developer.yahoo.com/yui/docs/YAHOO.util.Event.html#onAvailable"&gt;here&lt;/a&gt;. When our html element is ready, the init function will be called. Although I do not use it, it is important to note that the keyword 'this' will refer to the Dom element with id 'el' within init after YAHOO.util.Event.onAvailable calls it.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;return {&lt;br /&gt; /* public functions here */&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;Let's just perform another closure. Why not. This is the final closure, and will contain any public functions. For example, within the big brackets, we could say:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;hide: function (){&lt;br /&gt; Dom.setStyle(el, 'display', 'none');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This is a public function which uses YAHOO.util.Dom.setStyle to make our Dom element with id 'el' go away. To used it we would say DomHijacker.hide(); The naming convention of my DomHijacker is a little weird, but I will give a better example below. If I was going to 'hijack' a list and turn it into some sort of dynamic menu, I would have called DomHijacker, CustomMenu. Then saying CustomMenu.hide(); would sound a lot more acceptable.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;}();&lt;br /&gt;&lt;/pre&gt;Of course, if we want init to Event.onAvailable(el, init); to get called, we must invoke the anonymous function which we were returning in the first place. Now that code will get run by JavaScript, and YAHOO.util.Event will start waiting on 'el'. This is good. The whole reason that we have to wait on 'el' is because the JavaScript gets started before the rest of the Dom elements are actually... well... Dom elements (in the Dom). If you are still with me, you are freakin' awesome! If not, well, congrats on even reading this far. Feel free to ask questions.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;}('htmlElementId');&lt;br /&gt;&lt;/pre&gt;This is the final line in the function. Remember how on the first line, DomHijacker wanted a string for the 'el' which is the id of the html element? Well, we are self invoking DomHijacker and at the same time passing it that very string. 'htmlElementId' gets squished into the variable we called 'el' and is available all throughout DomHijacker, our 'class'. Remember? This is the id that onAvailable was waiting for.&lt;br /&gt;&lt;br /&gt;The whole idea here is that our big class called DomHijacker wants to modify an html element. We cannot do that until that element is in the Dom; which is why we must wait on it; which is why &lt;span style="font-style: italic;"&gt;YUI &lt;/span&gt;comes in so handy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Lets add some functionality to our class.&lt;/span&gt;&lt;br /&gt;We'll call it customList. First let's get a namespace to work in.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var DanW = {};&lt;br /&gt;&lt;/pre&gt;This will help keep things clean.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;DanW.customList = function(el) {&lt;br /&gt;&lt;/pre&gt;I want to make that 'better example' I mentioned earlier.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var Event = YAHOO.util.Event;&lt;br /&gt;var Anim = YAHOO.util.Anim;&lt;br /&gt;var Dom = YAHOO.util.Dom;&lt;br /&gt;&lt;br /&gt;var _item;&lt;br /&gt;&lt;/pre&gt;Establish some shortcuts for ease of typing. Also, make a 'private' variable, with the underscore prefixed naming convention called _item. This will be an array of the LI items in the list on the page. They will be references to the actual Dom nodes or elements.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var init = function() {&lt;br /&gt; _item = Dom.getChildren(el);&lt;br /&gt; Event.on(_item, 'click', action);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;This is the init function, in all its glory. All we do is get the items in the list called el, and assign a function, action to their respective clickage.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var action = function() {&lt;br /&gt; /* keyword this refers to&lt;br /&gt;    the li which was clicked on */&lt;br /&gt; Dom.setStyle(this, 'color', '#FBB104');&lt;br /&gt;&lt;br /&gt; var attributes = {};&lt;br /&gt;&lt;br /&gt; attributes.fontSize = {&lt;br /&gt;     from: 100,&lt;br /&gt;     to: 200,&lt;br /&gt;     unit: '%'&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; var sizeUp = new Anim(&lt;br /&gt;     this,&lt;br /&gt;     attributes,&lt;br /&gt;     0.2,&lt;br /&gt;     YAHOO.util.Easing.easeOutStrong);&lt;br /&gt;&lt;br /&gt; sizeUp.animate();&lt;br /&gt; Event.purgeElement(this, false, 'click');&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;If you have been with me so far, I should really not need to explain all this. Although I will say that since I only want the items to be clicked once for the animation, I simply removed the click listener after one click. I did this by calling: Event.purgeElement(this, false, 'click');&lt;br /&gt;&lt;br /&gt;Here is the entire function: customList, showing the self invokers at the bottom.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var DanW = {};&lt;br /&gt;&lt;br /&gt;DanW.customList = function(el) {&lt;br /&gt;&lt;br /&gt; var Event = YAHOO.util.Event;&lt;br /&gt; var Anim = YAHOO.util.Anim;&lt;br /&gt; var Dom = YAHOO.util.Dom;&lt;br /&gt;&lt;br /&gt; var _item;&lt;br /&gt;&lt;br /&gt; var init = function() {&lt;br /&gt;&lt;br /&gt;     _item = Dom.getChildren(el);&lt;br /&gt;&lt;br /&gt;     Event.on(_item, 'click', action);&lt;br /&gt;&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; var action = function() {&lt;br /&gt;   /* keyword this refers to&lt;br /&gt;      the li which was clicked on */&lt;br /&gt;   Dom.setStyle(this, 'color', '#FBB104');&lt;br /&gt;&lt;br /&gt;   var attributes = {};&lt;br /&gt;&lt;br /&gt;   attributes.fontSize = {&lt;br /&gt;       from: 100,&lt;br /&gt;       to: 200,&lt;br /&gt;       unit: '%'&lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   var sizeUp = new Anim(&lt;br /&gt;       this,&lt;br /&gt;       attributes,&lt;br /&gt;       0.2,&lt;br /&gt;       YAHOO.util.Easing.easeOutStrong);&lt;br /&gt;  &lt;br /&gt;   sizeUp.animate();&lt;br /&gt;   Event.purgeElement(this, false, 'click');&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;return function() {&lt;br /&gt;&lt;br /&gt;   Event.onAvailable(el, init);&lt;br /&gt;&lt;br /&gt;}();&lt;br /&gt;&lt;br /&gt;}('customList');&lt;br /&gt;&lt;/pre&gt;It has been a pleasure explaining this. Feel free to ask questions. A full example of this function is posted &lt;a href="http://code.polyesterhat.com/examples/My_Singleton_Instance_Dom_Hijacker/customList.html"&gt;here&lt;/a&gt;.</description><link>http://blog.polyesterhat.com/2007/10/my-hijax-singleton-instance.html</link><author>noreply@blogger.com (Daniel W)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item></channel></rss>