<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Tong</title>
	<atom:link href="http://www.davidtong.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidtong.me</link>
	<description>web engineering and interaction design from davidtong.me</description>
	<lastBuildDate>Wed, 01 Feb 2012 21:33:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>IE bugs caused by CSS filter property fixed in jQuery 1.7</title>
		<link>http://www.davidtong.me/ie-bugs-caused-by-css-filter-fixed-in-jquery-1-7/</link>
		<comments>http://www.davidtong.me/ie-bugs-caused-by-css-filter-fixed-in-jquery-1-7/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 23:00:34 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=688</guid>
		<description><![CDATA[I assume that everyone knows about IE&#8217;s &#8216;filter&#8216; CSS property. We use it on IE&#60; =8 mainly because they don&#8217;t support the W3C opacity property. The new jQuery 1.7 finally added a fix to an issue with IE&#8217;s &#8216;filter&#8217; property. If you look at jQuery 1.7&#8242;s source code, you see that it does style.removeAttribute( &#8220;filter&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>I assume that everyone knows about IE&#8217;s &#8216;<a href="http://msdn.microsoft.com/en-us/library/ms532967(v=vs.85).aspx" target="_blank">filter</a>&#8216; CSS property. We use it on IE&lt; =8 mainly because they don&#8217;t support the W3C opacity property.</p>
<p>The new jQuery 1.7 finally added a fix to an issue with IE&#8217;s &#8216;filter&#8217; property. If you look at jQuery 1.7&#8242;s <a href="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js" target="_blank">source code, you see that it does style.removeAttribute( &#8220;filter&#8221; ) when opacity is 1 upon setting the opacity csshook.</a></p>
<p>The jQuery upgrade <strong>eliminates the need</strong> for us to do something like this:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">j_obj.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>opacity<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">removeAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'filter'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// remove filter property at the end of animation... no longer needed in jQuery 1.7 and higher</span><br />
<span style="color: #006600; font-style: italic;">// alternative: $(this).css('opacity', '');</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Why did we have to manually remove the filter CSS property for IE when opacity is 1, and why is jQuery finally doing it internally?</p>
<p>To recap, the filter of IE property is the cause of a few common IE bugs:</p>
<h3>Fuzzy/ blurry text</h3>
<p>This occurs on IE6 and IE7. Text would look fuzzy after some opacity animation if the filter CSS property is left behind. As stated early, this can be fixed by manually removing the filter property. See another <a href="http://brenelz.com/blog/ie-cleartype-blurry-text-solution/" target="_blank">blog post</a> for more information.</p>
<h3>Content clipping/ cut-off</h3>
<p>This occurs on IE8 only. Elements/ containers/ divs can be cut off at the edge of the parent container even if various tricks (z-index, position: absolute, overflow: visible) are already applied. The solution is, again, to remove the filter property. See another <a href="http://labs.thesedays.com/blog/2011/06/02/ie-alpha-overflow-hidden-bug/" target="_blank">blog post</a> for more information. (Thanks my colleague, Pavel Sergeev, in Russia, for pointing this out.)</p>
<h4>Other changes</h4>
<ul>
<li>When you upgrade jQuery to version 1.7, pay attention to any instance of jQuery.isNaN(), which is removed in this version of the library. Also, event.layerX/layerY is changed to event.originalEvent.layerX/layerY, so be sure to modify your code accordingly.</li>
<li>jQuery 1.7 is less forgiving about passing in non-function to, for example, .load(), when a function is expected. Prior to 1.7, it still worked if a setTimeout, which would return a timer ID, is directly being passed in to the event.</li>
<li>If you have any swf objects in your app, watch out for an &#8220;object expected&#8221; error in IE. It&#8217;s probably trying to do elem.getAttribute() on an elem that is an object DOM element (with the &lt;object&gt; tag).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/ie-bugs-caused-by-css-filter-fixed-in-jquery-1-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating Canvas into your Web App</title>
		<link>http://www.davidtong.me/integrating-canvas-into-your-web-app/</link>
		<comments>http://www.davidtong.me/integrating-canvas-into-your-web-app/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 21:13:12 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=662</guid>
		<description><![CDATA[My <a href="http://www.html5rocks.com/en/tutorials/canvas/integrating/" target="_blank">tutorial on HTML5 canvas</a> has finally been posted to <a href="http://www.html5rocks.com/" target="_blank">html5rocks</a>!]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://www.html5rocks.com/en/tutorials/canvas/integrating/" target="_blank">tutorial on HTML5 canvas</a> has finally been posted to <a href="http://www.html5rocks.com/" target="_blank">html5rocks</a>!</p>
<p>I demonstrated the integration of a Canvas editor and the <a href="http://www.box.net" target="_blank">Box</a> application during the <a href="http://blog.box.net/2010/12/14/coding-with-the-stars-our-second-box-hackathon/" target="_blank">Hackathon</a> in December, 2010. This article was written as a result of the project done by my colleague <a href="http://www.linkedin.com/in/hieunguyen08" target="_blank">Hieu Nguyen</a> and myself.</p>
<p>Thanks <a href="http://paulirish.com/" target="_blank">Paul Irish</a> and other friends at Google for reviewing the article.</p>
<p>It&#8217;s all basic stuff, but I hope you enjoy it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/integrating-canvas-into-your-web-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading jQuery &#8211; from 1.4.x to 1.6.x</title>
		<link>http://www.davidtong.me/upgrading-jquery-from-1-4-x-to-1-6-1/</link>
		<comments>http://www.davidtong.me/upgrading-jquery-from-1-4-x-to-1-6-1/#comments</comments>
		<pubDate>Sat, 28 May 2011 11:28:33 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=587</guid>
		<description><![CDATA[The jQuery library, specifically its architecture of Ajax handling, has been significantly re-written in 1.5. We at Box love jQuery, but we had to skip version 1.5 because a quick jquery.js file replacement failed many of our automated test cases. After a couple of weeks of debugging, we finally migrated to version 1.6.1. In this [...]]]></description>
			<content:encoded><![CDATA[<p>The jQuery library, specifically its architecture of Ajax handling, has been significantly re-written in 1.5. We at <a href="http://www.box.net">Box</a> love jQuery, but we had to skip version 1.5 because a quick jquery.js file replacement failed many of our automated test cases.</p>
<p>After a couple of weeks of debugging, we finally migrated to version 1.6.1. In this post, I want to share my experience upgrading jQuery from 1.4.4 to 1.6.1.</p>
<h3>prop() and attr()</h3>
<p><a href="http://api.jquery.com/prop/">prop()</a> is a new method to retrieve a property value of a DOM object, while <a href="http://api.jquery.com/attr/">attr()</a> is used to retrieve attribute values written in the HTML source.</p>
<p><a href="http://api.jquery.com/attr/">attr()</a> used to be the single method to handle both cases. Basically, in jQuery 1.4, attr() first checks if the attribute is explicitly written in the HTML code, then it looks at the object created by the HTML tag, and inspects its object property. When you upgrade to newer versions of jQuery, you may need to change attr() to prop().</p>
<p>In our code, we had something like this</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'method'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'post'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #006600; font-style: italic;">// do something</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>This code used to work in 1.4.x, but it fails in 1.6.1. I then found out it fails on this case:</p>
<div class="codecolorer-container html4strict vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">form</span></a> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;process.php&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">form</span></a>&gt;</span></div></td></tr></tbody></table></div>
<p>The problem is that, in 1.4, when a form has no method attribute written in the HTML code, it would return an empty string because method is a property, which happens to be an empty string, of the form object. However, in 1.6.1, the attr(&#8220;method&#8221;) call would return undefined because it is not written in the HTML code, and so doing toLowerCase() on undefined triggers error.</p>
<p>To fix the issue, we changed attr() to prop():</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">prop</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'method'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'post'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #006600; font-style: italic;">// do something</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>According to the <a href="http://api.jquery.com/prop/">documentation</a>, prop() should return undefined for the value of the property that has not been set. In reality, this is not true when doing prop(&#8216;method&#8217;) on a form. As previously stated, &#8220;method&#8221; is a property of a form object even if it&#8217;s not explicitly written in the HTML code.</p>
<p>This is not the end of the story. It turned out that the JavaScript block shown above still fails in a form that looks like this:</p>
<div class="codecolorer-container html4strict vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">form</span></a> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;action.php&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span><span style="color: #808080; font-style: italic;">&lt;!-- a bunch of input fields --&gt;</span> <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">input</span></a> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ratio&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;method&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;xml&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>XML <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">input</span></a> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ratio&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;method&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;json&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>JSON<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/form.html"><span style="color: #000000; font-weight: bold;">form</span></a>&gt;</span></div></td></tr></tbody></table></div>
<p>And when we do $(&#8216;form&#8217;).prop(&#8216;method&#8217;), instead of returning the string &#8220;post&#8221;, it returns two input elements! The reason, which should be obvious, is because there are two input fields that are named &#8220;method.&#8221; As a result, we need to add to the coding practice that no input elements should be named &#8220;method.&#8221;</p>
<p>You now probably see some of the benefits of separating prop() and attr(). In addition to clearing confusion between HTML attributes and DOM element properties, there are a few more benefits using prop() when it&#8217;s applicable:<br />
- From John Resig: &#8220;Accessing properties through the .attr() method will be slightly slower than accessing them directly through .prop() (as .attr() calls .prop() internally in order to handle all property-related mutation)&#8221;<br />
- Attributes like &#8216;checked&#8217; and &#8216;value&#8217; of input elements do not map to their corresponding properties in the DOM elements. So doing attr(&#8216;checked&#8217;) or attr(&#8216;value&#8217;) will only retrieve the default/ initial value, but not the current one. You browser uses the property, and not the attribute, to keep track of the current value. That is also the reason why in previous versions we had to do :is(&#8216;checked&#8217;) and .val(). Now that we have prop() and we can rely on it in getting the current value.<br />
- In previous versions of jQuery, both attr(&#8216;checked&#8217;, true) and attr(&#8216;checked&#8217;, &#8216;checked&#8217;) would work. When examining the value, we have to look for every possible values. Using prop, we are sure it would return boolean for things like &#8216;checked&#8217; and &#8216;readOnly.&#8217;</p>
<p>If you still find it confusing, visit <a href="http://www.timmywillison.com/2011/When-to-use-.attr()-and-.prop().html" target="_blank">http://www.timmywillison.com/2011/When-to-use-.attr()-and-.prop().html</a> for a list of recommended usage.</p>
<h3>Ajax and parseJSON</h3>
<p>In the Box app, we use <a href="http://api.jquery.com/jQuery.ajaxPrefilter/">$.ajaxPrefilter</a> to handle Ajax calls that are supposed to return a JSON object. Our unique approach is that the backend actually returns what we called BOXON (BOX Object Notation) strings, and we use ajaxPrefilter to convert BOXON to JSON by modifying the string and calling eval(). In then becomes a JavaScript object.</p>
<p>This no longer works in jQuery 1.6.1 (and probably 1.5+). Basically, the new Ajax architecture in jQuery would call $.parseJSON() after ajaxPrefilter. Here is the first few lines of $.parseJSON():</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">parseJSON<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> data <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> data <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;string&quot;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span>data <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #006600; font-style: italic;">//...</span><br />
<span style="color: #006600; font-style: italic;">// convert the &quot;data&quot; string into an object and return that</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Because data, when coming from our own ajaxPrefilter, is already an object, the JSON object becomes null after parseJSON, and thus the Ajax calls get a null value to work on.</p>
<p>To fix this issue, I had to patch the jQuery code like this:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">parseJSON<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> data <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> data <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;object&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> data<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">/* true for both Array and Object */</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> data <span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;string&quot;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span>data <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h3>getAttribute on Flash objects</h3>
<p>We also got a weird bug that occurred in IE9 only. After we moved to 1.6.1, the &#8220;upload&#8221; button won&#8217;t work!</p>
<p>After some investigation, I found that it&#8217;s related to our very own upload approach. We use HTML5 upload on browsers that support it. IE9 is not one of those browsers, and so we use a SWF object to handle it. Somewhere in the code, it triggers a click event on the SWF object that checks for $.(e.target).attr(&#8216;id&#8217;) == &#8216;something&#8217;. SWF objects do not implement the getAttribute() DOM method, and so it fails.</p>
<p>This is such a race case and probably will not be seen in your application. A quick fix I added to the code is to return immediately in the custom mousedown/ click function if the target does not implement the .getAttribute method.</p>
<h3>Plugins</h3>
<p>Many popular jQuery plugins have to be upgraded to become compatible with the latest version of jQuery. For example, The<a href="http://jquery.malsup.com/form/#getting-started"> jQuery Form plugin</a> needs to be upgraded to 2.80. One of the reasons is that jQuery has removed the internal $.httpData() method since version 1.5. Plugins that make use of these methods need to be rewritten.</p>
<p>The <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery validation plugin</a> is another plugin that needs an upgrade. It works perfectly once we upgrade it to the latest version of 1.8.</p>
<h3>Sweet, now we&#8217;re on the new train!</h3>
<p>I am very happy about the new version of jQuery. In addition to the aforementioned new Ajax architecture (which brings good stuff like &#8220;<a href="http://api.jquery.com/category/deferred-object/">deferred</a>&#8220;), there are <a href="http://jsperf.com/dh-jquery-1-4-vs-1-6">performance improvements</a> (also see <a href="http://bugs.jquery.com/ticket/7341">http://bugs.jquery.com/ticket/7341</a>. Now I don&#8217;t have to modify the Sizzle engine to make it faster in IE!), and a lot of nice fixes and features. If you have not upgraded yet due to compatibility issues like the ones described above, I suggest you to take some time to do some investigation and adjust the code. Don&#8217;t stay behind and miss out the good things the new version of jQuery brings to the table.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/upgrading-jquery-from-1-4-x-to-1-6-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Popup blocker detection pattern</title>
		<link>http://www.davidtong.me/detecting-popup-blocker-pattern/</link>
		<comments>http://www.davidtong.me/detecting-popup-blocker-pattern/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 01:36:26 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[popup]]></category>
		<category><![CDATA[popup blocker]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=569</guid>
		<description><![CDATA[Have you ever wondered why popup blockers hate certain popup windows, but not others? The underneath formula is pretty simple: if a window.open() call is not on top of a click event in the call stack, popup blockers would block it unless it&#8217;s on the exception list. This can be verified using Firebug or Chrome [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered why popup blockers hate certain popup windows, but not others?</p>
<p>The underneath formula is pretty simple: if a window.open() call is not on top of a click event in the call stack, popup blockers would block it unless it&#8217;s on the exception list. This can be verified using Firebug or Chrome Developer Tools.</p>
<div class="img aligncenter size-medium wp-image-582" style="width:300px;">
	<a href="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/04/popup_blocker_click_stack.png" rel="lightbox[569]"><img src="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/04/popup_blocker_click_stack-300x92.png" alt="" width="300" height="92" /></a>
	<div>Call stack of window.open() triggered indirectly from a click event</div>
</div>
<div class="img aligncenter size-medium wp-image-583" style="width:300px;">
	<a href="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/04/popup_blocker_ajax_stack.png" rel="lightbox[569]"><img src="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/04/popup_blocker_ajax_stack-300x93.png" alt="" width="300" height="93" /></a>
	<div>Call stack of window.open() triggered from an Ajax callback</div>
</div>
<p>Therefore, the rule of thumb is that <strong>you should avoid calling window.open() from anything other than an user-initiated click event</strong>. </p>
<p>What if it&#8217;s a design requirement, or if it really works better for your application to call window.open() arbitrarily?</p>
<p>We used to be able to easily detect whether a popup window is opened successfully. When a popup window is created using window.open(), it would return an reference object to the new window if it&#8217;s successful, and null if something prevents it from opening. This works for all major browsers except the latest versions of Chrome (9 and 10), which always return an object.</p>
<p>This is explained in this <a href="Chromium ticket">Chromium ticket</a>. The popup blocker in Chrome actually just hides the popup window behind the scene instead of blocking it from opening.</p>
<p>Until the Chromium ticket is closed, this is probably the most universal way of detecting popup blockers:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// try to create a popup</span><br />
<span style="color: #003366; font-weight: bold;">var</span> popup <span style="color: #339933;">=</span> window.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>popup <span style="color: #339933;">||</span> popup.<span style="color: #660066;">closed</span> <span style="color: #339933;">||</span> parseInt<span style="color: #009900;">&#40;</span>popup.<span style="color: #660066;">innerWidth</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">//POPUP BLOCKED</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Please disable your browser popup blocker in order to continue.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>For most browsers, !popup is sufficient. In case the popup is closed immediately, its closed property would be set to true. For Chrome, the window.open() would return an object, and so detecting its innerWidth (or innerHeight, outerWidth, outerHeight&#8230; your choice) after a timeout should work.</p>
<p>Here is my recommended pattern of detecting and solving popup blocker issues:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// For large applications, you probably need a name for the window to prevent multiple window for the same goal</span><br />
<span style="color: #003366; font-weight: bold;">var</span> name_of_popup <span style="color: #339933;">=</span> <span style="color: #3366CC;">'new_window_123'</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// This works just fine unless there is a popup blocker</span><br />
<span style="color: #003366; font-weight: bold;">var</span> popup <span style="color: #339933;">=</span> window.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>...<span style="color: #339933;">,</span> name_of_popup<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// Detect popup blocker</span><br />
setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>popup <span style="color: #339933;">||</span> popup.<span style="color: #660066;">closed</span> <span style="color: #339933;">||</span> parseInt<span style="color: #009900;">&#40;</span>popup.<span style="color: #660066;">innerWidth</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Close the window that is hidden behind Chrome's popup blocker</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// This is useful because you can then reclaim the name of the window that is being hidden</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Without this, window.open(..., name_of_popup, ...) will be blocked because it is currently hidden by Chrome</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; popup <span style="color: #339933;">&amp;&amp;</span> popup.<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// This is just an example. Won't work unless you have popup() defined</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Use your own alert framework or modal plugin to allow user-initiated window.open()</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; popup<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Please disable your browser popup blocker in order to continue. You may also &lt;a href=&quot;</span>#<span style="color: #3366CC;">&quot; id=&quot;</span>popup_openbox_blocked<span style="color: #3366CC;">&quot;&gt;click here to open the window.&lt;/a&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// Attach click event to the link</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; $j<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#popup_openbox_blocked'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// window.open() works here because it is initiated by an user's click action</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// We prefer window.open() to the anchor's href action because we want to save the return reference from window.open</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> new_window <span style="color: #339933;">=</span> window.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>...<span style="color: #339933;">,</span> name_of_popup<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; popup.<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Close the custom alert. Won't work unless you have popup() defined</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/detecting-popup-blocker-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switching between box models 2011</title>
		<link>http://www.davidtong.me/switching-between-box-models-2011/</link>
		<comments>http://www.davidtong.me/switching-between-box-models-2011/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 03:18:26 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=538</guid>
		<description><![CDATA[Do we all hate IE because the IE box model makes more sense? For those who don&#8217;t know and are lazy to look it up, prior to IE 6, IE used to include border and padding in its calculation of the width (and height) of a page element. This is different than the &#8220;standard&#8221; W3C [...]]]></description>
			<content:encoded><![CDATA[<p>Do we all hate IE because the <a href="http://www.quirksmode.org/css/box.html" target="_blank">IE box model</a> makes more sense?</p>
<p>For those who don&#8217;t know and are lazy to <a href="http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug" target="_blank">look it up</a>, prior to IE 6, IE used to include border and padding in its calculation of the width (and height) of a page element. This is different than the &#8220;standard&#8221; W3C box model, which defines width as only the width of the content, not including padding and border.</p>
<div class="img size-full wp-image-545 alignright" style="width:68px;">
	<a href="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/03/box_8.png" style="float: right; rel="lightbox[538]"><img src="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/03/box_8.png" alt="" width="68" height="65" /></a>
	<div>Box Model?</div>
</div>
<p>In IE 6 and 7, you have to manually enable the W3C box model by adding a doctype. IE 8 uses the standard box model by default. This makes IE more consistent with other browsers.</p>
<p>However, a lot people find the old IE box model more intuitive. In fact, if you set a 100px width to an element, you want it to be 100px; nothing less, nothing more. You won&#8217;t want it to appear bigger and screw your page up when there&#8217;s padding and border.</p>
<p>You can actually enable the IE box model on other browsers by doing this:</p>
<div class="codecolorer-container css vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="css codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* enable good-old IE box model on all divs<br />
** add to the selector for wider adoption<br />
*/</span><br />
div <span style="color: #00AA00;">&#123;</span><br />
-moz-box-sizing<span style="color: #00AA00;">:</span> border-box<span style="color: #00AA00;">;</span><br />
-webkit-box-sizing<span style="color: #00AA00;">:</span> border-box<span style="color: #00AA00;">;</span><br />
box-sizing<span style="color: #00AA00;">:</span> border-box<span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span></div></td></tr></tbody></table></div>
<p>border-box means that the width (or height) is calculated border-to-border (border + padding + content width). The opposite (default) value is content-box.</p>
<p>Pretty cool huh?</p>
<p>Humm&#8230; not really. It&#8217;s only supported by IE8 (more on IE8 later), Webkit browsers (e.g. Chrome) and Mozilla browsers (e.g. Firefox). We&#8217;re missing IE6 and IE7.</p>
<p>Unless you don&#8217;t care about IE6 and IE7, I recommend that you don&#8217;t use border-box to switch your box model.</p>
<p>If you are one of the pioneers who don&#8217;t give a ____ on those bad browsers, you still need to watch out its strange behavior on IE8.</p>
<p>On IE8, border-box applies to width and height. It does not apply to min-width and min-height! That means if a container has a min-height, it&#8217;s going to exclude the padding and border in the calculation even if border-box is applied. The container will appear taller than expected in this case.</p>
<p>You can try it out on this test page: <a href="http://jsfiddle.net/XS2JF/" target="_blank">http://jsfiddle.net/XS2JF/</a>. The one with border-box should be shorter, but they appear the same on IE8.</p>
<p>Conclusion: let&#8217;s not deal with box models anymore. It&#8217;s not yet 2013.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/switching-between-box-models-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>z-index misconceptions, IE bugs and fixes</title>
		<link>http://www.davidtong.me/z-index-misconceptions-bugs-fixes/</link>
		<comments>http://www.davidtong.me/z-index-misconceptions-bugs-fixes/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 03:10:52 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[z-index]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=500</guid>
		<description><![CDATA[Update (12/1/2011): Version 1.2 In the past 13 years, I have worked on numerous issues related to layering, specifically the z-index CSS property. It is one of the most misunderstood CSS properties. Surprisingly, there are not many well-written articles or tutorials on this topic. I came across this blog post that talks about the way to [...]]]></description>
			<content:encoded><![CDATA[<div>
Update (12/1/2011): Version 1.2</p>
<p>In the past 13 years, I have worked on numerous issues related to layering, specifically the z-index CSS property. It is one of the most misunderstood CSS properties. Surprisingly, there are not many well-written articles or tutorials on this topic.</p>
<p>I came across <a href="http://brenelz.com/blog/squish-the-internet-explorer-z-index-bug/">this blog post</a> that talks about the way to fix a z-index issue. It works as it nails the key point about the parent element, but there isn&#8217;t much explanation. You can find all the misconceptions written by other readers.</p>
<p>To understand what z-index is, I find <a href="http://www.smashingmagazine.com/2009/09/15/the-z-index-css-property-a-comprehensive-look/">this</a> to be the best beginner&#8217;s post. <a href="http://css-discuss.incutio.com/wiki/Overlapping_And_ZIndex">This post</a> went a step further into the concept of &#8220;stacking contexts,&#8221; which is the major reason of all the bugs you would encounter.</p>
<p>Here are the top two misconceptions:</p>
<ul>
<li><em>People say&#8230; &#8220;z-indexes are &#8220;absolute&#8221;. If an element has a high z-index, e.g. 9999, it should always stay on top of everything.&#8221; </em><br />
The truth is&#8230; WRONG! An element with a z-index would stay below or above other elements in the same stacking context only! That means, if an element with a z-index 9999 that is a descendant of an element that has z-index -1 (negative one), the element is still invisible because ultimately it&#8217;s being affected by its ancestor that has a negative one z-index.</li>
<li><em>People say&#8230; &#8220;without z-indexes declared, the default should always be auto.&#8221; </em><br />
The truth is&#8230; not on IE. If an element has a position CSS property other than the default &#8220;static&#8221; (i.e. absolute or relative), Internet Explorer is always implicitly giving it a 0 (zero) z-index value. When a bunch of elements with positions come together, whatever appearing later in the document structure will stay on top of elements that appear earlier in the document structure (or the DOM tree).<br />
(A more technical way to explain this issue is that IE is creating a new stacking context on each of these elements, but it&#8217;s less easy to understand so I skip it here and stick with the implicit zero z-index explanation.)</li>
</ul>
<p>Let&#8217;s look at an example:</p>
<div class="img " style="width:300px;">
	<a href="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/02/2011-02-03_1639.png" rel="lightbox[500]"><img src="http://www.davidtong.me/omgthisisawesome/wp-content/uploads/2011/02/2011-02-03_1639-300x230.png" alt="" width="300" height="230" /></a>
	<div>z-index issue on IE</div>
</div>
<p>In this screenshot, the drop-down menu appears below the next gray area. While the drop-down menu has a high z-index value, the two areas (&lt;li&gt; elements) do not have any z-index values! Why the hell would elements with no z-index value cover one with high z-index value?</p>
<p>The bug is caused by the implied zero (0) z-index when position (position: relative in this case) is used. Because the last gray area appears later in the document, it is on top of the second last gray area, even though they have have an implied z-index value of 0. The drop-down menu is a descendant of the parent gray area that has 0 z-index value, so it is eventually covered by the last gray area.</p>
<p>To fix it, you can simply hardcode z-index:1 (or any value greater than 0) to the gray area that contains the drop-down menu, and make sure the bottom gray area has 0 z-index (or no z-index).</p>
<p>In a complex web app or any <a href="http://www.stubbornella.org/content/2009/03/23/object-oriented-css-video-on-ydn/" target="_blank">component-based web design</a>, however, this may not be desired. If you care about the new best practice of object-oriented CSS, you should not hardcode CSS inline, and you should never target a specific instance of the generic CSS class to have a special CSS value.</p>
<p>Because of the reasons above, and maybe you are just lazy to find out what container to apply additional z-index, you can apply this z-index fixer jQuery plugin that I wrote for these issues. What it does is that given a jQuery object, it would go up the DOM to check if any of its ancestors is relatively positioned. Then it adds a high z-index to it to make sure that the the whole family line has high z-index values.</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">/* Fixes z-index issues - Version 1.2<br />
Update v1.2 - fixed an issue when this is being called on an element that is not in the DOM tree.<br />
<br />
This plugin fixes z-index issues typically occur in IE. It traverses up the DOM to make sure that all the ancestors of the target element have a high z-index value.<br />
<br />
This fixes a common z-index issue that an element with high z-index is showing underneath its ancestor's sibling that has the same explicit or implicit (e.g. IE's implied zero z-index when position: relative is applied) z-index as the corresponding ancestor.<br />
For IE 6's z-index issues with input boxes, see the jQuery bgiframe plugin.<br />
<br />
www.davidtong.me/z-index-misconceptions-bugs-fixes/<br />
<br />
param obj:<br />
&nbsp; &nbsp; recursive: boolean (default: true) - set to false to reduce the number of loops and if it still works, go for false<br />
&nbsp; &nbsp; exclude: string - a list of class names to be excluded in the fix<br />
&nbsp; &nbsp; msieOnly: boolean (default: false) - set to true to only apply the fix to IE browsers<br />
&nbsp; &nbsp; zIndex: string (default: '9999') - a big number that should just be high enough to make the element-to-be-fixed stay on top of other elements<br />
*/</span><br />
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $.<span style="color: #660066;">fn</span>.<span style="color: #660066;">fixZIndex</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>params<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; params <span style="color: #339933;">=</span> params <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>params.<span style="color: #660066;">msieOnly</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>$.<span style="color: #660066;">browser</span>.<span style="color: #660066;">msie</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> num_of_jobj <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> num_of_jobj<span style="color: #339933;">;</span> i<span style="color: #339933;">--;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> curr_element <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> config_recursive <span style="color: #339933;">=</span> params.<span style="color: #660066;">recursive</span> <span style="color: #339933;">||</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> config_exclude <span style="color: #339933;">=</span> params.<span style="color: #660066;">exclude</span> <span style="color: #339933;">||</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>curr_element <span style="color: #339933;">!=</span> document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>$<span style="color: #009900;">&#40;</span>curr_element<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span>config_exclude<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span>curr_element<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'position'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'relative'</span> <span style="color: #339933;">||</span> $<span style="color: #009900;">&#40;</span>curr_element<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'position'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'absolute'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span>curr_element<span style="color: #339933;">,</span> <span style="color: #3366CC;">'zIndex'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> undefined<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span>curr_element<span style="color: #339933;">,</span> <span style="color: #3366CC;">'zIndex'</span><span style="color: #339933;">,</span> curr_element.<span style="color: #660066;">style</span>.<span style="color: #660066;">zIndex</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">'-1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curr_element.<span style="color: #660066;">style</span>.<span style="color: #660066;">zIndex</span> <span style="color: #339933;">=</span> params.<span style="color: #660066;">zIndex</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">'9999'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curr_element <span style="color: #339933;">=</span> curr_element.<span style="color: #660066;">parentNode</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>config_recursive<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// optional function to restore z-index if needed</span><br />
&nbsp; &nbsp; $.<span style="color: #660066;">fn</span>.<span style="color: #660066;">restoreZIndex</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>params<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; params <span style="color: #339933;">=</span> params <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>params.<span style="color: #660066;">msieOnly</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>$.<span style="color: #660066;">browser</span>.<span style="color: #660066;">msie</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> num_of_jobj <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> num_of_jobj<span style="color: #339933;">;</span> i<span style="color: #339933;">--;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> curr_element <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> config_exclude <span style="color: #339933;">=</span> params.<span style="color: #660066;">exclude</span> <span style="color: #339933;">||</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>curr_element <span style="color: #339933;">&amp;&amp;</span> curr_element <span style="color: #339933;">!=</span> document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> currZIndex <span style="color: #339933;">=</span> $.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span>curr_element<span style="color: #339933;">,</span> <span style="color: #3366CC;">'zIndex'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currZIndex <span style="color: #339933;">&gt;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>$<span style="color: #009900;">&#40;</span>curr_element<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span>config_exclude<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curr_element.<span style="color: #660066;">style</span>.<span style="color: #660066;">zIndex</span> <span style="color: #339933;">=</span> currZIndex<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.<span style="color: #660066;">removeData</span><span style="color: #009900;">&#40;</span>curr_element<span style="color: #339933;">,</span> <span style="color: #3366CC;">'zIndex'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currZIndex <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curr_element.<span style="color: #660066;">style</span>.<span style="color: #660066;">zIndex</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curr_element <span style="color: #339933;">=</span> curr_element.<span style="color: #660066;">parentNode</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>jQuery<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Example:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// .inner_div is covered by other page elements. Use fixZIndex plugin to fix.</span><br />
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.inner_div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fixZIndex</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>recursive<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> msieOnly<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> zIndex<span style="color: #339933;">:</span> <span style="color: #CC0000;">15</span><span style="color: #339933;">,</span> exclude<span style="color: #339933;">:</span> <span style="color: #3366CC;">'.page_container'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>// When we hide .inner_div, restore z-index (optional)<br />
$(&#8216;.inner_div&#8217;).restoreZIndex();</p>
<p>Using IE (6, 7 or 8), and open the <a href="http://jsfiddle.net/davidtong/mxdTs/">demo page</a> or see the iframe below. Uncomment the last line in the JavaScript portion to enable the fix.</p>
<p><iframe style="width: 100%; height: 300px;" src="http://jsfiddle.net/davidtong/mxdTs/embedded/" width="320" height="240"></iframe></p>
<p>Note that this plugin does not solve IE6&#8242;s bug that form elements always stay on top of other page elements. The solution for that particular bug is at <a href="http://brandonaaron.net/code/bgiframe/docs/">http://brandonaaron.net/code/bgiframe/docs/</a></p>
<p>Thanks Zak Stein and Adam Platti&#8217;s suggestions to put this plugin to work.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/z-index-misconceptions-bugs-fixes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Code Standards &amp; Best Practices</title>
		<link>http://www.davidtong.me/code-standards-front-end-development-best-practices/</link>
		<comments>http://www.davidtong.me/code-standards-front-end-development-best-practices/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 00:34:01 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[code standards]]></category>
		<category><![CDATA[front-end]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=466</guid>
		<description><![CDATA[This is the code standards doc that my previous team at Isobar/ Molecular created in early 2010. It was wildly circulated since its release. The doc contains a lot of knowledge that we have gathered in our combined 100+ years of web experience. You may find it useful if you are curious what best practices [...]]]></description>
			<content:encoded><![CDATA[<p>This is the code standards doc that my previous team at Isobar/ Molecular created in early 2010. It was wildly circulated since its release. The doc contains a lot of knowledge that we have gathered in our combined 100+ years of web experience. You may find it useful if you are curious what best practices that third-party agencies are following.</p>
<p><a href="http://na.isobar.com/standards/" target="_blank">http://na.isobar.com/standards/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/code-standards-front-end-development-best-practices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE8 Developer Tools won&#8217;t open</title>
		<link>http://www.davidtong.me/ie8-developer-tools-wont-open/</link>
		<comments>http://www.davidtong.me/ie8-developer-tools-wont-open/#comments</comments>
		<pubDate>Sat, 15 Jan 2011 00:21:44 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[tools and apps]]></category>
		<category><![CDATA[developer tools]]></category>
		<category><![CDATA[ie8]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=460</guid>
		<description><![CDATA[This may sound stupid, but I ran into this issue that upon pressing F12 or choosing Tools > Developer Tools, the IE Developer Tools window does not show up. It is, however, showing up in the task bar. The issue is that when you have Developer Tools detached from the browser window, and you don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>This may sound stupid, but I ran into this issue that upon pressing F12 or choosing Tools > Developer Tools, the IE Developer Tools window does not show up. It is, however, showing up in the task bar.</p>
<p>The issue is that when you have Developer Tools detached from the browser window, and you don&#8217;t close it before exiting the browser, the next time you open IE8 and try to run Developer Tools, the Developer Tools window will be an &#8216;invisible state&#8217; (simply put&#8230;).</p>
<p>The solution is to right-click on the tab/ icon in your Windows task bar and choose Maximize. If there is no such option in Windows 7, hover on the tab/ icon in the task bar for a moment until an overlay pops up that shows all the IE8 instances and the Developer Tools representation view, right-click on the Developer Tools&#8217; representation view and choose Maximize. Alternatively, you may do Alt+Spacebar, then hit &#8216;m&#8217; and start using your arrow keys to move the window around. You will then be glad to see your long-lost friend!</p>
<p>It sounds stupid, but this is still a kind of IE bug.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/ie8-developer-tools-wont-open/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Javascript shorthand for string comparison</title>
		<link>http://www.davidtong.me/javascript-shorthand-for-string-comparison/</link>
		<comments>http://www.davidtong.me/javascript-shorthand-for-string-comparison/#comments</comments>
		<pubDate>Fri, 17 Dec 2010 02:10:14 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[string comparison]]></category>

		<guid isPermaLink="false">http://www.davidtong.me/?p=437</guid>
		<description><![CDATA[Do you write this kind of code? (string1 == "test" or string1 == "staging" or string1 == "dev" or string1 == "internal" or string1 == "beta") Think twice!]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve decided to write a short article just to keep up the momentum.</p>
<p>Very often, we do something like this:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> string1 <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;textbox1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>string1 <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;test&quot;</span> or string1 <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;staging&quot;</span> or string1 <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;dev&quot;</span> or string1 <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;internal&quot;</span> or string1 <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;beta&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;banner&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;This app is not the live app!&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>The string comparison part is just tedious.</p>
<p>Try to do this instead</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>test<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> staging<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> dev<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> internal<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> beta<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span>string1<span style="color: #009900;">&#93;</span></div></td></tr></tbody></table></div>
<p>and so the demo block becomes</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> string1 <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;textbox1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>test<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> staging<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> dev<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> internal<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> beta<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span>string1<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;banner&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;This app is not the live app!&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Very neat huh? If the string matches one of those in the associative array, it will return 1, and else undefined. If you want to go even more fancy, try out the operator &#8216;in&#8217;:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> string1 <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;textbox1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>string1 <span style="color: #000066; font-weight: bold;">in</span> <span style="color: #009900;">&#123;</span>test<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> staging<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> dev<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> internal<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> beta<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;banner&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;This app is not the live app!&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Or even this&#8230;</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;banner&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;textbox1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span> <span style="color: #000066; font-weight: bold;">in</span> <span style="color: #009900;">&#123;</span>test<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> staging<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> dev<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> internal<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> beta<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">&quot;This app is not the live app!&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>What other rarely-used shorthands can you come up with?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/javascript-shorthand-for-string-comparison/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Attaching events to disabled input elements</title>
		<link>http://www.davidtong.me/attaching-events-on-disabled-form-elements/</link>
		<comments>http://www.davidtong.me/attaching-events-on-disabled-form-elements/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 02:56:44 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[interaction development]]></category>
		<category><![CDATA[disabled]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[readonly]]></category>

		<guid isPermaLink="false">http://www.davidalism.com/?p=394</guid>
		<description><![CDATA[I encountered an issue that all the attached mouseover and mouseevent events on a disabled checkbox &#60;input type=&#8221;checkbox&#8221; disabled=&#8221;disabled&#8221;/&#62; failed to work. After verifying the issue from a few references, I confirmed that this is an expected behavior of a disabled form element (button, input, optgroup, option, select or textarea). Many argued that if a [...]]]></description>
			<content:encoded><![CDATA[<p>I encountered an issue that all the attached mouseover and mouseevent events on a disabled checkbox &lt;input type=&#8221;checkbox&#8221; disabled=&#8221;disabled&#8221;/&gt; failed to work. After verifying the issue from a few references, I confirmed that this is an expected behavior of a disabled form element (button, input, optgroup, option, select or textarea).</p>
<p>Many argued that if a form element is disabled, it should not trigger any event. However, for various reasons, I just need it to trigger certain events.</p>
<p>For example, I may want a tooltip to appear when you hover on a disabled field to explain why the field is disabled. This requires a mouseover element to be triggered upon mouseover.</p>
<p>My specific problem is a special one. The checkbox is in a drop-down menu, which disappears when the mouse cursor is moved outside of the menu area (via a mouseout event on the menu). However, when you hover on the checkbox, it is considered a mouseout event of the menu, and so the menu would disappear. One way to fix that is to set a variable (bHoverMenu) to true when you hover on the checkbox. The mouseout event of the menu does a brief time out to allow sufficient time for the checkbox&#8217;s mouseover event to set the value of the variable bHoverMenu. Eventually, the mouseout event of the menu checks for the variable bHoverMenu to determine if the menu needs to be closed. Obviously, there needs to be a mouseover event on the checkbox in order to set bHoverMenu to avoid falsely closing the menu.</p>
<p>Long story short, I just need events to function on my disabled form elements.</p>
<p>After some research, I found a solution from <a href="http://blog.pengoworks.com/index.cfm/2010/4/23/Attaching-mouse-events-to-a-disabled-input-element" target="_blank">Dan G. Switzer, II</a>. Basically, the solution is to &#8220;add an overlay over the disabled element which I&#8217;d use as the hotspot for mouse interaction. The overlay lays on top of the element and intercepts all mouse interaction.&#8221; This is a very neat solution, but I want a slightly simpler solution that requires less code and perhaps does less DOM manipulation if that&#8217;s possible.</p>
<h3>readonly vs disabled</h3>
<p>I then looked up the list of attributes that a form element takes, and noticed that &#8220;readonly&#8221; may be of use. Instead of using the &#8220;disabled&#8221; attribute, we can actually use &#8220;readonly&#8221;, which does not disable any events attached to the element.</p>
<p>However, &#8220;readonly&#8221; merely prevents users from changing the value of a form element, not from interacting with it, and so you can still alter the &#8220;checked&#8221; attribute of a checkbox even if &#8220;readonly&#8221; is set. I found another <a href="http://kreotekdev.wordpress.com/2007/11/08/disabled-vs-readonly-form-fields/" target="_blank">article </a>that explains more about the differences between these two attributes.</p>
<p>To fix this issue, we only need to make sure that when the readonly attribute is set, the checkbox is always unchecked. The following piece of code in jQuery will do the job:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">readOnly</span><span style="color: #009900;">&#41;</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'checked'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container html4strict vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/input.html"><span style="color: #000000; font-weight: bold;">input</span></a> <span style="color: #000066;">readonly</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;readonly&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;checkbox&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></td></tr></tbody></table></div>
<p>And if your input element is wrapped by a label or some other container (such as a LI), you may do this</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.wrapperClass'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> input <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>input<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">readOnly</span><span style="color: #009900;">&#41;</span> $<span style="color: #009900;">&#40;</span>input<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'checked'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>I think this is pretty compact and sweet. Similar code can be applied to other form fields with just a little adjustment.</p>
<p>Bonus: In Chrome, a disable checkbox looks exactly like a checkbox that is read-only. This is not true for all browsers, and it requires some <a href="http://www.456bereastreet.com/lab/styling-form-controls-revisited/checkbox/" target="_blank">styling </a>to make it grey-out. In my opinion, this isn&#8217;t a critical issue as long as you have a label indicating the field is disabled and you have the code (from above) that disables any interaction on the checkbox.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidtong.me/attaching-events-on-disabled-form-elements/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

