<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://jacwright.com/blog/wp-atom.php">
	<title type="text">Jacob Wright - Flex, AIR, PHP, etc.</title>
	<subtitle type="text">Flex, AIR, PHP, etc.</subtitle>

	<updated>2010-07-29T15:05:34Z</updated>

	<link rel="alternate" type="text/html" href="http://jacwright.com/blog" />
	<id>http://jacwright.com/blog/feed/atom/</id>
	

	<generator uri="http://wordpress.org/" version="3.0">WordPress</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/jacwright" /><feedburner:info uri="jacwright" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[My First 10k, Trailer Park Style]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/RB0H5QVzhQg/" />
		<id>http://jacwright.com/blog/?p=446</id>
		<updated>2010-07-29T15:05:34Z</updated>
		<published>2010-07-29T15:05:18Z</published>
		<category scheme="http://jacwright.com/blog" term="General" />		<summary type="html"><![CDATA[I am finally getting around to sharing my memorial day adventure. I ran my first 10k here in Boulder (called the BolderBOULDER). It was pretty fun, considering I wasn&#8217;t in great shape for it. I outdid my expectations (I&#8217;m slow) with a 68 minute time. Our Jive team running the BolderBOULDER (voted best 10k in [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/446/my-first-10k-trailer-park-style/">&lt;p&gt;I am finally getting around to sharing my memorial day adventure. I ran my first 10k here in Boulder (called the BolderBOULDER). It was pretty fun, considering I wasn&amp;#8217;t in great shape for it. I outdid my expectations (I&amp;#8217;m slow) with a 68 minute time. Our Jive team running the BolderBOULDER (voted best 10k in the country) planned out a sweet running uniform: jean cutoffs, wife-beater, Jive tattoo, fake mustache, and anything else that screamed &amp;#8220;TRAILER PARK!&amp;#8221;&lt;/p&gt;
&lt;p&gt;UNFORTUNATELY, I was the &lt;em&gt;ONLY&lt;/em&gt; one who really followed through on the whole outfit. Guess that means I&amp;#8217;m totally the winner in the style category. Here are some photos to commemorate the event.&lt;/p&gt;
&lt;p&gt;Starting out&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jacwright.com/blog/wp-content/uploads/2010/07/startingout.jpg"&gt;&lt;img src="http://jacwright.com/blog/wp-content/uploads/2010/07/startingout-225x300.jpg" alt="Starting out" title="startingout" width="225" height="300" class="aligncenter size-medium wp-image-467" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just gettin&amp;#8217; going&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jacwright.com/blog/wp-content/uploads/2010/07/61703-1335-006f.jpg"&gt;&lt;img src="http://jacwright.com/blog/wp-content/uploads/2010/07/61703-1335-006f-200x300.jpg" alt="" title="61703-1335-006f" width="200" height="300" class="aligncenter size-medium wp-image-469" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Getting cooled off&lt;br /&gt;
&lt;a href="http://jacwright.com/blog/wp-content/uploads/2010/07/61703-3589-025f.jpg"&gt;&lt;img src="http://jacwright.com/blog/wp-content/uploads/2010/07/61703-3589-025f-199x300.jpg" alt="" title="61703-3589-025f" width="199" height="300" class="aligncenter size-medium wp-image-470" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Breaking a mile barrier&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jacwright.com/blog/wp-content/uploads/2010/07/gettingthrough.jpg"&gt;&lt;img src="http://jacwright.com/blog/wp-content/uploads/2010/07/gettingthrough.jpg" alt="" title="gettingthrough" width="151" height="178" class="aligncenter size-full wp-image-471" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Home stretch&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jacwright.com/blog/wp-content/uploads/2010/07/61703-5408-021f.jpg"&gt;&lt;img src="http://jacwright.com/blog/wp-content/uploads/2010/07/61703-5408-021f-201x300.jpg" alt="" title="61703-5408-021f" width="201" height="300" class="aligncenter size-medium wp-image-472" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After Pose (mustache finally fell off)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jacwright.com/blog/wp-content/uploads/2010/07/afterpose.jpg"&gt;&lt;img src="http://jacwright.com/blog/wp-content/uploads/2010/07/afterpose-225x300.jpg" alt="" title="afterpose" width="225" height="300" class="aligncenter size-medium wp-image-473" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/RB0H5QVzhQg" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/446/my-first-10k-trailer-park-style/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/446/my-first-10k-trailer-park-style/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/446/my-first-10k-trailer-park-style/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[Developers Put Their Heads in the Sand]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/01RjdBe448Y/" />
		<id>http://jacwright.com/blog/?p=464</id>
		<updated>2010-07-23T19:45:29Z</updated>
		<published>2010-07-23T19:45:29Z</published>
		<category scheme="http://jacwright.com/blog" term="General" />		<summary type="html"><![CDATA[As developers, we like to put our heads in the sand. We&#8217;d be much more successful if we didn&#8217;t. Let me explain. When I first learned about basic object oriented programming, I was suddenly disgusted with functions and code that wasn&#8217;t an object. I got over it. When I learned about composition over inheritance, that [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/464/developers-put-their-heads-in-the-sand/">&lt;p&gt;As developers, we like to put our heads in the sand. We&amp;#8217;d be much more successful if we didn&amp;#8217;t. Let me explain.&lt;/p&gt;
&lt;p&gt;When I first learned about basic object oriented programming, I was suddenly disgusted with functions and code that wasn&amp;#8217;t an object. I got over it.&lt;/p&gt;
&lt;p&gt;When I learned about composition over inheritance, that became the standard by which I judged all code, mine included. It became my fixation. I got over it.&lt;/p&gt;
&lt;p&gt;When I learned about design patterns, I wanted to apply them to every situation, and I wanted to do it &lt;em&gt;right&lt;/em&gt; and apply them &lt;em&gt;exactly&lt;/em&gt; the way prescribed in the pattern. &lt;em&gt;I got over it&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When I learned about optimizing code, I spat on for loops that didn&amp;#8217;t initialize the length first, I kicked dirt around static methods which are shown to be slower (in the language I was using) than instance methods, and I generally despised any type of code which I read on a blog was slower than an optimized alternative. &lt;em&gt;&lt;strong&gt;I got over it&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I could go on with dependency injection, abstraction, database normalization, and on, and on, and on. I hope I continue to get over over-applying new knowledge.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve always wanted to iterate over and rewrite again and again pieces of code, reusable libraries, and other gleaming nuggets I&amp;#8217;ve done in the past which could be more perfect. Even faster. Even better. I&amp;#8217;m getting over it.&lt;/p&gt;
&lt;p&gt;In the last few months I&amp;#8217;ve been working with some very bright and &lt;em&gt;&lt;a href="http://en.wiktionary.org/wiki/pragmatic" title="Practical, concerned with making decisions and actions that are useful in practice, not just theory"&gt;pragmatic&lt;/a&gt;&lt;/em&gt; developers. They&amp;#8217;ve been teaching me, unbeknownst to themselves, to look at the big picture and to get my freaking head out of the sand.&lt;/p&gt;
&lt;p&gt;Just because instance methods are slower than statics doesn&amp;#8217;t mean you shouldn&amp;#8217;t use them. Creating an object is slower than calling a method, but should we throw OOP out the window and stick with functional programming? Messing up the Flyweight pattern (or even heaven forbid, our blessed MVC pattern) by altering it from the original and all knowing gang-of-four specification doesn&amp;#8217;t end-of-life your product before it&amp;#8217;s out the door. What keeps your product from releasing is rewriting it, or pieces of it, over and over again. If it works, DON&amp;#8217;T FIX IT. Only optimize if your application is too slow for your users. And then only optimize the slowest parts. Next application you write you can do it better, but freaking finish! Clean up and refactor as you add new features for your users. Don&amp;#8217;t waste time redoing anything from scratch unless its complete junk. And if you wrote it, figure out why you&amp;#8217;re writing complete junk in the first place and fix the root of the problem.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m writing a &lt;a href="http://github.com/jacwright/simpli5" title="Simpli5 Javascript Library"&gt;library&lt;/a&gt; in Javascript for HTML5 applications that I know will make many Javascript developer weep. It flys in the face of all the wisdom and standards that they&amp;#8217;ve read about on their favorite blogs. But it will make developing applications easier and more maintainable. I know the rules, and thus I know how and when to break them because I know why they were established.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m still watching the development of Reflex, the Flash component library my brother is involved in (I&amp;#8217;m not actively participating anymore). They&amp;#8217;re fighting against head-sand-itis both externally and internally. Project supporters may disagree with things proposed because it&amp;#8217;s not right, or it&amp;#8217;s not as fast as machine code. Internally with themselves they&amp;#8217;re disgusted at breaking precious programming rules. Finally they&amp;#8217;re starting to let ideals slide because progression is so slow. Eventually, I hope, they&amp;#8217;ll raise their sites to the end goal and do what is necessary to reach it. Even if it means using brains instead of rules. (no offense to any individual person or the general group, we all struggle with it, we&amp;#8217;re developers)&lt;/p&gt;
&lt;p&gt;The rules are generalities, guidelines to help us until we understand the principle behind the rule well enough to make our own decisions. Understand your natural tendency to over-apply and work against your nature to be more pragmatic.&lt;/p&gt;
&lt;p&gt;May we all work on seeing the big picture, understanding the principle behind the rule, and creating great experiences for those who will use our applications. I&amp;#8217;m certainly the pot calling the kettle black on this.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/01RjdBe448Y" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/464/developers-put-their-heads-in-the-sand/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/464/developers-put-their-heads-in-the-sand/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/464/developers-put-their-heads-in-the-sand/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[Creating a Hover Menu with HTML5 and Simpli5]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/2_30ua8qSTw/" />
		<id>http://jacwright.com/blog/?p=457</id>
		<updated>2010-07-21T20:17:20Z</updated>
		<published>2010-07-21T19:46:11Z</published>
		<category scheme="http://jacwright.com/blog" term="HTML5" /><category scheme="http://jacwright.com/blog" term="Javascript" /><category scheme="http://jacwright.com/blog" term="Simpli5" />		<summary type="html"><![CDATA[A More Usable Application I decided to build my own version of a contextual hover menu to make my applications more usable. It is meant to appear when you select a piece of data and give you quick access to all the actions you might perform on it. Forget long toolbars and hidden right-click menus. [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/457/creating-a-hover-menu-with-html5-and-simpli5/">&lt;h3&gt;A More Usable Application&lt;/h3&gt;
&lt;p&gt;I decided to build my own version of a contextual hover menu to make my applications more usable. It is meant to appear when you select a piece of data and give you quick access to all the actions you might perform on it. Forget long toolbars and hidden right-click menus. I wanted something that a user didn't have to dig around to find, that wouldn't be hard to navigate, and that wasn't hidden (a right-click on the web is not common enough for users to rely on).&lt;/p&gt;
&lt;p&gt;I'll walk you through the beginning process I took to create the HoverMenu component using Simpli5 and then I'll cover at a higher level the UX considerations that went into making it even better. You can check out the &lt;a href="http://jacwright.github.com/simpli5/demos/hover-menu.html"&gt;component in action&lt;/a&gt; first (using Safari, Chrome, or Firefox).&lt;/p&gt;
&lt;h3&gt;Base Simpli5 Component&lt;/h3&gt;
&lt;p&gt;To start, &lt;a href="http://github.com/jacwright/simpli5"&gt;Simpli5&lt;/a&gt; encourages using tags that provide good semantics for the application, ignoring whether or not they are valid HTML tags. It makes your application easier to read and understand, and since Simpli5 was made for creating full web applications, SEO and other content-based concerns are thrown out the window. I will start with the component definition in &lt;a href="http://github.com/jacwright/simpli5/blob/master/components/HoverMenu.js" title="HoverMenu source code"&gt;HoverMenu.js&lt;/a&gt;. I have the base component, menu containers, and menu items that I'll need. There will also be separators, but that has no code or logic and so can just be added in the stylesheet.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-5"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; HoverMenu = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Component&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: Component, &lt;span style="color: #009900; font-style: italic;"&gt;// the base when using custom tags&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template: &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Template&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;hover-menu&amp;gt;&amp;lt;/hover-menu&amp;gt;'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;, &lt;span style="color: #009900; font-style: italic;"&gt;// component template used when creating from code&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; register: &lt;span style="color: #3366CC;"&gt;'hover-menu'&lt;/span&gt;, &lt;span style="color: #009900; font-style: italic;"&gt;// css selector to convert matching elements into a HoverMenu&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; constructor: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// the constructor&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt; = &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;find&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;simpli5.&lt;span style="color: #006600;"&gt;selector&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'menu'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hide&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; HoverMenuSubmenu = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Component&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: Component,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template: &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Template&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;menu&amp;gt;&amp;lt;/menu&amp;gt;'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; register: &lt;span style="color: #3366CC;"&gt;'hover-menu menu'&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; HoverMenuItem = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Component&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: Component,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template: &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Template&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;menu-item&amp;gt;&amp;lt;/menu-item&amp;gt;'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; register: &lt;span style="color: #3366CC;"&gt;'hover-menu menu-item'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; constructor: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I'll give it a stylesheet &lt;a href="http://github.com/jacwright/simpli5/blob/master/css/HoverMenu.css"&gt;HoverMenu.css&lt;/a&gt; to make it look good.&lt;/p&gt;
&lt;p&gt;What I want is when the user hovers over the button, the menu pops up.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-6"&gt;
&lt;div class="javascript"&gt;constructor: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'rollover'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #000066;"&gt;open&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'rollout'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #000066;"&gt;close&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;open&lt;/span&gt;: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; rect = &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;rect&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;.&lt;span style="color: #006600;"&gt;show&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;true&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;addClass&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'open'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;.&lt;span style="color: #006600;"&gt;rect&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;left: rect.&lt;span style="color: #006600;"&gt;right&lt;/span&gt;, top: rect.&lt;span style="color: #006600;"&gt;top&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;close&lt;/span&gt;: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;.&lt;span style="color: #000066;"&gt;close&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Of course, sometimes I might want to have the user click to popup the menu, for ones that are used less often or in the case that there are many on the screen (don't want to have popups all over the place by moving your mouse around).&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-7"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; HoverMenu = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Component&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: Component,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template: &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Template&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;hover-menu&amp;gt;&amp;lt;/hover-menu&amp;gt;'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; register: &lt;span style="color: #3366CC;"&gt;'hover-menu'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; properties: &lt;span style="color: #66cc66;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'click-only'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#93;&lt;/span&gt;, &lt;span style="color: #009900; font-style: italic;"&gt;// add attributes that translate to properties in this array&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; constructor: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'click'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #000066;"&gt;open&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// click will always open it&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;clickOnly&lt;/span&gt; = &lt;span style="color: #003366; font-weight: bold;"&gt;false&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; get clickOnly&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._clickOnly;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; set clickOnly&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._clickOnly == value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._clickOnly = value;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; value ? &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;un&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'rollover'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #000066;"&gt;open&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; : &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'rollover'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #000066;"&gt;open&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here I added an implicit getter/setter that by default is false so hovering will open the menu. But if hoverMenu.clickOnly = false or &amp;lt;hover-menu click-only="false"&amp;gt;...&amp;lt;/hover-menu&amp;gt; then you'll have to click the button to open the menu.&lt;/p&gt;
&lt;p&gt;I've also added other settings for customization: autoClose to close the menu automatically when the mouse moves off of it for a few milliseconds, menuDelay to turn off the delay menus take to close (I talk about this later), and openBelow to cause the menu to open up beneath the button instead of to the side of it.&lt;/p&gt;
&lt;p&gt;Next we need to allow menu items to hold submenus and to dispatch events when the user selects them. It would be nice if these can be triggered by code too.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-8"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #009900; font-style: italic;"&gt;// HoverMenuItem&lt;/span&gt;&lt;br /&gt;
events: &lt;span style="color: #66cc66;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'select'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#93;&lt;/span&gt;, &lt;span style="color: #009900; font-style: italic;"&gt;// add custom events that can be listened to via onevent attributes&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;constructor: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'click'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;select&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'rollover'&lt;/span&gt;, &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hovered&lt;/span&gt;.&lt;span style="color: #006600;"&gt;boundTo&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt; = &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;find&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'menu'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hide&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;addClass&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'submenu'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;open&lt;/span&gt;: HoverMenu.&lt;span style="color: #006600;"&gt;prototype&lt;/span&gt;.&lt;span style="color: #000066;"&gt;open&lt;/span&gt;, &lt;span style="color: #009900; font-style: italic;"&gt;// use the same function from HoverMenu&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;close&lt;/span&gt;: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;.&lt;span style="color: #000066;"&gt;close&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;removeClass&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'open'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hoveredItem&lt;/span&gt; = &lt;span style="color: #003366; font-weight: bold;"&gt;null&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;select: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;disabled&lt;/span&gt; || &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;dispatchEvent&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; CustomEvent&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'select'&lt;/span&gt;, &lt;span style="color: #003366; font-weight: bold;"&gt;true&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// this is our own event and we will bubble it&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;menu&lt;/span&gt;.&lt;span style="color: #000066;"&gt;close&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// once selected, close the whole menu&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;/p&gt;
&lt;p&gt;hovered: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;disabled&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hoveredItem&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hoveredItem&lt;/span&gt; != &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;.&lt;span style="color: #006600;"&gt;hoveredItem&lt;/span&gt;.&lt;span style="color: #000066;"&gt;close&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;submenu&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #000066;"&gt;open&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hopefully you can understand the logic by reading through the code, but there are a couple of things I want to point out. The "events" property holds a list of custom events for the component to look for when initializing its attributes. Because I specified the select event there you can add onselect="alert('item selected')" to the tag and it will work. Also, our first usability tidbit for the menu, don't close submenus until the user moves their mouse to a sibling menu item. That wraps up our basic-component-building-101-in-Simpli5 overview and brings us to our user experience in using this component. Now I realize that UX encompasses so much more than a component, but the usability and experience the user has with this component is what I am referring to when I say UX.&lt;/p&gt;
&lt;h3&gt;Making it Shine with Usability&lt;/h3&gt;
&lt;p&gt;Most of these things were added because I tried using the menu and noticed spots of frustration. Some were added from suggestions of others.&lt;/p&gt;
&lt;p&gt;The first thing I did to enhance the usability of the menu was to keep the entire menu and submenus from closing immediately. The less accurate a user has to be with their mouse, the quicker they can get things done and the easier it is to use an application. If the menu closes because a user accidentally moves the mouse a little beyond the menu then they have to start all over again opening the menu up from the beginning. When the hover menu's autoClose is true, the menu waits 600 milliseconds before closing. This allows a user to make mouse mistakes and recover from them before having to reopen the menu.&lt;/p&gt;
&lt;p&gt;The next usability piece came from testing with longer submenus. I noticed that if I wanted to click the last item in a submenu and I moved my mouse strait to it, the mouse path went over the edge of the next sibling menu item, closing the previous item's submenu. In order to select that last submenu item I had to alter my mouse path to a 7 shape, moving across to the submenu first, then down to the desired item. In order to allow some forgiveness in the mouse movement while trying not to hamper the speed at opening the next submenu if that is the real desired action, I added a 150ms delay in opening and closing submenus. This seemed to be enough time for a quick mouse movement down across sibling menu items into the submenu, while not being too much time if you wanted to open the sibling submenu. I also added the menuDelay option that defaults to true, but can be set to false if you want to get rid of this 150ms delay.&lt;/p&gt;
&lt;p&gt;I added an alternate element style in the stylesheet for elements called &amp;lt;menu-content&amp;gt; which is an alternative to holding menu items in a submenu and allows robust components like color pickers or lists of images to be used, adding to the overall UX of the UI.&lt;/p&gt;
&lt;p&gt;I added positioning support for them menus to popup above or to the left of their parent if they are near the edge of the screen. I made the menus append to the body of the document so that they wouldn't get cut off by any overflow auto/hidden elements. There were also other small things I added too, such as a style on items with open submenus so they can be seen easier and allowing the menu to be closed by clicking elsewhere or pressing Esc.&lt;/p&gt;
&lt;p&gt;Overall the component turned out quite well. Here is a demo page of it in action (view source to see the markup): &lt;a href="http://jacwright.github.com/simpli5/demos/hover-menu.html"&gt;http://jacwright.github.com/simpli5/demos/hover-menu.html&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/2_30ua8qSTw" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/457/creating-a-hover-menu-with-html5-and-simpli5/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/457/creating-a-hover-menu-with-html5-and-simpli5/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/457/creating-a-hover-menu-with-html5-and-simpli5/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[The Joys of HTML5]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/-ZLsKwtoxHA/" />
		<id>http://jacwright.com/blog/?p=454</id>
		<updated>2010-07-16T22:11:49Z</updated>
		<published>2010-07-16T22:11:49Z</published>
		<category scheme="http://jacwright.com/blog" term="HTML5" />		<summary type="html"><![CDATA[HTML5 is SOOOooooo much nicer to program for than previous versions of HTML. Here's why, but first a little context. We're creating a power-user interface for the next version of our app using HTML5. It will be similar to tweet deck with multiple columns, and it needs to have all sorts of functionality crammed into [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/454/the-joys-of-html5/">&lt;p&gt;HTML5 is SOOOooooo much nicer to program for than previous versions of HTML. Here's why, but first a little context.&lt;/p&gt;
&lt;p&gt;We're creating a power-user interface for the next version of our app using HTML5. It will be similar to tweet deck with multiple columns, and it needs to have all sorts of functionality crammed into the column views. This will require a lot of custom UI components and iterative work on UX. But it's not so daunting a task when you don't have to support really old browsers. Browsers which forcing you to compromise your user's experience.&lt;/p&gt;
&lt;p&gt;I've been putting time into creating a Javascript library for HTML5 applications, and I've open sourced it with the name Simpli5 (&lt;a href="http://github.com/jacwright/simpli5/"&gt;hosting on github&lt;/a&gt;). Many of the things I'm doing there will make traditional Javascript purists cry in horror, but it's focused on building rich applications that are easy to understand and maintain. But I'll come back to Simpli5 later. Today it's about HTML5 and the CSS and Javascript that comes with it.&lt;/p&gt;
&lt;p&gt;These are some of the golden gleaming granules of goodness that gives me goosebumps with HTML5. (now THAT is some alliteration!)&lt;/p&gt;
&lt;p&gt;CSS Selectors do what they're supposed to. Using the child selector "&gt;" I can remove blocks of CSS that exist solely to nullify cascading styles. I can add a margin to all but the first element using the sibling selector "+". I can exclude using :not(.someclass) and skip items using :nth-child(odd). :hover works on all elements. And I can use a[href~=jive] if I want to highlight Jive links all special.&lt;/p&gt;
&lt;p&gt;CSS Styles prevent much of the need for extra HTML cluttering up the page for styling sake. I can layer on multiple backgrounds to elements (background: url(1), url(2), etc), round out corners (border-radius:5px), reliably use opacity for a whole element or for just the border/background color (rgba(0, 0, 0, .5)), and even create gradients and reflections. Everything I need for a Web 2.0 application . Between this and the selectors, I can cook up some pretty decent looking prototypes without any images at all.&lt;/p&gt;
&lt;p&gt;Javascript Consistency allows me to reliably make use of implicit getters and setters, add to the prototype of DOM elements (gasp, he wouldn't dare!), select elements in the DOM using all the above mentioned CSS selector coolness (natively BTW), and all the Array methods and DOM methods that you SHOULD be able to use but usually can't because you have to support browser X (being, of course, IE).&lt;/p&gt;
&lt;p&gt;HTML5 also has newer tags, micro formats, and such, but that hasn't been something I've really benefited from so much. I'm not building a website. I'm building an application. And those have different needs. I'm excited to use some of the other new features such as the client-side storage and database for speed and offline support.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/-ZLsKwtoxHA" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/454/the-joys-of-html5/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/454/the-joys-of-html5/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/454/the-joys-of-html5/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[Scalable MySQL]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/cv4WywWxel0/" />
		<id>http://jacwright.com/blog/?p=447</id>
		<updated>2010-07-01T23:04:19Z</updated>
		<published>2010-07-01T23:04:19Z</published>
		<category scheme="http://jacwright.com/blog" term="MySQL" />		<summary type="html"><![CDATA[Today I attended a class on Building Scalable, High Performance Applications put on by Percona, a bunch of guys who wrote MySQL and started their own consulting firm. There was only two people in the class which was quite surprising as these guys are the best in their space. But here are my notes from [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/447/scalable-mysql/">&lt;p&gt;Today I attended a class on Building Scalable, High Performance Applications put on by &lt;a href="http://www.percona.com/"&gt;Percona&lt;/a&gt;, a bunch of guys who wrote MySQL and started their own consulting firm. There was only two people in the class which was quite surprising as these guys are the best in their space. But here are my notes from the class, for what it is worth. Some of the items are random tidbits that came up. The guy knew PHP so some of the stuff is about PHP.&lt;/p&gt;
&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;Response, how long it takes, and throughput, how many users you can serve.&lt;/p&gt;
&lt;p&gt;If a feature isn't core to the user's experience, it ought to be in another database. Logs, statistics, or other non-customer facing data shouldn't become a bottleneck to the application's functions.&lt;/p&gt;
&lt;p&gt;It's good for all the stakeholders to agree on what a reasonable response time is.&lt;/p&gt;
&lt;p&gt;Optimizing for throughput can hurt response, optimizing for response can hurt throughput.&lt;/p&gt;
&lt;p&gt;Passing non-urgent requests to an asynchronous queue can help throughput and response time. Gearman or ActiveMQ can be used for async tasks that need to be inserted.&lt;/p&gt;
&lt;p&gt;Tuning your slowest queries isn't as helpful as looking at the full stack of what is happening in an app and finding out the bottleneck of regular user requests. Saving on one query could make the overall request take longer because of additional tasks that need to be done. Alternatively, eliminating a bunch of the fast queries might help the application performance, even though they're fast. Setting your long-query time to 0 for 5 minutes, an hour, whatever you can afford to do, then send the it through mk-query-digest will give you the query that took the longest combined. That will help to find fast queries that take a lot of time because of how often they are called. You can also use tcp dump on port 3306 piped to mk-query-digest as well. &lt;/p&gt;
&lt;p&gt;You can add performance data gathering in your live app by grabbing the data randomly (e.g. if (rand(1, 100) == 1) capturePerformance();)&lt;/p&gt;
&lt;p&gt;Sphinx is like lucene for PHP.&lt;/p&gt;
&lt;p&gt;Looking at average time doesn't help as much as looking at the 95th percentile, because some pages might be really fast, others might be really slow. (e.g. 95% served within 300ms, 99% within 1200ms)&lt;/p&gt;
&lt;p&gt;Make it harder for users to do things that are expensive. Don't discount the outlier expensive requests, denial of service, users may surprise you. It's easier to scale task when they are about the same shape.&lt;/p&gt;
&lt;p&gt;Cacti and Munin can graph activity over time with plugins for MySQL.&lt;/p&gt;
&lt;p&gt;Cross database joins are really no different than cross table joins in a single MySQL instance.&lt;/p&gt;
&lt;p&gt;Make your code flexible, put SQL into a library. Don't hard-code database names, IPs, hosts, reads may need to go against one database, writes against another. Perhaps logs or other functions might hit even another database.&lt;/p&gt;
&lt;p&gt;Sharding is for write-heavy applications. A cluster setup is best when grabbing rows by id, but geting a range of data causes a lot of network IO, but they're good for write-heavy too.&lt;/p&gt;
&lt;p&gt;Exact numbers aren't always needed. You can guestimate or round the number. Grab the number once a day and cache that, use a counter with memcached to batch the updates, etc.&lt;/p&gt;
&lt;p&gt;Don't overengineer, don't add complexity if you don't need to. 1 database on 1 machine is simple, master slave less, sharding even less.&lt;/p&gt;
&lt;p&gt;First, use caching (memcached) then, if needed use replication. Finally, as a last option, go to sharding.&lt;/p&gt;
&lt;p&gt;Grouping writes in a transaction helps a lot. Using a queue to async the writes will help.&lt;/p&gt;
&lt;p&gt;InnoDB groups rows by their id in page files. Thus, auto-increment ids are more optimized under innodb than random ids.&lt;/p&gt;
&lt;p&gt;Percona's blog is &lt;a href="http://www.mysqlperformanceblog.com/"&gt;mysqlperformanceblog.org&lt;/a&gt; and looks to have some great articles including EC2 performance and more.&lt;/p&gt;
&lt;p&gt;If you're sharding, there's several methods. You could shard the same data in different shards that is being accessed for different uses (search db vs data storage db).&lt;/p&gt;
&lt;p&gt;Sysbench provides a framework for benchmarking mysql, but replaying the user's data is the best strategy. Mysqlslap creates random data for testing data load.&lt;/p&gt;
&lt;p&gt;When upgrading, upgrade the slaves first, then the master.&lt;/p&gt;
&lt;p&gt;In applications, mysql connections should be short lived. You should fetch all the data as early in your request as you can, then close the connection. Stored Procedures can be more performant because they lower the round trips to the database from your application code.&lt;/p&gt;
&lt;p&gt;Persistent connections or connection pools can often be bad. JDBC is pretty good, but others (PHP) are not. Creating a connection to MySQL is really cheap.&lt;/p&gt;
&lt;p&gt;Dividing reads amongst the slaves in a smart manner allows for DB caching.&lt;/p&gt;
&lt;p&gt;Building summary tables for users when they log in to cache what they may be likely to access can increase performance.&lt;/p&gt;
&lt;p&gt;Master-master setup (mysql-master-master, MMM) can work well when a database goes down.&lt;/p&gt;
&lt;p&gt;When we know MySQL is the issue, use EXPLAIN. Bookmark, read, and use &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/using-explain.html"&gt;http://dev.mysql.com/doc/refman/5.1/en/using-explain.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Varchar is stored as the number of characters + 1, but when aggregating it in memory during a select, MySQL can not use variable width fields, so using VARCHAR(255) for all your fields causes much higher memory usage in queries than might be necessary.&lt;/p&gt;
&lt;p&gt;\G at the end of your queries on the command line prints out the rows in blocks and is more readable (if you have one or just a few rows returned).&lt;/p&gt;
&lt;p&gt;MySQL is pretty smart about its data distribution. Run ANALYZE TABLE table_name; to reset the usage statistics.&lt;/p&gt;
&lt;p&gt;Indexes are stored in a balanced tree.&lt;/p&gt;
&lt;p&gt;An index on field A, B, and C takes the three values and concatenates them. It will use A first, then B, then C. If any of the WHERE clause is a range query (&lt;, &gt;, BETWEEN, etc) MySQL will not use the fields after that. In other words, if A was only used in range queries, it wouldn't make any sense to add B and C to the index. Or you might put B and C before A. The first field in your index should be the most limiting in the result set. Knowing your data will help you to create and use the best indexes.&lt;/p&gt;
&lt;p&gt;SQL Tuning by Dan Tow is a good book to understand how things work under the hood.&lt;/p&gt;
&lt;p&gt;When JOINing tables if you think MySQL isn't doing it optimally you can use a STRAIGHT_JOIN and it will filter the result set in the order you have the tables, rather than it's own idea.&lt;/p&gt;
&lt;p&gt;Subqueries are horrible on performance with MySQL's optimizer. Use a join where you can. SELECT field FROM table procedure analyse(); will help to see what your data looks like with min, max, and average sizes.&lt;/p&gt;
&lt;p&gt;A benchmark function helps test speeds: SELECT benchmark(1000000, crc32("test"));&lt;/p&gt;
&lt;p&gt;Since MySQL uses a nested loop join, don't be shy about denormalizing your data. Optimizer decision making is all about tradeoffs.&lt;/p&gt;
&lt;p&gt;`mysqladmin extended status -i 2 -r` will show the global status every 2 seconds. -r will do relative.&lt;/p&gt;
&lt;p&gt;SHOW SESSION STATUS will give the temp tables create for the session and a lot of other useful data that I don't understand completely. Setting @@profiles = 1 will start storing profiles for the queries run. Then SHOW PROFILES; will show the profiles stored for each query, but you still have to figure out what to do with it. And that is for the whole system, not thread/connection specific.&lt;/p&gt;
&lt;p&gt;Using IN() is faster than ranges (e.g. WHERE id IN(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); is faster than WHERE id BETWEEN 1 AND 10; supposedly.) Because the equalifier is more mature than the range.&lt;/p&gt;
&lt;p&gt;Day one advice: keep it simple, normalize with the understanding you may denormalize later as needed. Use unicode where needed, not necessarily everywhere. Always have a primary key, keep it short, try and make it your primary access method. Innodb is safest, use it unless you have a specific reason to use MyISAM.&lt;/p&gt;
&lt;p&gt;If you have a column that gets written to (last_login_date on a user table) separate them out to another table. Keep your reads separate from your writes. "Hot column on a wide table"&lt;/p&gt;
&lt;p&gt;Domas has a good article on why round-trips take time.&lt;/p&gt;
&lt;p&gt;Mark Calahan wrote a nice post about using LIMIT with Mysql. Using LIMIT 100, 10 reads 110 rows, only returns 10. Grabbing the last id from the previous page and doing a WHERE id &gt; last_id LIMIT 0, 10 is faster.&lt;/p&gt;
&lt;p&gt;To optimize, don't use triggers, foreign keys, stored procedures except for limiting the trips to the server.&lt;/p&gt;
&lt;p&gt;Hope this helps.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/cv4WywWxel0" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/447/scalable-mysql/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/447/scalable-mysql/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/447/scalable-mysql/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[Javascript Rollover Rollout Events]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/TImxQoyBkM4/" />
		<id>http://jacwright.com/blog/?p=443</id>
		<updated>2010-06-01T22:42:18Z</updated>
		<published>2010-05-28T00:01:07Z</published>
		<category scheme="http://jacwright.com/blog" term="HTML5" /><category scheme="http://jacwright.com/blog" term="Javascript" /><category scheme="http://jacwright.com/blog" term="Simpli5" />		<summary type="html"><![CDATA[Javascript has mouseover and mouseout events. Flash has these, but they also have rollover and rollout events. There is a difference, and it can be painful developing Javascript components without the rollover and rollout events. So I put together a little script that provides them for us. Problem You want to perform some action when [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/443/javascript-rollover-rollout-events/">&lt;p&gt;Javascript has mouseover and mouseout events. Flash has these, but they also have rollover and rollout events. There is a difference, and it can be painful developing Javascript components without the rollover and rollout events. So I put together a little script that provides them for us.&lt;/p&gt;
&lt;h3&gt;Problem&lt;/h3&gt;
&lt;p&gt;You want to perform some action when the cursor rolls onto and off of an HTML element. When you use the mouseover/mouseout events, you get a mouseout and immediately another mouseover when the cursor is over a child element. Technically the mouse is still over the parent element, why does the mouseout happen? What the... you want it to work like CSS :hover. The way you'd think it SHOULD work. You figure, maybe it's just you're catching because bubbling child events, so you return out of your listener if the target does not equal your element. This removes the second mouseover, but you still get a mouseout when hovering over a child element.&lt;/p&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;Flash's solution was to build in a non-bubbling rollover/rollout event that works like you'd expect. I've never used a mouseover/mouseout in Flash since these new events came about. So, assuming you've got a modern standards-compliant browser (tested on Safari/Chrome &amp;#038; Firefox), this little bit of code will provide rollover/rollout events for your HTML and is non-intrusive. It saves a lot of headache and works great.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Updated:&lt;/b&gt; The code did not previously take into account siblings, only ancestors. Fixed to find the common ancestor.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-10"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt; listener&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;event&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; child = event.&lt;span style="color: #006600;"&gt;relatedTarget&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; ancestor = event.&lt;span style="color: #006600;"&gt;target&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// cancel if the relatedTarget is a child of the target&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;child&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;child.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt; == ancestor&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child = child.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// dispatch for the child and each parentNode except the common ancestor&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ancestor = event.&lt;span style="color: #006600;"&gt;target&lt;/span&gt;.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; ancestors = &lt;span style="color: #66cc66;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;ancestor&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ancestors.&lt;span style="color: #006600;"&gt;push&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;ancestor&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ancestor = ancestor.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ancestor = event.&lt;span style="color: #006600;"&gt;relatedTarget&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;ancestor&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;ancestors.&lt;span style="color: #006600;"&gt;indexOf&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;ancestor&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; != -&lt;span style="color: #CC0000;"&gt;1&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;break&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ancestor = ancestor.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child = event.&lt;span style="color: #006600;"&gt;target&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;child&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; mouseEvent = document.&lt;span style="color: #006600;"&gt;createEvent&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'MouseEvents'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mouseEvent.&lt;span style="color: #006600;"&gt;initEvent&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;event.&lt;span style="color: #006600;"&gt;type&lt;/span&gt;.&lt;span style="color: #006600;"&gt;replace&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'mouse'&lt;/span&gt;, &lt;span style="color: #3366CC;"&gt;'roll'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;false&lt;/span&gt;, &lt;span style="color: #009900; font-style: italic;"&gt;// does not bubble&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; event.&lt;span style="color: #006600;"&gt;cancelable&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; event.&lt;span style="color: #006600;"&gt;view&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; event.&lt;span style="color: #006600;"&gt;detail&lt;/span&gt;, event.&lt;span style="color: #006600;"&gt;screenX&lt;/span&gt;, event.&lt;span style="color: #006600;"&gt;screenY&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; event.&lt;span style="color: #006600;"&gt;ctrlKey&lt;/span&gt;, event.&lt;span style="color: #006600;"&gt;altKey&lt;/span&gt;, event.&lt;span style="color: #006600;"&gt;metaKey&lt;/span&gt;, event.&lt;span style="color: #006600;"&gt;button&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; event.&lt;span style="color: #006600;"&gt;relatedTarget&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child.&lt;span style="color: #006600;"&gt;dispatchEvent&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;mouseEvent&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child = child.&lt;span style="color: #006600;"&gt;parentNode&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;child == ancestor&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;break&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// setup the rollover/out events for components to use&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; document.&lt;span style="color: #006600;"&gt;addEventListener&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'mouseover'&lt;/span&gt;, listener, &lt;span style="color: #003366; font-weight: bold;"&gt;false&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; document.&lt;span style="color: #006600;"&gt;addEventListener&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'mouseout'&lt;/span&gt;, listener, &lt;span style="color: #003366; font-weight: bold;"&gt;false&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I hope this helps someone having a rough time with Javascript mouseovers.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/TImxQoyBkM4" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/443/javascript-rollover-rollout-events/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/443/javascript-rollover-rollout-events/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/443/javascript-rollover-rollout-events/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[Javascript Data Binding]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/XoJfJIpeh7g/" />
		<id>http://jacwright.com/blog/?p=438</id>
		<updated>2010-05-25T18:20:50Z</updated>
		<published>2010-05-25T18:20:16Z</published>
		<category scheme="http://jacwright.com/blog" term="HTML5" /><category scheme="http://jacwright.com/blog" term="Javascript" /><category scheme="http://jacwright.com/blog" term="Simpli5" />		<summary type="html"><![CDATA[Simpli5 has been coming along nicely as I've been able to put time into it. I'm very excited to announce data-binding. Data Binding Data binding is a technique we have and use in Flash quite a bit that allows one property to stay in sync with another. If obj.x is bound to obj.y then whenever [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/438/javascript-data-binding/">&lt;p&gt;&lt;a href="http://jacwright.com/blog/428/simpli5-an-html5-javascript-framework/"&gt;Simpli5&lt;/a&gt; has been coming along nicely as I've been able to put time into it. I'm very excited to announce data-binding.&lt;/p&gt;
&lt;h3&gt;Data Binding&lt;/h3&gt;
&lt;p&gt;Data binding is a technique we have and use in Flash quite a bit that allows one property to stay in sync with another. If obj.x is bound to obj.y then whenever obj.x is changed, obj.y will automatically update to the same value. I've built my own data binding frameworks in ActionScript 3 and I wanted it for my Javascript work as well.&lt;/p&gt;
&lt;p&gt;Since Simpli5 has a base-line of HTML5, I was easily able to create data binding in Javascript using implicit getters and setters. Any property on an object can be bound. My binding supports one-way, two-way, and bind-setters, and it allows deep binding.&lt;/p&gt;
&lt;p&gt;One-way binding propagates the changes of the &lt;strong&gt;source&lt;/strong&gt; object's property to the &lt;strong&gt;target&lt;/strong&gt; object's property. Whenever the source's property changes, the target's property updates. If the target's property is changed however, nothing will happen to the source.&lt;/p&gt;
&lt;p&gt;Two-way binding keeps the properties of the source and target in sync. When first bound, the source's property will be the value used, but if either the source's property is changed or the target's property is changed the other will update to stay in sync.&lt;/p&gt;
&lt;p&gt;Deep binding is being able to bind the property of a property of the source. As an example, obj.x would be shallow binding where obj.x.y.z would be deep binding.&lt;/p&gt;
&lt;h3&gt;Binding Usage&lt;/h3&gt;
&lt;p&gt;The following shows how binding can be used.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-13"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; obj1 = &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt;: &lt;span style="color: #3366CC;"&gt;'Bob'&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; obj2 = &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt;: &lt;span style="color: #3366CC;"&gt;'Henry'&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;Bind.&lt;span style="color: #006600;"&gt;property&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj1, &lt;span style="color: #3366CC;"&gt;'name'&lt;/span&gt;, obj2, &lt;span style="color: #3366CC;"&gt;'name'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj2.&lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// will be Bob&lt;/span&gt;&lt;br /&gt;
obj1.&lt;span style="color: #000066;"&gt;name&lt;/span&gt; = &lt;span style="color: #3366CC;"&gt;'Patricia'&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// the binding makes obj2.name update as well&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj2.&lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// will be Patricia&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; obj1 = &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt;: &lt;span style="color: #3366CC;"&gt;'Bob'&lt;/span&gt;, address: &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt; zip: &lt;span style="color: #CC0000;"&gt;12345&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; obj2 = &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color: #000066;"&gt;name&lt;/span&gt;: &lt;span style="color: #3366CC;"&gt;'Henry'&lt;/span&gt;, address: &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt; zip: &lt;span style="color: #CC0000;"&gt;56789&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;Bind.&lt;span style="color: #006600;"&gt;property&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj1, &lt;span style="color: #3366CC;"&gt;'address.zip'&lt;/span&gt;, obj2, &lt;span style="color: #3366CC;"&gt;'address.zip'&lt;/span&gt;, &lt;span style="color: #003366; font-weight: bold;"&gt;true&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// the last param (true) means a two way bind&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj2.&lt;span style="color: #006600;"&gt;address&lt;/span&gt;.&lt;span style="color: #006600;"&gt;zip&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// 12345&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;obj2.&lt;span style="color: #006600;"&gt;address&lt;/span&gt;.&lt;span style="color: #006600;"&gt;zip&lt;/span&gt; = &lt;span style="color: #3366CC;"&gt;'unknown'&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj1.&lt;span style="color: #006600;"&gt;address&lt;/span&gt;.&lt;span style="color: #006600;"&gt;zip&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// will be 'unknown' because we are 2-way binding&lt;/span&gt;&lt;br /&gt;
obj1.&lt;span style="color: #006600;"&gt;address&lt;/span&gt;.&lt;span style="color: #006600;"&gt;zip&lt;/span&gt; = &lt;span style="color: #CC0000;"&gt;12345&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;obj2.&lt;span style="color: #006600;"&gt;address&lt;/span&gt;.&lt;span style="color: #006600;"&gt;zip&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// will be 12345 again, same as obj1 &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Binding added to Template&lt;/h3&gt;
&lt;p&gt;I've added a new method to Template called createBound(). The Template.create() method will give you back an HTML element created from the template's HTML, replacing anything in curly braces with the evaluated javascript equivalent. With Template.createBound() you get back an HTML element which continues to update its attributes or text content as properties in the data or element change. Perhaps the best way to explain is to show some code.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-14"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; template = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Template&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;button&amp;gt;&amp;lt;img src=&amp;quot;{this.src}&amp;quot; alt=&amp;quot;{this.label}&amp;quot;/&amp;gt; Say {this.label}&amp;lt;/button&amp;gt;'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; btn = template.&lt;span style="color: #006600;"&gt;createBound&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;btn.&lt;span style="color: #006600;"&gt;outerHTML&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// &amp;lt;button&amp;gt;&amp;lt;img src=&amp;quot;&amp;quot; alt=&amp;quot;&amp;quot;/&amp;gt; Say &amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;btn.&lt;span style="color: #006600;"&gt;label&lt;/span&gt; = &lt;span style="color: #3366CC;"&gt;'Hello World'&lt;/span&gt;;&lt;br /&gt;
btn.&lt;span style="color: #006600;"&gt;src&lt;/span&gt; = &lt;span style="color: #3366CC;"&gt;'images/hello_world.png'&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;btn.&lt;span style="color: #006600;"&gt;outerHTML&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// &amp;lt;button&amp;gt;&amp;lt;img src=&amp;quot;images/hello_world.png&amp;quot; alt=&amp;quot;Hello World&amp;quot;/&amp;gt; Say Hello World&amp;lt;/button&amp;gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I've made it the component creation method of course, so now the properties on your components can update the HTML directly. And it isn't setting the innerHTML of the component, which would replace all the sub-elements and destroy any listeners that were on the old ones. It's binding smartly so that attributes and text get updated carefully.&lt;/p&gt;
&lt;h3&gt;Limitations&lt;/h3&gt;
&lt;p&gt;There are properties on elements that binding will not work the way you'd expect. Things like element.id, element.firstChild, img.src, et cetera, which the browser treats in a special way but are not getters and setters (as far as the javascript can tell anyway), these cannot be bound to reliably. They cannot be the source of a bind, but they could be the target of a one-way (non-deep) bind just fine.&lt;/p&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;I've started adding unit tests to the framework, especially since data binding can be such a tricky thing. I've got tests around the binding and the templates right now and feel confident that they are working pretty well. I'm using &lt;a href="http://code.google.com/p/js-test-driver/"&gt;js-test-driver&lt;/a&gt;. I've also added a maven build file for the tests and for compressing the library into a single file and a compressed file.&lt;/p&gt;
&lt;p&gt;The Simpli5 project is being hosted on Github: &lt;a href="http://github.com/jacwright/simpli5"&gt;http://github.com/jacwright/simpli5&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/XoJfJIpeh7g" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/438/javascript-data-binding/#comments" thr:count="5" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/438/javascript-data-binding/feed/atom/" thr:count="5" />
		<thr:total>5</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/438/javascript-data-binding/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[Simpli5, an HTML5 Javascript Framework]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/JKF53EcArdo/" />
		<id>http://jacwright.com/blog/?p=428</id>
		<updated>2010-05-07T16:13:49Z</updated>
		<published>2010-05-07T16:13:49Z</published>
		<category scheme="http://jacwright.com/blog" term="HTML5" /><category scheme="http://jacwright.com/blog" term="Javascript" />		<summary type="html"><![CDATA[I've started putting together a new HTML5 Javascript framework that is only compatible with HTML5 browsers. I'm able to have a much smaller library that way, and I'm able to do stuff I couldn't otherwise. Like... Optimization Because I'm using built-in Javascript methods (written in C) for many things I do, I am taking advantage [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/428/simpli5-an-html5-javascript-framework/">&lt;p&gt;I've started putting together a new &lt;a href="http://github.com/jacwright/simpli5" title="Simpli5, HTML5 Javascript Framework"&gt;HTML5 Javascript framework&lt;/a&gt; that is only compatible with HTML5 browsers. I'm able to have a much smaller library that way, and I'm able to do stuff I couldn't otherwise. Like...&lt;/p&gt;
&lt;h3&gt;Optimization&lt;/h3&gt;
&lt;p&gt;Because I'm using built-in Javascript methods (written in C) for many things I do, I am taking advantage of the speed of modern HTML5 browsers, without the bloat of code that makes up for missing features. Array.prototype.slice is used to convert NodeLists and Argument objects into arrays with $.toArray(); querySelector and querySelectorAll are used to quickly find the first or all matches for a given selector string. The built-in Array.prototype.forEach is used for iterating over arrays.&lt;/p&gt;
&lt;h3&gt;HTMLElement.prototype&lt;/h3&gt;
&lt;p&gt;I can add methods to the prototype of Node and HTMLElement, giving all elements in my document functionality that I feel are common enough to be needed.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-19"&gt;
&lt;div class="javascript"&gt;element.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'click'&lt;/span&gt;, callback, &lt;span style="color: #003366; font-weight: bold;"&gt;false&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900; font-style: italic;"&gt;// same as element.addEventListener(...) but shorter&lt;/span&gt;&lt;br /&gt;
element.&lt;span style="color: #006600;"&gt;addClass&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'my-class-name'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// hasClass, removeClass, toggleClass&lt;/span&gt;&lt;br /&gt;
element.&lt;span style="color: #006600;"&gt;findFirst&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'div .red'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; element.&lt;span style="color: #006600;"&gt;find&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'li'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
element.&lt;span style="color: #006600;"&gt;html&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; element.&lt;span style="color: #006600;"&gt;html&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;b&amp;gt;Hi!&amp;lt;/b&amp;gt;'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And much much more.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;simpl5&lt;/code&gt; Element Wrapper&lt;/h3&gt;
&lt;p&gt;I've also create a jQuery-like class (called simpli5) which is basically an Array (uses all the &lt;em&gt;native&lt;/em&gt; Array methods like concat, splice, forEach, map, etc.) and forwards all my calls I specify onto the elements in the array.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-20"&gt;
&lt;div class="javascript"&gt;simpli5&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'#my-div'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;.&lt;span style="color: #006600;"&gt;toggleClass&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'blue'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
$&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'a'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;.&lt;span style="color: #006600;"&gt;on&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'click'&lt;/span&gt;, &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;event&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; event.&lt;span style="color: #006600;"&gt;preventDefault&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;; &lt;span style="color: #009900; font-style: italic;"&gt;// real event object, don't need to fake it with a compatible browser&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Class Model and EventDispatcher&lt;/h3&gt;
&lt;p&gt;I like the class model a lot. It is actually compatible with earlier browsers as well. And I do use getters/setters now that I can. I also created an EventDispatcher class that provides the addEventListener/removeEventListener/dispatchEvent, and the shortcut methods on/un.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-21"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; Foo = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; &lt;span style="color: #003366; font-weight: bold;"&gt;Class&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: EventDispatcher,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; init: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._name = &lt;span style="color: #000066;"&gt;name&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; get &lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._name;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; set &lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._name == value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; oldName = &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._name;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._name = value;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;dispatchEvent&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; PropertyChangeEvent&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'name'&lt;/span&gt;, oldName, value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; Bar = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; &lt;span style="color: #003366; font-weight: bold;"&gt;Class&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: Foo,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; init: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// I've found this to be the simplest most optimized (least hacky) way for overrides&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// even though the syntax with a string isn't ideal. And I've looked around.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;callSuper&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'init'&lt;/span&gt;, &lt;span style="color: #3366CC;"&gt;'Bar'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// override only the getter to make it read-only&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; get &lt;span style="color: #000066;"&gt;name&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;._name;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Component Model&lt;/h3&gt;
&lt;p&gt;The part I'm most excited about is my component model. It allows you to make DOM elements &lt;strong&gt;become&lt;/strong&gt; new classes. I can take a common &amp;lt;button id="myButton"&amp;gt;&amp;lt;/button&amp;gt; (HTMLButtonElement) element and make it become my ToggleButton component. You will even get a "true" when doing: document.getElementById('myButton') instanceof ToggleButton. The following is a simple Button component.&lt;/p&gt;
&lt;div class="syntax_hilite"&gt;
&lt;div id="javascript-22"&gt;
&lt;div class="javascript"&gt;&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; Button = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Component&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; extend: HTMLButtonElement, &lt;span style="color: #009900; font-style: italic;"&gt;// be sure to extend the type you are becoming&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// the default template, true == cached (thanks ExtJS)&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #009900; font-style: italic;"&gt;// this component will become the top-level element in the template&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template: &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Template&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'&amp;lt;button&amp;gt;&amp;lt;/button&amp;gt;'&lt;/span&gt;, &lt;span style="color: #003366; font-weight: bold;"&gt;true&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; init: &lt;span style="color: #003366; font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;label&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;label&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;label&lt;/span&gt; = label;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; get label&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;text&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; set label&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #000066; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;text&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;value&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #66cc66;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #009900; font-style: italic;"&gt;// create a new button and add it into the document&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #003366; font-weight: bold;"&gt;var&lt;/span&gt; button = &lt;span style="color: #003366; font-weight: bold;"&gt;new&lt;/span&gt; Button&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
button.&lt;span style="color: #006600;"&gt;label&lt;/span&gt; = &lt;span style="color: #3366CC;"&gt;"Hello World"&lt;/span&gt;;&lt;br /&gt;
document.&lt;span style="color: #006600;"&gt;body&lt;/span&gt;.&lt;span style="color: #006600;"&gt;prepend&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;button&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #009900; font-style: italic;"&gt;// turn all existing &amp;lt;button&amp;gt;&amp;lt;/button&amp;gt; elements into Button components&lt;/span&gt;&lt;br /&gt;
document.&lt;span style="color: #006600;"&gt;find&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;'button'&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;.&lt;span style="color: #006600;"&gt;make&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;&amp;#40;&lt;/span&gt;Button&lt;span style="color: #66cc66;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Just the Beginning&lt;/h3&gt;
&lt;p&gt;This is just the start. I've been borrowing ideas and code from libraries such as jQuery, mootools, prototype, and Extjs. The library is still only partial with many missing features, but it will mature, and the beginning I've got has been quite exciting.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/JKF53EcArdo" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/428/simpli5-an-html5-javascript-framework/#comments" thr:count="7" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/428/simpli5-an-html5-javascript-framework/feed/atom/" thr:count="7" />
		<thr:total>7</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/428/simpli5-an-html5-javascript-framework/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[CSS3 Buttons]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/PWQ13_jpUdQ/" />
		<id>http://jacwright.com/blog/?p=421</id>
		<updated>2010-05-04T18:53:01Z</updated>
		<published>2010-05-04T18:50:48Z</published>
		<category scheme="http://jacwright.com/blog" term="CSS3" /><category scheme="http://jacwright.com/blog" term="HTML5" />		<summary type="html"><![CDATA[Using a handful of CSS3 styles implemented by Webkit (Safari and Chrome) and Firefox browsers, I've recreated buttons which I previously did with images, all in some simple CSS. I used the following styles: Background-image gradients Border radius Text shadow Box shadow Custom fonts The page is shown here in an iframe: If you have [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/421/css3-buttons/">&lt;p&gt;Using a handful of CSS3 styles implemented by Webkit (Safari and Chrome) and Firefox browsers, I've recreated buttons which I previously did with images, all in some simple CSS. I used the following styles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Background-image gradients&lt;/li&gt;
&lt;li&gt;Border radius&lt;/li&gt;
&lt;li&gt;Text shadow&lt;/li&gt;
&lt;li&gt;Box shadow&lt;/li&gt;
&lt;li&gt;Custom fonts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href="/blog/resources/html5/css_buttons/"&gt;page&lt;/a&gt; is shown here in an iframe:&lt;/p&gt;
&lt;p&gt;&lt;iframe style="width:100%;height:50px" src="/blog/resources/html5/css_buttons/"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;If you have a keen eye you'll see I'm using some borders on the top and bottom to simulate bevels, I'm using a custom font, Sansation, courtesy of &lt;a href="http://www.dafont.com/theme.php?cat=501&amp;#038;page=2"&gt;dafont.com&lt;/a&gt;, and the text shadows are cast upward when hoving over the button.&lt;/p&gt;
&lt;p&gt;Best part is, I'm using no javascript, and whenever I change the text of the buttons, I don't have to re-export images with the correct text. Won't the world be a lovely place when all browsers support the full HTML5/CSS3 spec?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/PWQ13_jpUdQ" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/421/css3-buttons/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/421/css3-buttons/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/421/css3-buttons/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Jacob Wright</name>
						<uri>http://www.jacwright.com</uri>
					</author>
		<title type="html"><![CDATA[New Track: HTML5]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/jacwright/~3/cG9bjh82dCE/" />
		<id>http://jacwright.com/blog/?p=419</id>
		<updated>2010-05-04T21:49:20Z</updated>
		<published>2010-05-03T18:37:13Z</published>
		<category scheme="http://jacwright.com/blog" term="HTML5" />		<summary type="html"><![CDATA[I've picked up a side job using HTML5's canvas element, and the project at work turned HTML5 for various non-Apple reasons. I've been hesitant to post about it because I firmly feel that Flash will continue to flourish in the future, and HTML5 is simply a new and better HTML4/XHTML. I will continue to be [...]]]></summary>
		<content type="html" xml:base="http://jacwright.com/blog/419/new-track-html5/">&lt;p&gt;I've picked up a side job using HTML5's canvas element, and the project at work turned HTML5 for various non-Apple reasons. I've been hesitant to post about it because I firmly feel that Flash will continue to flourish in the future, and HTML5 is simply a new and better HTML4/XHTML.&lt;/p&gt;
&lt;p&gt;I will continue to be involved in the Reflex project and in the Flash community, but since I am doing a lot of HTML5 work in the next few months, I will be talking about the cool stuff I am learning and doing. I've done a lot of HTML/CSS/JS, but now that I am tasked to only worry about HTML5, and not worry about being compatible with non-HTML5, the world has become a brighter place. A lot brighter.&lt;/p&gt;
&lt;p&gt;To get you started, &lt;a href="http://apirocks.com/html5/html5.html"&gt;here's a great overview on some of the new HTML5 features&lt;/a&gt;. There is some cool stuff, especially the Worker (which Flash doesn't have...yet) for a type of multi-threading. But the best feature for me is the CSS3 spec, allowing me to have scale-9 borders, use negative margins and inline-block without worrying about browser compatibility, and in general not need to create a ton of HTML markup just for my design. More coming soon.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/jacwright/~4/cG9bjh82dCE" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://jacwright.com/blog/419/new-track-html5/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://jacwright.com/blog/419/new-track-html5/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://jacwright.com/blog/419/new-track-html5/</feedburner:origLink></entry>
	</feed>
