<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;D0YNRng4eSp7ImA9WhVUF00.&quot;"><id>tag:blogger.com,1999:blog-30404818</id><updated>2012-05-22T11:46:37.631-05:00</updated><category term="Random" /><category term="Visual Studio" /><category term="Book Review" /><category term="Twitter" /><category term="Riddle" /><category term="Joke" /><category term="jQuery" /><category term="Amplify" /><category term="Regular Expressions" /><category term="Podcast" /><category term="Sublime Text 2" /><category term="Cheat Sheet" /><category term="Screencast" /><category term="Find the jQuery Bug" /><category term="MVC Contrib" /><category term="jQuery Mobile" /><category term="Extensions" /><category term="jQuery UI" /><category term="Interview" /><category term="ASP.NET MVC" /><category term="CouchDB" /><category term="ASP.NET" /><category term="Quote" /><category term="Browser" /><category term="CoffeeScript" /><category term="Firefox" /><category term="Firebug" /><category term="NuGet" /><category term="Conference" /><category term="AmplifyJS" /><category term="Tools" /><category term="Humor" /><category term="Internet Explorer" /><category term="JavaScript" /><category term="Giveaway" /><category term="Health" /><category term="Unit Testing" /><category term=".NET" /><category term="HTML5" /><title>Web Dev .NET</title><subtitle type="html">Front-end Web Dev Tips, Tricks, and Tools</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>498</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/webdevnet" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="webdevnet" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DUIDQ3c5fSp7ImA9WhVUFkQ.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-1019224064507618908</id><published>2012-05-22T07:44:00.001-05:00</published><updated>2012-05-22T09:39:32.925-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-22T09:39:32.925-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>QUnit Composite Addon: Running Multiple jQuery Test Files</title><content type="html">&lt;h3&gt;

Introduction&lt;/h3&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-f5ev9AjbDLc/T7uK0MBLKbI/AAAAAAAAQVk/xju-gnr6mfI/s1600/qunit.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-f5ev9AjbDLc/T7uK0MBLKbI/AAAAAAAAQVk/xju-gnr6mfI/s200/qunit.png" width="198" /&gt;&lt;/a&gt;&lt;/div&gt;
When you start Unit Testing your application with QUnit you'll notice that you'll have lots of different QUnit files that thoroughly test one feature or component of your system.&lt;br /&gt;
&lt;br /&gt;
Instead of opening each one of those test files and running them separately, wouldn't it be nice if you could launch one file that would run all the tests?&lt;br /&gt;
&lt;br /&gt;
Thankfully, there is a addon for that and it's called the Composite addon!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
Composite is a QUnit addon that, when handed an array of files, will open each of those files inside of an iframe, run the tests and display the results as a single suite of QUnit tests. -- &lt;a href="https://github.com/jquery/qunit/tree/master/addons/composite"&gt;https://github.com/jquery/qunit/.../addons/composite&lt;/a&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;h3&gt;

Setup&lt;/h3&gt;
&lt;br /&gt;
Setting up the Composite addon is pretty easy. All you really need to do is to get the &lt;code&gt;qunit-composite.js&lt;/code&gt; and &lt;code&gt;qunit-composite.css&lt;/code&gt; files from the &lt;a href="https://github.com/jquery/qunit/tree/master/addons/composite"&gt;Composite Addon Repository&lt;/a&gt; in GitHub and then tell QUnit what test files are a part of your Test Suite! See the following for an example setup.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/2642015.js?file=fiddle.html"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;

Running Example&lt;/h3&gt;
&lt;br /&gt;
I've taken the Unit Tests from a couple of blog posts I've done recently (&lt;a href="http://www.elijahmanor.com/2011/07/filterbydata-jquery-plugin.html"&gt;filterByData jQuery Plugin: Select by HTML5 Data Attr Value&lt;/a&gt; &amp;amp; &lt;a href="http://www.elijahmanor.com/2011/07/jquery-dataattr-pseudo-selector.html"&gt;jQuery :dataAttr Pseudo Selector&lt;/a&gt;) and have decided to bundle them together using the QUnit Composite Addon.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/bCgV6/embedded/result,js,html,css,resources/presentation" style="height: 300px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
&lt;i&gt;NOTE: Normally your URLs will look much cleaner than these in this example. Since I'm running these tests in jsFiddle the resources are pointed to their jsFiddle hash appended with &lt;code&gt;/show&lt;/code&gt; so that they will render only the result.&lt;/i&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;h3&gt;

Running from the file:// Protocol&lt;/h3&gt;
&lt;br /&gt;
In order for this to work you must host your files in a web server because the Composite addon relies on making AJAX calls to pull in the other QUnit files. If you are trying to run the test from the &lt;code&gt;file://&lt;/code&gt; protocol then you will get an error and the tests will not run. If you want to run the tests from Google Chrome you can enable the &lt;code&gt;allow-file-access-from-files&lt;/code&gt; command line parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Mac: &lt;code&gt;open /Applications/Google\ Chrome.app --args --allow-file-access-from-files&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\path\to\chrome.exe --allow-file-access-from-files&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;/usr/bin/google-chrome --allow-file-access-from-files&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h3&gt;

Conclusion&lt;/h3&gt;
&lt;br /&gt;
Using the QUnit Composite addon is very handy to get a quick high level view of the health of your web application. There is some overhead when running all of the tests at one time, but by making it easier to run all of your tests makes the likelihood of you running them much higher than otherwise.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-1019224064507618908?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LdUBRicdlfiXfBPrnq6QNRFH2ZI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LdUBRicdlfiXfBPrnq6QNRFH2ZI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LdUBRicdlfiXfBPrnq6QNRFH2ZI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LdUBRicdlfiXfBPrnq6QNRFH2ZI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/1019224064507618908/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/05/qunit-compsite-addon-running-multiple.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1019224064507618908?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1019224064507618908?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/05/qunit-compsite-addon-running-multiple.html" title="QUnit Composite Addon: Running Multiple jQuery Test Files" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-f5ev9AjbDLc/T7uK0MBLKbI/AAAAAAAAQVk/xju-gnr6mfI/s72-c/qunit.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0ECRXc_eSp7ImA9WhVVFUs.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-1983426776335366353</id><published>2012-05-09T00:06:00.000-05:00</published><updated>2012-05-09T07:14:24.941-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-09T07:14:24.941-05:00</app:edited><title>jQuery HTML5 :dataAttr Pseudo Selector</title><content type="html">&lt;h3&gt;Problem&lt;/h3&gt;&lt;br /&gt;
A while back someone on twitter was asking me how they might find a set of DOM elements by using doing a partial search on their HTML5 data attribute.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;I'm not actually sure what type of use case you would need for such problem, but I thought it was an interesting issue to work on, so I went ahead and took a stab at solving it.&lt;/blockquote&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1844955.js?file=fiddle.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;Desired Solution&lt;/h3&gt;&lt;br /&gt;
In order to solve the above example of finding elements that start with a certain HTML5 data attribute, I wanted to follow a similar API to that of jQuery Attribute Selectors with the &lt;code&gt;^=&lt;/code&gt;, &lt;code&gt;$=&lt;/code&gt;, etc... syntax. The following is an example of how I thought the solution should look like.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1844955.js?file=selector.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;Custom Pseudo Selector&lt;/h3&gt;&lt;br /&gt;
In order to create an API like the above I needed to create a custom pseudo selector, much like what you've seen when using &lt;code&gt;:last&lt;/code&gt;, &lt;code&gt;:odd&lt;/code&gt;, &lt;code&gt;:eq( number )&lt;/code&gt;, and numerous other common selectors.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1844955.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;Unit Tests&lt;/h3&gt;&lt;br /&gt;
I didn't want to just have some code laying around that wasn't thoroughly tested, so I went ahead and created a set of unit tests to cover various scenarios. I could have kept going, but I thought the following was a decent set of tests to start with.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/ZZhQ6/embedded/result,js/presentation" style="height: 500px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-1983426776335366353?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/G6ZnW8c08WjEk3tojBvX1LX9RTU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G6ZnW8c08WjEk3tojBvX1LX9RTU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/G6ZnW8c08WjEk3tojBvX1LX9RTU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G6ZnW8c08WjEk3tojBvX1LX9RTU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/1983426776335366353/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2011/07/jquery-dataattr-pseudo-selector.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1983426776335366353?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1983426776335366353?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2011/07/jquery-dataattr-pseudo-selector.html" title="jQuery HTML5 :dataAttr Pseudo Selector" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EFQ3kycCp7ImA9WhVVEEg.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-5140870788603084254</id><published>2012-05-03T08:26:00.001-05:00</published><updated>2012-05-03T08:26:52.798-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-03T08:26:52.798-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Sublime Text 2" /><category scheme="http://www.blogger.com/atom/ns#" term="Twitter" /><title>Tweet Package for Sublime Text 2</title><content type="html">I was browsing through the list of available packages in Sublime Text 2 and noticed once entitled &lt;a href="https://github.com/rozboris/Sublime-Tweet"&gt;Sublime Tweet&lt;/a&gt; that caught my eye, so I thought I would try it out.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-w5hTT4CaThU/T6KDOW7K0vI/AAAAAAAAPL4/zRmdMDF1DgY/s1600/Screen+Shot+2012-05-03+at+7.56.58+AM+(1)+2.png" imageanchor="1" style="font-size: medium; font-weight: normal; margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-w5hTT4CaThU/T6KDOW7K0vI/AAAAAAAAPL4/zRmdMDF1DgY/s1600/Screen+Shot+2012-05-03+at+7.56.58+AM+(1)+2.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
How to Install&lt;/h3&gt;
&lt;br /&gt;
&lt;b&gt;With Package Control&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-XE4X8giYQmY/T6J-819J3tI/AAAAAAAAPLY/NOt0Q-wbkjM/s1600/Screen+Shot+2012-05-03+at+7.48.46+AM+(1).png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="316" src="http://1.bp.blogspot.com/-XE4X8giYQmY/T6J-819J3tI/AAAAAAAAPLY/NOt0Q-wbkjM/s320/Screen+Shot+2012-05-03+at+7.48.46+AM+(1).png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
The easiest way to install &lt;code&gt;Sublime Tweet&lt;/code&gt; is using &lt;a href="http://wbond.net/sublime_packages/package_control"&gt;Sublime Package Control&lt;/a&gt;. If you don't already have Package Control installed, then I highly recommend it. It is a very easy way to find and manage packages. &lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Open the Command Palette... &lt;code&gt;Shift-Cmd-P&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;Package Control: Install Package&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Sublime Tweet&lt;/code&gt; from the List&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;b&gt;Without Package Control&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It isn't necessary to have Package Control to install &lt;code&gt;Sublime Tweet&lt;/code&gt;. Instead you can clone the repository from GitHub into your Sublime Text 2 package directory. For detailed instructions on what path to use for your operating system please refer to the documentation on the &lt;a href="https://github.com/rozboris/Sublime-Tweet"&gt;Sublime Tweet&lt;/a&gt; repository on GitHub.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
How to Setup&lt;/h3&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-4lAb1gj3uag/T6KBPn7jCxI/AAAAAAAAPLw/kj0xXkKJUGU/s1600/Twitter+:+Authorize+an+application.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="239" src="http://3.bp.blogspot.com/-4lAb1gj3uag/T6KBPn7jCxI/AAAAAAAAPLw/kj0xXkKJUGU/s320/Twitter+:+Authorize+an+application.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
The first time you try to use &lt;code&gt;Sublime Tweet&lt;/code&gt; it will ask for authentication information.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Open the Command Palette... &lt;code&gt;Shift-Cmd-P&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;Tweet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A browser will open and Twitter will generate an authentication token for you&lt;/li&gt;
&lt;li&gt;Copy the authentication token and paste it into the prompt in Sublime Text&lt;/li&gt;
&lt;li&gt;Now you are all setup for using the package&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;h3&gt;
How to Use&lt;/h3&gt;
&lt;br /&gt;
&lt;b&gt;Sending a Tweet&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Open the Command Palette... &lt;code&gt;Shift-Cmd-P&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;Tweet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Type in your tweet and press enter&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;b&gt;Reading Your Timelime&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can also read your timelime and favorite, reply, and open embedded URLs, but I'll refer you to the documentation on the &lt;a href="https://github.com/rozboris/Sublime-Tweet"&gt;Sublime Tweet&lt;/a&gt; repository on GitHub.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-5140870788603084254?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MpldHFcIJMdaGlubO5iJD9XGGsc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MpldHFcIJMdaGlubO5iJD9XGGsc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MpldHFcIJMdaGlubO5iJD9XGGsc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MpldHFcIJMdaGlubO5iJD9XGGsc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/5140870788603084254/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/05/tweet-package-for-sublime-text-2.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5140870788603084254?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5140870788603084254?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/05/tweet-package-for-sublime-text-2.html" title="Tweet Package for Sublime Text 2" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-w5hTT4CaThU/T6KDOW7K0vI/AAAAAAAAPL4/zRmdMDF1DgY/s72-c/Screen+Shot+2012-05-03+at+7.56.58+AM+(1)+2.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0INQnc-eSp7ImA9WhVQF0w.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-5858107662844630487</id><published>2012-04-06T00:05:00.000-05:00</published><updated>2012-04-06T07:33:13.951-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-06T07:33:13.951-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Interview" /><title>Interviewed on The Code Project's Coder Series</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.codeproject.com/Articles/360527/A-Coder-Interview-With-Elijah-M" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-lS4PC78hSpU/T30TCSUSC0I/AAAAAAAAN1o/6CV3jsBUKIk/s1600/CodeProject_LogoURL.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
I was recently asked to participate in &lt;a href="http://www.codeproject.com/"&gt;The Code Project's&lt;/a&gt; A Coder Interview series by &lt;a href="http://terrencedorsey.com/"&gt;Terrence Dorsey&lt;/a&gt; (&lt;a href="http://twitter.com/tpdorsey"&gt;@tpdorsey&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
You can view the &lt;a href="http://www.codeproject.com/Articles/360527/A-Coder-Interview-With-Elijah-M"&gt;A Coder Interview With Elijah Manor&lt;/a&gt; from The Code Project website.&lt;br /&gt;
&lt;br /&gt;
The questions that I answer in the interview are…&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Who are you?&lt;/li&gt;
&lt;li&gt;What do you do?&lt;/li&gt;
&lt;li&gt;What is your development environment?&lt;/li&gt;
&lt;li&gt;What new tools, languages or frameworks interest you?&lt;/li&gt;
&lt;li&gt;What is your coding pet peeve?&lt;/li&gt;
&lt;li&gt;How did you get started programming?&lt;/li&gt;
&lt;li&gt;How has the developer community influenced your coding?&lt;/li&gt;
&lt;li&gt;What advice would you offer to an up-and-coming programmer?&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The following are some other notable interviews they have done recently...&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/Articles/277701/A-Coder-Interview-With-Dan-Mohl"&gt;A Coder Interview With Dan Mohl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/Articles/316687/A-Coder-Interview-With-Julie-Lerman"&gt;A Coder Interview With Julie Lerman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/Articles/327251/A-Coder-Interview-With-Dave-Ward"&gt;A Coder Interview With Dave Ward&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/Articles/300175/A-Coder-Interview-With-Phil-Haack"&gt;A Coder Interview With Phil Haack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/Articles/258168/A-Coder-Interview-With-Paul-Griffin"&gt;A Coder Interview With Paul Griffin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/Articles/342139/A-Coder-Interview-With-Chris-Sells"&gt;A Coder Interview With Chris Sells&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Thank you Code Project and Terrence Dorsey for the honor of being included in your coder interview series.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-5858107662844630487?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nkY1Y_sWDAGYYSwvDb15LxynXBE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nkY1Y_sWDAGYYSwvDb15LxynXBE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nkY1Y_sWDAGYYSwvDb15LxynXBE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nkY1Y_sWDAGYYSwvDb15LxynXBE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/5858107662844630487/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/04/interviewed-on-code-project.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5858107662844630487?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5858107662844630487?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/04/interviewed-on-code-project.html" title="Interviewed on The Code Project's Coder Series" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-lS4PC78hSpU/T30TCSUSC0I/AAAAAAAAN1o/6CV3jsBUKIk/s72-c/CodeProject_LogoURL.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkMMQ3w-fyp7ImA9WhVQFk4.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-8240680645932127959</id><published>2012-04-05T07:54:00.001-05:00</published><updated>2012-04-05T07:54:42.257-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-05T07:54:42.257-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Health" /><title>How a Programmer Lost 46 Pounds and Survived</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-pdgvQdlMelk/T30ZtSA8vAI/AAAAAAAAN1w/C85M_dUxIes/s1600/weight-loss-plateau.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://4.bp.blogspot.com/-pdgvQdlMelk/T30ZtSA8vAI/AAAAAAAAN1w/C85M_dUxIes/s320/weight-loss-plateau.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
So I started this journey 46 pounds ago on July 6th, 2011 weighing in at 196 pounds. That may not sound too bad, but keep in mind that I'm only 5' 6" tall!&lt;br /&gt;
&lt;br /&gt;
It seems every year I've been gaining more and more weight. A combination of stress, overeating, late night snacking, and eating a bunch of unhealthy foods brought me to where I was. I used to hold back and resist getting larger pants, but it soon became ridiculous trying to fit into clothes that I really shouldn't be wearing. So, I eventually got up to a 36` waist so I could fit comfortably.&lt;br /&gt;
&lt;br /&gt;
Near my heaviest weight an uncle of mine passed away from a heart attack. At the funeral I was approached by my sister and my aunt. They both showed concern for my condition. Deep down I knew I was at high risk for multiple health related problems, but having a relative die because of health issues opened my eyes.&lt;br /&gt;
&lt;br /&gt;
So, what did I do to loose weight? Well, it mostly began when I started a special &lt;a href="http://www.cp24.com/PDF/detox28day.pdf"&gt;MetaGenics Ultraclear Detox&lt;/a&gt; diet in another attempt to reduce or eliminate chronic headaches. The passing of my uncle and other health problems (pain in my legs) were additional encouragement for me to continue with this detox, to start exercising, and to continue eating well.&lt;br /&gt;
&lt;br /&gt;
The detox was a one month strict combination of reducing sugars, dairy, meat, carbs, and pretty much everything but vegetables, fruit, nuts, and brown rice. In addition I took a series of shakes and pills to attach and flush out any toxins that were in my body. After the month of this detox program my headaches were not any better, but physically I felt a lot better and I was loosing quite a bit of weight in the process. &lt;br /&gt;
&lt;br /&gt;
I could not have stuck to this program without my wife. Having her support was vital for me completing this detox successfully. Our grocery list changed quite a bit and she helped prepare meals that we can both eat that are healthy and delicious.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-DBCE-LSGVW0/T32Ton_NceI/AAAAAAAAN20/KXmMNvojZzo/s1600/pool.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/-DBCE-LSGVW0/T32Ton_NceI/AAAAAAAAN20/KXmMNvojZzo/s320/pool.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
The detox was not the only reason for my weight lose. I also was exercising quite regularly. I used to run outside, but that was too hard on my body. My shins would hurt, I'd get hot, and after about 15 minutes or so my arms would go numb! So, I was inspired by my 6yo daughter's swim lessons and decided to start swimming. As it turns out, swimming it is easy on my body and I stay pretty cool during the workout. About 4 times a week I go to our local YMCA and swim in the indoor lap pool. When I started swimming I could hardly swim a length of the pool without stoping to rest, but over time I worked up to swimming several laps at a time without resting. As of recent, I typically swim 1/2 mile during a workout.&lt;br /&gt;
&lt;br /&gt;
Now that the detox program is over I am still being very restrictive of what foods I eat. I do eat some meat, but I try to limit it to organic beef, chicken, or turkey and wild fish. I still try not to eat sugars, dairy, or carbs. So, what do I eat and drink then? Here are some items that I enjoy...&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Humus with vegetables&lt;/li&gt;
&lt;li&gt;Guacamole with vegetables&lt;/li&gt;
&lt;li&gt;Raw cashews and cranberries or raisins&lt;/li&gt;
&lt;li&gt;Rice Cake with turkey and avocado&lt;/li&gt;
&lt;li&gt;Rice Cake with almond Butter&lt;/li&gt;
&lt;li&gt;Brown rice sushi&lt;/li&gt;
&lt;li&gt;Black been salad and Shish Kabobs&lt;/li&gt;
&lt;li&gt;Blueberries, almond Butter, and stevia&lt;/li&gt;
&lt;li&gt;Lime water with stevia&lt;/li&gt;
&lt;li&gt;Water with blueberries at the bottom&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.dandyblend.com/"&gt;Dandy Blend&lt;/a&gt; with stevia in place of coffee&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.larabar.com/"&gt;LÄRABAR&lt;/a&gt; for a snack&lt;/li&gt;
&lt;li&gt;Apple and almond butter&lt;/li&gt;
&lt;li&gt;Etc...&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-_3oQ0SSs8Ss/T30aBJs35II/AAAAAAAAN14/weO2ioPXAI4/s1600/about-our-recipes.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="186" src="http://1.bp.blogspot.com/-_3oQ0SSs8Ss/T30aBJs35II/AAAAAAAAN14/weO2ioPXAI4/s320/about-our-recipes.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
In addition to the above items a lot of what we eat these days comes from the &lt;a href="http://store.maximizedliving.com/Scripts/prodView.asp?idproduct=140"&gt;MaximizedLiving Nutrition Plans&lt;/a&gt; cookbook.&lt;br /&gt;
&lt;br /&gt;
As a developer who speaks regularly, I am finding it difficult to find things I can eat while I'm away from home. It seems everything is fried, has carbohydrates, or added sugar. I typically bring with me several snack baggies of nuts, dried fruit, and lara bars. I keep my pockets full of stevia packets just in case I need it while away from home. &lt;br /&gt;
&lt;br /&gt;
If you know you are overweight and have been looking for a reason to change your life, I encourage you to start now. Maybe you can start by cutting out sugar drinks, cut out that late night snack, or start exercing in your home or at the gym. Whatever you do, please do something to take care of your body. Your family is counting on you to be alive.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-8240680645932127959?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BDePtC10QfYdsIhRY3jv475GnIs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BDePtC10QfYdsIhRY3jv475GnIs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BDePtC10QfYdsIhRY3jv475GnIs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BDePtC10QfYdsIhRY3jv475GnIs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/8240680645932127959/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/04/how-programmer-lost-46-pounds-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/8240680645932127959?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/8240680645932127959?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/04/how-programmer-lost-46-pounds-and.html" title="How a Programmer Lost 46 Pounds and Survived" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-pdgvQdlMelk/T30ZtSA8vAI/AAAAAAAAN1w/C85M_dUxIes/s72-c/weight-loss-plateau.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkUNQ3w9cCp7ImA9WhVQFUk.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-6060962255643672361</id><published>2012-04-04T07:56:00.000-05:00</published><updated>2012-04-04T07:58:12.268-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-04T07:58:12.268-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="AmplifyJS" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Orlando Code Camp JavaScript Sessions</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-ZoGIODxagGk/T3xEa9CeGLI/AAAAAAAAN0c/OvvzqypBtgQ/s1600/Screen+Shot+2012-04-04+at+7.51.45+AM.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-ZoGIODxagGk/T3xEa9CeGLI/AAAAAAAAN0c/OvvzqypBtgQ/s1600/Screen+Shot+2012-04-04+at+7.51.45+AM.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;I was honored to be asked by &lt;a href="http://estebanfg.blogspot.com/"&gt;Esteban Garcia&lt;/a&gt; (&lt;a href="https://twitter.com/EstebanFGarcia"&gt;@EstebanFGarcia&lt;/a&gt;) to speak at the &lt;a href="http://www.orlandocodecamp.com/"&gt;Orlando Code Camp&lt;/a&gt; on March 31, 2012.&lt;br /&gt;
&lt;br /&gt;
I was impressed that there were 13 simultaneous tracks that were running all day long! One of the tracks was JavaScript and that is where I stayed pretty much stayed.&lt;br /&gt;
I presented 2 sessions &lt;a href="http://elijahmanor.github.com/talks/extend-jquery-amplifyjs/index.html"&gt;Extending Your jQuery Application with AmplifyJS&lt;/a&gt; and &lt;a href="http://elijahmanor.github.com/talks/find-jquery-bugs/Bugs.html"&gt;Find Common jQuery Bugs&lt;/a&gt;. You can find the slides for these presentations online:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://elijahmanor.github.com/talks/extend-jquery-amplifyjs/index.html"&gt;Extending Your jQuery Application with AmplifyJS&lt;/a&gt; - This session takes an existing web application and slow enhances it with with the 3 components of AmplifyJS. I introduce the observer pattern using amplify.publish/amplify.subscribe, I show how to use the amplify.store to support HTML5 persistant storage that is cross-browser, and I show amplify.request which is a high level abstraction to $.ajax that provides ease of configuration, mocking, prototyping, and hooks to protect against future changes. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://elijahmanor.github.com/talks/find-jquery-bugs/Bugs.html"&gt;Find Common jQuery Bugs&lt;/a&gt; - jQuery is so easy to use and thankfully abstracts many of the cross-browser concerns we used to labor over years ago. However, as with any library there are a common set of bugs that tend to crop up the more you use it. This session aims to help equip developers with the appropriate knowledge and tools to exterminate many common bugs seen in jQuery code. For each topic that is covered we will start with a piece of code that has a jQuery bug, then identify what the bug is, explain why it is happening, and then proceed to explore various techniques to exterminate the bug. &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;a href="http://www.kevgriffin.com/"&gt;Kevin Griffin&lt;/a&gt; (&lt;a href="https://twitter.com/1kevgriff"&gt;@1kevgriff&lt;/a&gt;) started the day with a beginner "Zero to Hero in jQuery" talk. Even though jQuery has been around for years, it still can pack a room! Kevin had a lot of question from the audience and engaged them well.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://johnpapa.net/"&gt;John Papa&lt;/a&gt; (&lt;a href="https://twitter.com/john_papa"&gt;@john_papa&lt;/a&gt;) was the keynote speaker and gave an overview on the state of the web. He gave a good high level view of the technologies that are used today in modern front-end applications. John also gave the following 2 JavaScript presentations that were standing room only:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://johnpapa.net/whirlwind-tour-of-hellip-building-html5-and-javascript-apps-with-mvvm-and-knockout"&gt;Whirlwind Tour of Building HTML5 and JavaScript Apps with MVVM and Knockout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://johnpapa.net/jsrender-fundamentals-templating-for-html5-applications"&gt;JsRender Fundamentals: Templating for HTML5 Applications&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;blockquote&gt;In addition John has done an in-depth Pluralsight series on &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=knockout-mvvm"&gt;Knockout&lt;/a&gt; and he is currently working on a series for JsRender that should be available May 2012.&lt;/blockquote&gt;&lt;br /&gt;
There was a large crown of attendees at the conference. I heard that over 750 people signed-up to attend. That is extremely impressive and the conference was FREE too! It takes a lot of hard work, determination, and donations from generous sponsors to have something like that succeed. I want to thank &lt;a href="http://estebanfg.blogspot.com/"&gt;Esteban Garcia&lt;/a&gt; and his team for the great job that they did.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-6060962255643672361?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ox0LY9xxwAbLBB2q-p3otOa7LwE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ox0LY9xxwAbLBB2q-p3otOa7LwE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ox0LY9xxwAbLBB2q-p3otOa7LwE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ox0LY9xxwAbLBB2q-p3otOa7LwE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/6060962255643672361/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/04/orlando-code-camp-sessions.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/6060962255643672361?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/6060962255643672361?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/04/orlando-code-camp-sessions.html" title="Orlando Code Camp JavaScript Sessions" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-ZoGIODxagGk/T3xEa9CeGLI/AAAAAAAAN0c/OvvzqypBtgQ/s72-c/Screen+Shot+2012-04-04+at+7.51.45+AM.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUENQ3g5cCp7ImA9WhVSF0U.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-2308618531621875468</id><published>2012-03-15T00:01:00.000-05:00</published><updated>2012-03-15T00:01:32.628-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-15T00:01:32.628-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #8: Suspicious Selectors</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view other posts in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html"&gt;Find the jQuery Bug #3: Give Me Truth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/02/find-jquery-bug-4-animations-gone-wild.html"&gt;Find the jQuery Bug #4: Animations Gone Wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/03/find-jquery-bug-5-defective-data.html"&gt;Find the jQuery Bug #5: Defective Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/03/find-jquery-bug-6-traversing-trouble.html"&gt;Find the jQuery Bug #6: Traversing Trouble&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/03/find-jquery-bug-7-using-method-as-event.html"&gt;Find the jQuery Bug #7: Using a Method as an Event Handler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
The following is a snippet of HTML markup that was generated by Oracle's JSF (&lt;a href="http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html"&gt;JavaServer Faces&lt;/a&gt;). We want to select the first name field and add a class that will change it's border style.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1964298.js?file=_snippet.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The following code snippets is our first attempt at solving the problem, but there is a subtle error. Do you see it?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1964298.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/WU5Tz/"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/WU5Tz/embedded/result,js,html/presentation/" style="height: 150px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
The result that we expected was to see the first name textbox with a red border, but as you can see above it was not successful.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
At the root of the problem is that JSF inserts a &lt;code&gt;:&lt;/code&gt; delimiter inside of the &lt;code&gt;id&lt;/code&gt; attribute. jQuery abides by the &lt;a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier"&gt;W3C CSS Specification Rules&lt;/a&gt; when it comes to valid characters in a selector. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;If your ID, name, or class contains one of the following meta-characters then you have a problem... &lt;code&gt;!"#$%&amp;'()*+,./:;&lt;=&gt;?@[\]^`{|}~&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;
Here are some examples of invalid selectors in jQuery because they contain invalid characters:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1964298.js?file=_snippet.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
jQuery provides a solution of escaping invalid characters inside a selector. You can proceed each character with two backslashes &lt;code&gt;\\&lt;/code&gt; and then the selector should start working as you expect.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;If you wish to use any of the meta-characters ( such as &lt;code&gt;!"#$%&amp;'()*+,./:;&lt;=&gt;?@[\]^`{|}~&lt;/code&gt; ) as a literal part of a name, you must escape the character with two backslashes: &lt;code&gt;\\&lt;/code&gt;. For example, if you have an element with id="foo.bar", you can use the selector &lt;code&gt;$("#foo\\.bar")&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
-- &lt;a href="http://api.jquery.com/category/selectors/"&gt;http://api.jquery.com/category/selectors/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
In order to fix our example we just need to escape the &lt;code&gt;:&lt;/code&gt; character with &lt;code&gt;\\&lt;/code&gt; like the following code example demonstrates.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1964301.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/qTk6P/"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
If you test out the code again below you'll notice that once you've filled in the textbox and click enter then the behavior will continue as we expected.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/qTk6P/embedded/result,js,html/presentation/" style="height: 150px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
The following examples are the corrected versions of the previous snippets shown in the previous section:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1964301.js?file=_snippet.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;An Alternate Solution&lt;/h3&gt;&lt;br /&gt;
An alternate way to look at this problem is to create a method that will automatically escape the id, name, or class name before using it as a selector.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1964301.js?file=escapeSelector.js"&gt;&lt;/script&gt;&lt;br /&gt;
The previous code snippet extends the String prototype and uses a regular expression to find all invalid meta-characters and escapes them with &lt;code&gt;\\&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is that there is a set of characters that are invalid and need to be escaped before using them in a jQuery selector.&lt;br /&gt;
&lt;br /&gt;
Until next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-2308618531621875468?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/r2AzfHg24eL-fMB_0mtYQqA6uyg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/r2AzfHg24eL-fMB_0mtYQqA6uyg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/r2AzfHg24eL-fMB_0mtYQqA6uyg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/r2AzfHg24eL-fMB_0mtYQqA6uyg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/2308618531621875468/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-8-suspicious-selectors.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/2308618531621875468?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/2308618531621875468?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-8-suspicious-selectors.html" title="Find the jQuery Bug #8: Suspicious Selectors" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0UDSHs6cSp7ImA9WhVSF00.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-3001670987060483800</id><published>2012-03-14T00:01:00.000-05:00</published><updated>2012-03-14T00:01:19.519-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-14T00:01:19.519-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #7: Using a Method as an Event Handler</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view other posts in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html"&gt;Find the jQuery Bug #3: Give Me Truth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/02/find-jquery-bug-4-animations-gone-wild.html"&gt;Find the jQuery Bug #4: Animations Gone Wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/03/find-jquery-bug-5-defective-data.html"&gt;Find the jQuery Bug #5: Defective Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/03/find-jquery-bug-6-traversing-trouble.html"&gt;Find the jQuery Bug #6: Traversing Trouble&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
We want to use an existing object's method to be invoked when the user clicks on a button.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1954271.js?file=_snippet.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The following code snippets is our first attempt at solving the problem, but there is a subtle error. Do you see it?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1954271.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can view, run, and edit the above code sample from the following embedded jsFiddle.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/EhrLE/embedded/result,js,html/presentation/" style="height: 100px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
The result that we expected was to see was an alert box showing up when the user clicks the Register button, but instead the following error shows up in the console.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-cWMj2J6pun0/T1ARLRmOirI/AAAAAAAAMoM/xcjIixckHmc/s1600/JavaScript+Error+Proxy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-cWMj2J6pun0/T1ARLRmOirI/AAAAAAAAMoM/xcjIixckHmc/s1600/JavaScript+Error+Proxy.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
At the root of the problem is that once the event handler is invoked jQuery makes sure the &lt;code&gt;this&lt;/code&gt; pseudo parameter is set to the DOM element that caused the event. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1954271.js?file=_snippet.js"&gt;&lt;/script&gt;&lt;br /&gt;
Inside of the &lt;code&gt;conference.register&lt;/code&gt; method listed above, the &lt;code&gt;this&lt;/code&gt; parameter refers to the register button DOM element. Since &lt;code&gt;this&lt;/code&gt; is a DOM element that is why we are getting the "Cannot call method 'push' of undefined" error.&lt;br /&gt;
&lt;br /&gt;
What we need to resolve this issue is a way to control the value of the &lt;code&gt;this&lt;/code&gt; parameter when the &lt;code&gt;conference.register&lt;/code&gt; method is invoked. Thankfully, there is a way in jQuery to do this.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
The solution to fix this problem is really simple and straightforward. As of version 1.4, jQuery added the &lt;code&gt;$.proxy()&lt;/code&gt; method to help solve the bug found in the previous example. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;code&gt;jQuery.proxy( function, context )&lt;/code&gt; &lt;br /&gt;
&lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;Returns: Function&lt;/i&gt;&lt;/div&gt;Takes a function and returns a new one that will always have a particular context.&lt;br /&gt;
&lt;br /&gt;
-- &lt;a href="http://api.jquery.com/jQuery.proxy/"&gt;http://api.jquery.com/jQuery.proxy/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
In order to fix our example we just need to wrap the &lt;code&gt;conference.register&lt;/code&gt; method with the &lt;code&gt;$.proxy()&lt;/code&gt; method and provide the context that we want the pseudo &lt;code&gt;this&lt;/code&gt; parameter to represent.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1954558.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/http://jsfiddle.net/R9hRP/"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
If you test out the code again below you'll notice that once you've filled in the textbox and click enter then the behavior will continue as we expected.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/FkSbN/embedded/result,js,html/presentation/" style="height: 100px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Alternate Solutions&lt;/h3&gt;&lt;br /&gt;
The above solution shows how you can use the &lt;code&gt;$.proxy()&lt;/code&gt; method to solve the problem, but technically you could have used a plain JavaScript technique instead. By using the &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call"&gt;.call()&lt;/a&gt;&lt;/code&gt; or &lt;code&gt;&lt;a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply"&gt;.apply()&lt;/a&gt;&lt;/code&gt; methods in JavaScript you can control what the value of the &lt;code&gt;this&lt;/code&gt; parameter will be just like we did with the &lt;code&gt;$.proxy()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how you can use the &lt;code&gt;.call()&lt;/code&gt; method to control the &lt;code&gt;this&lt;/code&gt; parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1954558.js?file=call.js"&gt;&lt;/script&gt;&lt;br /&gt;
In a very similar way the next snippet of code shows how you can use the &lt;code&gt;.apply()&lt;/code&gt; method as an alternate solution. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;NOTE: While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments. -- &lt;a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply"&gt;https://developer.mozilla.org/...&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1954558.js?file=apply.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/UtCfP/"&gt;view, run, and edit&lt;/a&gt; the above code sample from jsFiddle.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is that if you ever need to control the value of the pseudo &lt;code&gt;this&lt;/code&gt; paramater inside an event handlers, then you can use the &lt;code&gt;$.proxy()&lt;/code&gt; method in jQuery. In addition, you could just use the &lt;code&gt;.call()&lt;/code&gt; or &lt;code&gt;.apply()&lt;/code&gt; methods in JavaScript if you would rather not use the &lt;code&gt;$.proxy()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
Until next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-3001670987060483800?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qste4KPh6-LtcmnqCtXNvevZMR4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qste4KPh6-LtcmnqCtXNvevZMR4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qste4KPh6-LtcmnqCtXNvevZMR4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qste4KPh6-LtcmnqCtXNvevZMR4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/3001670987060483800/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-7-using-method-as-event.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3001670987060483800?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3001670987060483800?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-7-using-method-as-event.html" title="Find the jQuery Bug #7: Using a Method as an Event Handler" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-cWMj2J6pun0/T1ARLRmOirI/AAAAAAAAMoM/xcjIixckHmc/s72-c/JavaScript+Error+Proxy.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Ak4AQXs4eCp7ImA9WhVSFU8.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-7807323108965658205</id><published>2012-03-12T00:09:00.000-05:00</published><updated>2012-03-12T00:09:00.530-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-12T00:09:00.530-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #6: Traversing Trouble</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view other posts in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html"&gt;Find the jQuery Bug #3: Give Me Truth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/02/find-jquery-bug-4-animations-gone-wild.html"&gt;Find the jQuery Bug #4: Animations Gone Wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/03/find-jquery-bug-5-defective-data.html"&gt;Find the jQuery Bug #5: Defective Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
We want to take the following list of &lt;a href="http://jquery.org/team"&gt;jQuery board and team members&lt;/a&gt; and then hide only those that are team members, leaving only the board members showing.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1945230.js?file=_snippet.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The following code snippet is our first attempt at solving the problem, but there is a subtle error. Do you see it?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1945230.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/mtzT4/"&gt;view, run, and edit&lt;/a&gt; the above code sample from jsFiddle.&lt;br /&gt;
&lt;br /&gt;
The results that we expected was to only view a subset of the total list, but instead we ended up seeing all the items in the list!&lt;br /&gt;
&lt;br /&gt;
&lt;iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/mtzT4/embedded/result,js,html/presentation/" allowfullscreen="allowfullscreen" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
At the root of the problem is that the &lt;code&gt;.find()&lt;/code&gt; method is used for finding elements that are descendants of the current jQuery collection. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;code&gt;.find( selector )&lt;/code&gt; &lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;Returns: jQuery&lt;/i&gt;&lt;/div&gt;Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. &lt;br /&gt;
&lt;br /&gt;
-- &lt;a href="http://api.jquery.com/find/"&gt;http://api.jquery.com/find/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
The above code snippet already starts with a jQuery collection of 22 items referenced by the &lt;code&gt;$items&lt;/code&gt; variable. When calling the &lt;code&gt;$item.find( ".team" )&lt;/code&gt; method jQuery looks for all elements containing the &lt;code&gt;team&lt;/code&gt; class that are children of it's internal collection. In this case, the list items do not have any children, so the result is an empty jQuery collection. &lt;br /&gt;
&lt;br /&gt;
It is important to note that jQuery allows you to call methods off of any jQuery collection even if it is empty. The thing is that it just doesn't do anything, it silently fails. What we really need to solve this problem is to have some way to narrow down the internal jQuery collection based on a specified criteria. Thankfully, there is an easy way to do this.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
The solution to fix this problem is really simple and straightforward. The main problem is that we were using the wrong method.&lt;br /&gt;
&lt;br /&gt;
We should have been using the &lt;code&gt;.filter()&lt;/code&gt; method instead, which takes the current jQuery collection and filters them by matching against a provided selector. It doesn't traverse the children at all, but it's only purpose is to reduce the number of top level elements currently captured in the jQuery collection.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;code&gt;.filter( selector )&lt;/code&gt; &lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;Returns: jQuery&lt;/i&gt;&lt;/div&gt;Reduce the set of matched elements to those that match the selector or pass the function's test.&lt;br /&gt;
&lt;br /&gt;
-- &lt;a href="http://api.jquery.com/filter/"&gt;http://api.jquery.com/filter/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
All you really need to do is to use the &lt;code&gt;.filter()&lt;/code&gt; method instead of the &lt;code&gt;.find()&lt;/code&gt; as we used in the previous example.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1952412.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/g7aqc/"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
If you test out the code again below you'll notice that the list items with class of &lt;code&gt;team&lt;/code&gt; are targeted and hidden like we wanted! &lt;br /&gt;
&lt;br /&gt;
&lt;iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/g7aqc/embedded/result,js,html/presentation/" allowfullscreen="allowfullscreen" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is that the &lt;code&gt;.find()&lt;/code&gt; method is for traversing into the DOM and locating descendants that match a criteria and the &lt;code&gt;.filter()&lt;/code&gt; method is used to reduced the elements that are already selected that match a criteria. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;This may seem like a trivial concept to grasp by some, but I've seen this common confusion of the two methods numerous times. I find that many developers expect that the &lt;code&gt;.find()&lt;/code&gt; method will perform both filter and find, but it doesn't.&lt;/blockquote&gt;&lt;br /&gt;
Until next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-7807323108965658205?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GVD-dJFm4dXUlrI7OcktqrrWYXs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GVD-dJFm4dXUlrI7OcktqrrWYXs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GVD-dJFm4dXUlrI7OcktqrrWYXs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GVD-dJFm4dXUlrI7OcktqrrWYXs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/7807323108965658205/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-6-traversing-trouble.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/7807323108965658205?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/7807323108965658205?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-6-traversing-trouble.html" title="Find the jQuery Bug #6: Traversing Trouble" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkYHSX08cSp7ImA9WhVSEEg.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-5963062065312097666</id><published>2012-03-06T07:43:00.002-06:00</published><updated>2012-03-06T11:15:38.379-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-06T11:15:38.379-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #5: Defective Data</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view other posts in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html"&gt;Find the jQuery Bug #3: Give Me Truth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/02/find-jquery-bug-4-animations-gone-wild.html"&gt;Find the jQuery Bug #4: Animations Gone Wild&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
We want to build a simple jQuery Plugin that will add a confirm message to a simple button or anchor. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1886465.js?file=fiddle.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The following code snippet is our first attempt at building the plugin, but there is a subtle error. Do you see it?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1886465.js?file=_snippet.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/bDgc3/"&gt;view, run, and edit&lt;/a&gt; the above code sample from jsFiddle.&lt;br /&gt;
&lt;br /&gt;
The developer initialized the buttons on the page and then wanted to update the prompt for the first button. He removed all the event handlers added by the plugin, updated the attribute, and then re-initialized the button with the plugin. Unfortunately, this technique didn't work as intended. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
At the root of the problem is an issue when trying to use the &lt;code&gt;.attr()&lt;/code&gt; method after already using the &lt;code&gt;.data()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"Only the .data() API reads HTML5 data-* attributes, and it does so once." -- &lt;a href="https://twitter.com/#!/davemethvin"&gt;Dave Methvin&lt;/a&gt; &lt;a href="http://www.learningjquery.com/2011/09/using-jquerys-data-apis"&gt;http://www.learningjquery.com/...&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
The jQuery plugin reads the HTML5 &lt;code&gt;data-*&lt;/code&gt; attribute first, and the developer tried to update the &lt;code&gt;data-*&lt;/code&gt; attribute later with the &lt;code&gt;.attr()&lt;/code&gt; method. Once the jQuery plugin is re-initialized on the DOM element it will not read the &lt;code&gt;data-*&lt;/code&gt; attribute again, but instead use the data it retrieved the first time. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
The solution to fix this problem is really simple and straightforward. All you really need to do is to change the code where the &lt;code&gt;data-*&lt;/code&gt; attribute was updated to use the &lt;code&gt;.data()&lt;/code&gt; method instead of the &lt;code&gt;.attr()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1906622.js?file=_snippet.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/qEH94/"&gt;view, run, and edit&lt;/a&gt; the above code sample from jsFiddle.&lt;br /&gt;
&lt;br /&gt;
If you test out the code again below you'll notice that it behaves as expected. When you click on the button it will use the updated text that was provided before the plugin was re-initialized.&lt;br /&gt;
&lt;br /&gt;
You may notice that I also changed the key parameter to the &lt;code&gt;.data()&lt;/code&gt; method to camelCase instead of the dashed version I had previously. As of jQuery 1.6 the library has changed direction in how they deal with HTML5 &lt;code&gt;data-*&lt;/code&gt; attributes.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"The treatment of attributes with embedded dashes was changed in jQuery 1.6 to conform to the W3C HTML5 specification." -- &lt;a href="http://api.jquery.com/data/#data-html5"&gt;http://api.jquery.com/data...&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
Now, you can still reference that HTML5 &lt;code&gt;data-*&lt;/code&gt; attributes using their dashed keys, but jQuery will first attempt to use the key "as is" and only attempt to convert that to a camelCased version if it failed. See the following comment from the Dave's article I referenced above. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"Because many people will use .data( "camel-case" ) instead, we convert that to camelCase as well, but only if no data item named camel-case is found so it's faster to use the first form." -- &lt;a href="https://twitter.com/#!/davemethvin"&gt;Dave Methvin&lt;/a&gt; &lt;a href="http://www.learningjquery.com/2011/09/using-jquerys-data-apis"&gt;http://www.learningjquery.com/...&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;Other Things You Might Want to Know&lt;/h3&gt;&lt;br /&gt;
Something that you also may not know about the &lt;code&gt;$.data()&lt;/code&gt; method is that it will attempt to convert the contents of a HTML5 &lt;code&gt;data-*&lt;/code&gt; attributes into the appropriate type. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"Every attempt is made to convert the string to a JavaScript value (this includes booleans, numbers, objects, arrays, and null) otherwise it is left as a string. To retrieve the value's attribute as a string without any attempt to convert it, use the .attr() method." -- &lt;a href="http://api.jquery.com/data/#data-html5"&gt;http://api.jquery.com/data...&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
The following example shows a DOM element using various types of HTML5 &lt;code&gt;data-*&lt;/code&gt; attributes, and then shows that when you call the &lt;code&gt;.data()&lt;/code&gt; method to retrieve a value it will parse and convert it into a boolean, number, object, array, or null.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1906622.js?file=convert.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1906622.js?file=convert.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsfiddle.net/b7Dkm/"&gt;view, run, and edit&lt;/a&gt; the above code sample from jsFiddle.&lt;br /&gt;
&lt;br /&gt;
If for some reason you didn't want jQuery to convert the HTML &lt;code&gt;data-*&lt;/code&gt; attributes when using the &lt;code&gt;.data()&lt;/code&gt; method, you could use the &lt;code&gt;.attr()&lt;/code&gt; method instead. The &lt;code&gt;.attr()&lt;/code&gt; method will always return the string version of the attribute.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is that once you call the &lt;code&gt;.data()&lt;/code&gt; getter method on a element then it will read the HTML5 &lt;code&gt;data-*&lt;/code&gt; atributes only once. If you want to update the data from there on, then you'll need to use the &lt;code&gt;.data()&lt;/code&gt; setter method. Also, it is important to know that when you read these HTML5 &lt;code&gt;data-*&lt;/code&gt; attributes jQuery will convert those values into it's appropriate type.&lt;br /&gt;
&lt;br /&gt;
I hope you found this helpful. I recommend you reading &lt;a href="https://twitter.com/#!/davemethvin"&gt;Dave Methvin&lt;/a&gt;'s article entitled &lt;a href="http://www.learningjquery.com/2011/09/using-jquerys-data-apis"&gt;Using jQuery’s Data APIs&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Please provide any feedback in the comments below. Until next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-5963062065312097666?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CA0gRAlqr3gp8A4MSmOoE5tSAhw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CA0gRAlqr3gp8A4MSmOoE5tSAhw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CA0gRAlqr3gp8A4MSmOoE5tSAhw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CA0gRAlqr3gp8A4MSmOoE5tSAhw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/5963062065312097666/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-5-defective-data.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5963062065312097666?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5963062065312097666?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/03/find-jquery-bug-5-defective-data.html" title="Find the jQuery Bug #5: Defective Data" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUEMRnk6eip7ImA9WhVTE04.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-3704895608633866632</id><published>2012-02-27T04:14:00.000-06:00</published><updated>2012-02-27T04:14:47.712-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-27T04:14:47.712-06:00</app:edited><title>TextMate-like ⌘T &amp; ⇧⌘T in Chrome Dev Tools &amp; Other New Features</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://tools.google.com/dlpage/chromesxs" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-lQTREgnwTwA/T0eS0nVkD_I/AAAAAAAAMeI/vs2PUnotW3g/s1600/chrome-canary-lockup.png" /&gt;&lt;/a&gt;&lt;/div&gt;For the past year or so I've used &lt;a href="http://tools.google.com/dlpage/chromesxs"&gt;Google Chrome Canary&lt;/a&gt; as my primary web browser, however, about a month ago I temporarily switched to the stable&amp;nbsp;build&amp;nbsp;of Chrome because of some&amp;nbsp;instability&amp;nbsp;in the dev tools. I just recently switched back to Canary and was&amp;nbsp;pleasantly&amp;nbsp;surprised to see numerous new features in the dev tools there were very welcome indeed!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;This post only covers the extreme latest in Chrome Dev Tools. There are so many more rich features that can be found. If you are interested about more helpful features you might be interested in a post I did last year entitled &lt;a href="http://www.elijahmanor.com/2011/08/7-chrome-tips-developers-designers-may.html"&gt;7 Chrome Tips Developers &amp; Designers May Not Know&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
If you are not familiar with the Canary build of Chrome, it is a extremely dev version of the browser. You should be&amp;nbsp;cautious&amp;nbsp;because it does update almost every day, but at the same time you get first in line to see all the new features. Unlike the dev or beta builds of Chrome you can actually install Canary side-by-side next to your Stable or Beta build of Chrome. This makes switching between versions very&amp;nbsp;convenient.&lt;br /&gt;
&lt;br /&gt;
The features I am about to describe are currently only available in the dev or canary builds of Chrome. If you have the Beta or Stable builds then you will not see these yet, but hopefully they'll make their way to those builds sooner than later. At least this will wet your appetite ;)&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Scripts Explorer&lt;/h3&gt;&lt;br /&gt;
A welcome change to the Scripts tab is a new Scripts Explorer (as seen in the below image). The previous way to navigate through the scripts of a webpage was to open a HUGE drop down containing tons of script files. Chrome kept reorganizing that huge&amp;nbsp;drop-down&amp;nbsp;list to make it more usable, but in the end it wasn't optimal when dealing with a site with lots of JavaScript fiels.&lt;br /&gt;
&lt;br /&gt;
The new Scripts Explorer nicely&amp;nbsp;separates&amp;nbsp;the Scripts used on the webpage from the Content Scripts used in all of the Chrome Extensions you have installed in your browser. Historically, it was slightly annoying to see all those Content Scripts alongside your main JavaScript files in that huge drop down mentioned above. Again, over time Chrome moved those Content Scripts to the bottom of that drop down instead of intermingled, but this move to the Scripts Explorer is head over heals WAY better... YAY!&lt;br /&gt;
&lt;br /&gt;
In addition, you can also choose to dock the Scripts Explorer to the left side of the dev tools (by clicking the little icon in the upper right) or have it auto-close when you are done finding what you need.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-qWnhG0YA5VE/T0cVgbYDjmI/AAAAAAAAMdw/NX5IUwMhk1E/s1600/dev-tools-panel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-qWnhG0YA5VE/T0cVgbYDjmI/AAAAAAAAMdw/NX5IUwMhk1E/s1600/dev-tools-panel.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;TextMate's ⌘T "Go to File" Feature&lt;/h3&gt;&lt;br /&gt;
I don't know about you, but I'm one of those keyboard shortcut junkies, so I am always on the lookout on how to do my job without using the mouse. So, I was even more excited to see support for quickly finding a JavaScript file by only using the keyboard! Chrome call's this feature "Go to Script" and it is similar to what you may have experience in TextMate using&amp;nbsp;⌘T or maybe in Sublime Text 2 with&amp;nbsp;⌘P.&lt;br /&gt;
&lt;br /&gt;
Since&amp;nbsp;⌘T is already reserved for creating a new tab in Chrome, they have chosen&amp;nbsp;⌘O for this feature. As soon as you type&amp;nbsp;⌘O you will see the following dialog displaying JavaScript files. As you type the list will filter to only the files that match what you are typing. You can arrow up or down to narrow the selection even more and then click "enter" to open that script file.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-uZszUdnx8K4/T0cVf7F2nkI/AAAAAAAAMdo/rQPLsUR7sbo/s1600/dev-tools-cmd-t.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-uZszUdnx8K4/T0cVf7F2nkI/AAAAAAAAMdo/rQPLsUR7sbo/s1600/dev-tools-cmd-t.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;TextMate's ⇧⌘T "Go to Symbol" Feature&lt;/h3&gt;&lt;br /&gt;
Now, if the "Go to Script" feature wasn't enough, there is also the "Go to Function", which is similar to the "Go to Symbol" feature of TextMate using&amp;nbsp;⇧⌘T or&amp;nbsp;⌘R&amp;nbsp;in Sublime Text 2.&lt;br /&gt;
&lt;br /&gt;
Once you are in a JavaScript file you can press&amp;nbsp;⇧⌘O to bring up the "Go to Function" dialog. This works in a very similar way as the "Go to Script" dialog as we saw previously, but this time instead of looking for files, it helps you track down functions! Navigating through your JavaScript files to find a specific function has now become a breeze!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/--6PWmBTE7S8/T0cUa4OfBnI/AAAAAAAAMdg/fWr8kGBUHMk/s1600/dev-tools-cmd-shf-t.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/--6PWmBTE7S8/T0cUa4OfBnI/AAAAAAAAMdg/fWr8kGBUHMk/s1600/dev-tools-cmd-shf-t.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;Dock Dev Tools to the Right&lt;/h3&gt;&lt;br /&gt;
The last feature that stood out to me as really cool, was the new setting to "Dock to right". Many people these days have a wide-screen monitor and having the dev tools docked at the bottom of the screen sometimes feels a little scrunched. If I have my browser maximized there is usually tons of room to the left or right of the website I am viewing.&lt;br /&gt;
&lt;br /&gt;
Thankfully, with this new feature I can now choose to dock the dev tool to the right of my screen to give some breathing room for development!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Note: I undrestand some like to undock the dev tools to solve this issue, but I usually tend to like keeping them docked so this new feature is very handy for me.&lt;/blockquote&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Ahx9xel8o5c/T0cViJVrn_I/AAAAAAAAMd4/ZjJEF31X5gg/s1600/dev-tools-right.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-Ahx9xel8o5c/T0cViJVrn_I/AAAAAAAAMd4/ZjJEF31X5gg/s1600/dev-tools-right.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
In order to turn on this feature, you'll need to go into the Settings dialog. You can access this by clicking on the gear icon located at the bottom right of your dev tools. Once the dialog has been&amp;nbsp;launched&amp;nbsp;you should see a General section with the "Doc to right" option listed.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-F8Y8NpRMdr0/T0cVim2YnrI/AAAAAAAAMeA/MhWRi30hFzc/s1600/dev-tools-settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-F8Y8NpRMdr0/T0cVim2YnrI/AAAAAAAAMeA/MhWRi30hFzc/s1600/dev-tools-settings.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
I find the the above JavaScript&amp;nbsp;enhancements&amp;nbsp;to the dev tools have really made navigating through scripts to be much more enjoyable. If you have noticed any other new features that I have missed please let me know. They keep cropping up all the time... which is AWESOME!&lt;br /&gt;
&lt;br /&gt;
If you have Chrome Canary then you can start using the above features right way, otherwise they should make it in a Beta or Stable build in the near future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-3704895608633866632?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EIsKG2KcJ8XIDQBMvwjf7LDzC8U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EIsKG2KcJ8XIDQBMvwjf7LDzC8U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EIsKG2KcJ8XIDQBMvwjf7LDzC8U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EIsKG2KcJ8XIDQBMvwjf7LDzC8U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/3704895608633866632/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/02/textmate-like-t-t-in-chrome-dev-tools.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3704895608633866632?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3704895608633866632?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/02/textmate-like-t-t-in-chrome-dev-tools.html" title="TextMate-like ⌘T &amp; ⇧⌘T in Chrome Dev Tools &amp; Other New Features" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-lQTREgnwTwA/T0eS0nVkD_I/AAAAAAAAMeI/vs2PUnotW3g/s72-c/chrome-canary-lockup.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EDQHo_eSp7ImA9WhVTFUs.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-2360298955659483099</id><published>2012-02-13T00:01:00.000-06:00</published><updated>2012-02-29T18:27:51.441-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-29T18:27:51.441-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #4: Animations Gone Wild</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view other posts in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html"&gt;Find the jQuery Bug #3: Give Me Truth&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
We want to take the following HTML and build a simple jQuery menu that will reveal sub-menus when you hover over each item.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1777400.js?file=_snippet.html"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The following code snippet is our first attempt at solving the problem, but there is a subtle error. Do you see it?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1777400.js?file=fiddle.js"&gt;
&lt;/script&gt;&lt;br /&gt;
If you start playing with the menu it appears that it works as intended, but as you continue to use the menu an annoying problem raises its ugly head. If you move your mouse really quick from right to left over the menu you'll see the problem :(&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/R3q6c/embedded/result,js/presentation" style="height: 250px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
If you played with the example above you'll have noticed that if you interact with the menu really quickly side-to-side then the animations continue over and over and over again, even after you've moved off the menu completely! &lt;br /&gt;
&lt;br /&gt;
At the root of the problem is an animation queue that has gotten out of hand. jQuery keeps an internal queue to help it know what animation to run next. When you take an element and call one of the animation methods ( &lt;code&gt;.animate()&lt;/code&gt;, &lt;code&gt;.slideDown()&lt;/code&gt;, &lt;code&gt;.slideUp()&lt;/code&gt;, &lt;code&gt;.slideToggle()&lt;/code&gt;, etc... ) what really happens is that effect gets added to the default &lt;code&gt;"fx"&lt;/code&gt; animation queue that is attached to the element. As each effects completes jQuery will move on to the next effect in the queue until all animations are complete. &lt;br /&gt;
&lt;br /&gt;
The magic that we need is to somehow interrupt the queue system. Thankfully, there is an API just for that and in the next section we will show how to use it.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
&lt;div style="float: right; margin-bottom: 15px; margin-left: 15px;"&gt;&lt;iframe allowfullscreen="" frameborder="0" height="233" src="http://www.youtube.com/embed/Ow0lr63y4Mw" width="300"&gt;&lt;/iframe&gt;&lt;/div&gt;The solution to fix this problem is really simple and straightforward. In the words of &lt;a href="http://en.wikipedia.org/wiki/Bob_Newhart"&gt;Bob Newhart&lt;/a&gt;, we need the animation to &lt;strong&gt;STOP IT!&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Of course, we can tell our program to &lt;i&gt;STOP IT!&lt;/i&gt;, but they are usually to stubborn to heed to our warnings. Thankfully there is a method we can utilize in jQuery coincidentally called &lt;code&gt;.stop()&lt;/code&gt; which we can use to solve our animation problem!&lt;br /&gt;
&lt;br /&gt;
The following is the documentation from jQuery's website about the &lt;code&gt;.stop()&lt;/code&gt; method that we will use.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;code&gt;&lt;strong&gt;.stop( [clearQueue] [, jumpToEnd] )&lt;/strong&gt;&lt;/code&gt; &lt;br /&gt;
&lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;version added: 1.2&lt;/i&gt;&lt;/div&gt;&lt;code&gt;clearQueue&lt;/code&gt; - A Boolean indicating whether to remove queued animation as well. Defaults to false.&lt;br /&gt;
&lt;code&gt;jumpToEnd&lt;/code&gt; - A Boolean indicating whether to complete the current animation immediately. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;strong&gt;.stop( [queue] [, clearQueue] [, jumpToEnd] )&lt;/strong&gt;&lt;/code&gt; &lt;br /&gt;
&lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;version added: 1.7&lt;/i&gt;&lt;/div&gt;&lt;code&gt;queue&lt;/code&gt; - The name of the queue in which to stop animations.&lt;br /&gt;
&lt;code&gt;clear&lt;/code&gt; - QueueA Boolean indicating whether to remove queued animation as well. Defaults to false.&lt;br /&gt;
&lt;code&gt;jumpToEnd&lt;/code&gt; - A Boolean indicating whether to complete the current animation immediately. Defaults to false.&lt;br /&gt;
&lt;br /&gt;
--&lt;a href="http://api.jquery.com/stop/"&gt;http://api.jquery.com/stop/&lt;/a&gt;&lt;/blockquote&gt;&lt;div style="clear: both;"&gt;&lt;/div&gt;&lt;br /&gt;
As you see above there are 2 "overloaded" methods both with optional parameters. The important parameters that we will use to fix our code snippet are the &lt;code&gt;clearQueue&lt;/code&gt; and &lt;code&gt;jumpToEnd&lt;/code&gt; booleans. In order to get rid of the huge queue of animations on an element and complete whatever animation that was started all we need to do is pass &lt;code&gt;true&lt;/code&gt; as both parameters... &lt;code&gt;$element.stop( true, true )&lt;/code&gt;!&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1777752.js?file=fiddle1.js"&gt;
&lt;/script&gt;&lt;br /&gt;
If you test out the code again below you'll notice that it works just as before, but this time the bug we found when moving our mouse quickly back and forth across the menu is now gone! &lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/F4FRk/embedded/result,js/presentation" style="height: 250px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Fancy Solution&lt;/h3&gt;&lt;br /&gt;
If we wanted to get fancy, we could choose to update the animation easing algorithm. An easing algorithm is a mathematical equation that defines the animation path of an effect. Wow, that was a mouth full. Let's try that again, but this time with something visual. The following demo, from jQuery UI, is a great visualization of the various easing algorithms. Click the image to launch the &lt;a href="http://jqueryui.com/demos/effect/easing.html"&gt;jQuery UI Easing Demo&lt;/a&gt; and then click on each square to view the easing in action. I think my favorite is "easeOutBounce" ;)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://jqueryui.com/demos/effect/easing.html" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Odnpy97PAW4/TzS8BybJaOI/AAAAAAAAMV4/Szo0srpb5dk/s1600/Screen+Shot+2012-02-10+at+12.37.59+AM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
With these easing options in mind, let's update our example above and use "easeOutBounce" instead of the default "swing" option that is default in jQuery. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: "The only easing implementations in the jQuery library are the default, called swing, and one that progresses at a constant pace, called linear." &lt;br /&gt;
&lt;br /&gt;
-- &lt;a href="http://api.jquery.com/slideDown"&gt;http://api.jquery.com/slideDown&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1777752.js?file=fiddle2.js"&gt;
&lt;/script&gt;&lt;br /&gt;
You might notice that I also added some other parameters to the &lt;code&gt;.slideDown()&lt;/code&gt; and &lt;code&gt;.slideUp()&lt;/code&gt; methods. All of the parameters are optional, but if we want we can provide our own values such as a &lt;code&gt;duration&lt;/code&gt;, &lt;code&gt;easing&lt;/code&gt; algorithm, and a &lt;code&gt;callback&lt;/code&gt; to invoke when the animation is complete. In the code above, I trigger a custom event depending if the sub-menu was &lt;code&gt;opened&lt;/code&gt; or &lt;code&gt;closed&lt;/code&gt; and then I delegate to those events using the &lt;code&gt;.on()&lt;/code&gt; method on line 19.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;code&gt;&lt;strong&gt;.slideDown( [duration] [, easing] [, callback] )&lt;/strong&gt;&lt;/code&gt; &lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;version added: 1.4.3&lt;/i&gt;&lt;/div&gt;&lt;code&gt;&lt;strong&gt;.slideUp( [duration] [, easing] [, callback] )&lt;/strong&gt;&lt;/code&gt; &lt;div style="position: relative; text-align: right; top: -21px;"&gt;&lt;i&gt;version added: 1.4.3&lt;/i&gt;&lt;/div&gt;&lt;code&gt;duration&lt;/code&gt; - A string or number determining how long the animation will run.&lt;br /&gt;
&lt;code&gt;easing&lt;/code&gt; - A string indicating which easing function to use for the transition.&lt;br /&gt;
&lt;code&gt;callback&lt;/code&gt; - A function to call once the animation is complete.&lt;br /&gt;
&lt;br /&gt;
-- &lt;a href="http://api.jquery.com/slideDown/"&gt;http://api.jquery.com/slideDown/&lt;/a&gt; &amp; &lt;a href="http://api.jquery.com/slideUp/"&gt;http://api.jquery.com/slideUp/&lt;/a&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Now you can test the changes we made. The effect may be too adventurous for most production business web applications, but the one I chose is just one of the many easing algorithms provided by jQuery UI that you can pick from. Also, if you are a math wizard you can come up with your algorithm!&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" src="http://jsfiddle.net/xtD7j/embedded/result,js/presentation" style="height: 250px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Refactoring the Code&lt;/h3&gt;&lt;br /&gt;
If you are anything like me you probably noticed a &lt;a href="http://www.codinghorror.com/blog/2006/05/code-smells.html"&gt;code smell&lt;/a&gt;. Much of the code from the previous examples looks very redundant. Let's take a stab at refactoring the code somewhat to reduce the "duplicated code" smell and made the code &lt;a href="http://www.artima.com/intv/dry.html"&gt;DRY (don't repeat yourself)&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;If you look through your vast code base, And notice code repeated here and there.&lt;br /&gt;
You might consider refactoring soon, Or you'll experience maintenance despair!&lt;/blockquote&gt;&lt;br /&gt;
Previously we were passing two functions to the &lt;code&gt;.hover()&lt;/code&gt; method. The 1st function parameter was to handle &lt;code&gt;mouseover&lt;/code&gt; events and the other was to handle &lt;code&gt;mouseout&lt;/code&gt; events. Thankfully, there is another "overloaded" version of &lt;code&gt;.hover()&lt;/code&gt; that takes just 1 function parameter. This 1 function will be invoked on both &lt;code&gt;mouseover&lt;/code&gt; events and &lt;code&gt;mouseout&lt;/code&gt; events! &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1777752.js?file=fiddle3.js"&gt;&lt;/script&gt;&lt;br /&gt;
You may also notice that we are using a different method to actually perform the sub-menu animation. jQuery includes a &lt;code&gt;.slideToggle()&lt;/code&gt; method that will either &lt;code&gt;.slideDown()&lt;/code&gt; or &lt;code&gt;.slideUp()&lt;/code&gt; depending on the state of the element. &lt;br /&gt;
&lt;br /&gt;
The last thing to take into consideration is how to know which custom event to trigger. Previously I knew which event to trigger because &lt;code&gt;opened&lt;/code&gt; was associated with &lt;code&gt;.slideDown()&lt;/code&gt; and &lt;code&gt;closed&lt;/code&gt; was associated with &lt;code&gt;.slideUp()&lt;/code&gt;, but what about now? Thankfully that is easily solved by looking at the &lt;code&gt;event&lt;/code&gt; object passed to the &lt;code&gt;hover&lt;/code&gt; event handler. The &lt;code&gt;event&lt;/code&gt; object has a &lt;code&gt;type&lt;/code&gt; property which tells what type of event was originally fired. So, I can do something like this... &lt;code&gt;e.type === "mouseover" ? "opened" : "closed"&lt;/code&gt; -- &lt;a href="http://jsfiddle.net/ujsfH/"&gt;http://jsfiddle.net/ujsfH/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is that jQuery has an internal animation queue that you should be aware of. If you need to clear out that queue you can use the &lt;code&gt;.stop()&lt;/code&gt; method. Also, you can modify the duration of animation, change the animation easing algorithm, and also respond to an event when the animation is complete.&lt;br /&gt;
&lt;br /&gt;
Things we didn't cover in this post are how to create your own queue, how to create your own easing algorithm, how to modify the default animation duration, and several other concerns.&lt;br /&gt;
&lt;br /&gt;
Until next time...&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;NOTE: The CSS I used as the base for the example menu above is a modified version from a &lt;a href="http://www.kriesi.at/archives/create-a-multilevel-dropdown-menu-with-css-and-improve-it-via-jquery"&gt;blog post&lt;/a&gt; on &lt;a href="http://twitter.com/Kriesi"&gt;@Kriesi's&lt;/a&gt; website. I removed the hover styles and replaced his jQuery code with mine for this &lt;a href="http://www.elijahmanor.com/search/label/Find%20the%20jQuery%20Bug"&gt;Find the jQuery Bug&lt;/a&gt; post.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-2360298955659483099?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aA55Qs5lz3vNcSD3VCBFppuqEQw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aA55Qs5lz3vNcSD3VCBFppuqEQw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aA55Qs5lz3vNcSD3VCBFppuqEQw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aA55Qs5lz3vNcSD3VCBFppuqEQw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/2360298955659483099/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/02/find-jquery-bug-4-animations-gone-wild.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/2360298955659483099?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/2360298955659483099?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/02/find-jquery-bug-4-animations-gone-wild.html" title="Find the jQuery Bug #4: Animations Gone Wild" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/Ow0lr63y4Mw/default.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0IGQn4_cCp7ImA9WhRbFkU.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-7863784942380961556</id><published>2012-02-08T00:05:00.002-06:00</published><updated>2012-02-08T00:12:03.048-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-08T00:12:03.048-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="CoffeeScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Regular Expressions" /><title>Regular Expressions in CoffeeScript are Awesome</title><content type="html">Let's face it, &lt;a href="https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions"&gt;regular expressions&lt;/a&gt; aren't for everyone. It takes a special breed of developer to actually enjoy writing regular expressions. Although I enjoy them, the developer that comes after me may find that they are cryptic and hard to read. And yes, sometimes it takes me a little bit to decipher through an old regular expression that I wrote a while ago.&lt;br /&gt;
&lt;br /&gt;
Take for example, the following regular expression. Can you tell what it is doing? If so... then great, but what about the developers you work with?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1765839.js?file=emailPattern.js"&gt;&lt;/script&gt;&lt;br /&gt;
One of the very cool things I like about &lt;a href="http://coffeescript.org/"&gt;CoffeeScript&lt;/a&gt; is that you can &lt;a href="http://coffeescript.org/#regexes"&gt;annotate your regular expressions&lt;/a&gt;! The following snippet of CoffeeScript compiles down to the equivalent JavaScript as seen in the above code sample. Yay ;) &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1765839.js?file=emailPattern.coffee"&gt;&lt;/script&gt;&lt;br /&gt;
Which code sample would you rather maintain? And more importantly which one would your co-worker be more likely to understand? &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;NOTE: The above email regular expression is very naive in it's logic. I based the above snippet from a Nettuts+ post entitled, &lt;a href="http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/"&gt;8 Regular Expressions You Should Know&lt;/a&gt;. There are much more comprehensive email regular expressions available on the internet, but I used the above one to show the value of annotation.&lt;/blockquote&gt;&lt;br /&gt;
As a side note, some tools that I find helpful are Grant Skinner's &lt;a href="http://gskinner.com/RegExr/"&gt;Online RegExr Tool&lt;/a&gt; and I sometimes get inspiration for regular expressions at &lt;a href="http://regexlib.com/DisplayPatterns.aspx"&gt;RegExLib.com&lt;/a&gt;. What tools or resources do you use for regular expressions?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-7863784942380961556?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_V4GUuNNFX-SRR1qgHmH4070CPg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_V4GUuNNFX-SRR1qgHmH4070CPg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_V4GUuNNFX-SRR1qgHmH4070CPg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_V4GUuNNFX-SRR1qgHmH4070CPg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/7863784942380961556/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/02/regular-expressions-in-coffeescript-are.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/7863784942380961556?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/7863784942380961556?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/02/regular-expressions-in-coffeescript-are.html" title="Regular Expressions in CoffeeScript are Awesome" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0UGSHk6eCp7ImA9WhVSFkg.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-3131166255414772837</id><published>2012-02-06T01:00:00.002-06:00</published><updated>2012-03-13T10:07:09.710-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-13T10:07:09.710-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Differences Between jQuery .bind() vs .live() vs .delegate() vs .on()</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
I've seen quite a bit of confusion from developers about what the real differences are between the jQuery &lt;code&gt;.bind()&lt;/code&gt;, &lt;code&gt;.live()&lt;/code&gt;, &lt;code&gt;.delegate()&lt;/code&gt;, and &lt;code&gt;.on()&lt;/code&gt; methods and when they should be used.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;If you want, you can jump to the &lt;a href="#tldr"&gt;TL;DR&lt;/a&gt; section and get a high-level overview what this article is about.&lt;/blockquote&gt;&lt;br /&gt;
Before we dive into the ins and outs of these methods, let's start with some common HTML markup that we'll be using as we write sample jQuery code.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1749717.js?file=_snippet.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;Using the Bind Method&lt;/h3&gt;&lt;br /&gt;
The &lt;code&gt;.bind()&lt;/code&gt; method registers the type of event and an event handler directly to the DOM element in question. This method has been around the longest and in its day it was a nice abstraction around the various cross-browser issues that existed. This method is still very handy when wiring-up event handlers, but there are various performance concerns as are listed below.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1749717.js?file=bind.js"&gt;&lt;/script&gt;&lt;br /&gt;
The &lt;code&gt;.bind()&lt;/code&gt; method will attach the event handler to all of the anchors that are matched! That is not good. Not only is that expensive to implicitly iterate over all of those items to attach an event handler, but it is also wasteful since it is the same event handler over and over again.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pros&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;This methods works across various browser implementations.&lt;/li&gt;
&lt;li&gt;It is pretty easy and quick to wire-up event handlers.&lt;/li&gt;
&lt;li&gt;The shorthand methods (&lt;code&gt;.click()&lt;/code&gt;, &lt;code&gt;.hover()&lt;/code&gt;, etc...) make it even easier to wire-up event handlers.&lt;/li&gt;
&lt;li&gt;For a simple ID selector, using &lt;code&gt;.bind()&lt;/code&gt; not only wires-up quickly, but also when the event fires the event handler is invoked almost immediately.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Cons&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The method attaches the same event handler to every matched element in the selection.&lt;/li&gt;
&lt;li&gt;It doesn't work for elements added dynamically that matches the same selector.&lt;/li&gt;
&lt;li&gt;There are performance concerns when dealing with a large selection.&lt;/li&gt;
&lt;li&gt;The attachment is done upfront which can have performance issues on page load.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;Using the Live Method&lt;/h3&gt;&lt;br /&gt;
The &lt;code&gt;.live()&lt;/code&gt; method uses the concept of event delegation to perform its so called "magic". The way you call &lt;code&gt;.live()&lt;/code&gt; looks just like how you might call &lt;code&gt;.bind()&lt;/code&gt;, which is very convenient. However, under the covers this method works much different. The &lt;code&gt;.live&lt;/code&gt; method attaches the event handler to the root level document along with the associated selector and event information. By registering this information on the document it allows one event handler to be used for all events that have bubbled (a.k.a. delegated, propagated) up to it. Once an event has bubbled up to the document jQuery looks at the selector/event metadata to determine which handler it should invoke, if any. This extra work has some impact on performance at the point of user interaction, but the initial register process is fairly speedy. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1749717.js?file=live.js"&gt;&lt;/script&gt;&lt;br /&gt;
The good thing about this code as compared to the &lt;code&gt;.bind()&lt;/code&gt; example above is that it is only attaching the event handler once to the document instead of multiple times. This not only is faster, but less wasteful, however, there are many problems with using this method and they are outlined below.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pros&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;There is only one event handler registered instead of the numerous event handlers that could have been registered with the &lt;code&gt;.bind()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;The upgrade path from &lt;code&gt;.bind()&lt;/code&gt; to &lt;code&gt;.live()&lt;/code&gt; is very small. All you have to do is replace "bind" to "live".&lt;/li&gt;
&lt;li&gt;Elements dynamically added to the DOM that match the selector magically work because the real information was registered on the document.&lt;/li&gt;
&lt;li&gt;You can wire-up event handlers before the document ready event helping you utilize possibly unused time.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Cons&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;This method is deprecated as of jQuery 1.7 and you should start phasing out its use in your code.&lt;/li&gt;
&lt;li&gt;Chaining is not properly supported using this method.&lt;/li&gt;
&lt;li&gt;The selection that is made is basically thrown away since it is only used to register the event handler on the document.&lt;/li&gt;
&lt;li&gt;Using event.stopPropagation() is no longer helpful because the event has already delegated all the way up to the document.&lt;/li&gt;
&lt;li&gt;Since all selector/event information is attached to the document once an event does occur jQuery has match through its large metadata store using the &lt;code&gt;matchesSelector&lt;/code&gt; method to determine which event handler to invoke, if any.&lt;/li&gt;
&lt;li&gt;Your events always delegate all the way up to the document. This can affect performance if your DOM is deep.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;Using the Delegate Method&lt;/h3&gt;&lt;br /&gt;
The &lt;code&gt;.delegate()&lt;/code&gt; method behaves in a similar fashion to the &lt;code&gt;.live()&lt;/code&gt; method, but instead of attaching the selector/event information to the document, you can choose where it is anchored. Just like the &lt;code&gt;.live()&lt;/code&gt; method, this technique uses event delegation to work correctly. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;If you skipped over the explanation of the &lt;code&gt;.live()&lt;/code&gt; method you might want to go back up and read it as I described some of the internal logic that happen.&lt;/blockquote&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1749717.js?file=delegate.js"&gt;&lt;/script&gt;&lt;br /&gt;
The &lt;code&gt;.delegate()&lt;/code&gt; method is very powerful. The above code will attach the event handler to the unordered list ("#members") along with the selector/event information. This is much more efficient than the &lt;code&gt;.live()&lt;/code&gt; method that always attaches the information to the document. In addition a lot of other problematic issues were resolved by introducing the &lt;code&gt;.delegate()&lt;/code&gt; method. See the following outline for a detailed list.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pros&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;You have the option of choosing where to attach the selector/event information.&lt;/li&gt;
&lt;li&gt;The selection isn't actually performed up front, but is only used to register onto the root element.&lt;/li&gt;
&lt;li&gt;Chaining is supported correctly.&lt;/li&gt;
&lt;li&gt;jQuery still needs to iterate over the selector/event data to determine a match, but since you can choose where the root is the amount of data to sort through can be much smaller.&lt;/li&gt;
&lt;li&gt;Since this technique uses event delegation, it can work with dynamically added elements to the DOM where the selectors match.&lt;/li&gt;
&lt;li&gt;As long as you delegate against the document you can also wire-up event handlers before the document ready event.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Cons&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Changing from a &lt;code&gt;.bind()&lt;/code&gt; to a &lt;code&gt;.delegate()&lt;/code&gt; method isn't as straight forward.&lt;/li&gt;
&lt;li&gt;There is still the concern of jQuery having to figure out, using the &lt;code&gt;matchesSelector&lt;/code&gt; method, which event handler to invoke based on the selector/event information stored at the root element. However, the metadata stored at the root element should be considerably smaller compared to using the &lt;code&gt;.live()&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;Using the On Method&lt;/h3&gt;&lt;br /&gt;
Did you know that the jQuery &lt;code&gt;.bind()&lt;/code&gt;, &lt;code&gt;.live()&lt;/code&gt;, and &lt;code&gt;.delegate()&lt;/code&gt; methods are just one line pass throughs to the new jQuery 1.7 &lt;code&gt;.on()&lt;/code&gt; method? The same is true of the &lt;code&gt;.unbind()&lt;/code&gt;, &lt;code&gt;.die()&lt;/code&gt;, and &lt;code&gt;.undelegate()&lt;/code&gt; methods. The following code snippet is taken from the &lt;a href="https://github.com/jquery/jquery/blob/633ca9c1610c49dbb780e565f4f1202e1fe20fae/src/event.js#L956"&gt;jQuery 1.7.1 codebase in GitHub&lt;/a&gt;...&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1749717.js?file=jquery-1.7.1.js"&gt;&lt;/script&gt;&lt;br /&gt;
With that in mind, the usage of the new &lt;code&gt;.on()&lt;/code&gt; method looks something like the following...&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1749717.js?file=on.js"&gt;&lt;/script&gt;&lt;br /&gt;
You'll notice that depending how I call the &lt;code&gt;.on()&lt;/code&gt; method changes how it performs. You can consider the &lt;code&gt;.on()&lt;/code&gt; method as being "overloaded" with different signatures, which in turn changes how the event binding is wired-up. The &lt;code&gt;.on&lt;/code&gt; method bring a lot of consistency to the API and hopefully makes things slightly less confusing.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pros&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Brings uniformity to the various event binding methods.&lt;/li&gt;
&lt;li&gt;Simplifies the jQuery code base and removes one level of redirection since the &lt;code&gt;.bind()&lt;/code&gt;, &lt;code&gt;.live()&lt;/code&gt;, and &lt;code&gt;.delegate()&lt;/code&gt; call this method under the covers.&lt;/li&gt;
&lt;li&gt;Still provides all the goodness of the &lt;code&gt;.delegate()&lt;/code&gt; method, while still providing support for the &lt;code&gt;.bind()&lt;/code&gt; method if you need it.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Cons&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Brings confusion because the behavior changes based on how you call the method.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h3 id="tldr"&gt;Conclusion (tl;dr)&lt;/h3&gt;&lt;br /&gt;
If you have been confused about the various different types of event binding methods then don't worry, there has been a lot of history and evolvement in the API over time. There are many people that view these methods as magic, but once you uncover some of how they work it will help you understand how to better ode inside of your projects. &lt;br /&gt;
&lt;br /&gt;
The biggest take aways from this article are that...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Using the &lt;code&gt;.bind()&lt;/code&gt; method is very costly as it attaches the same event handler to every item matched in your selector.&lt;/li&gt;
&lt;li&gt;You should stop using the &lt;code&gt;.live()&lt;/code&gt; method as it is deprecated and has a lot of problems with it.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;.delegate()&lt;/code&gt; method gives a lot of "bang for your buck" when dealing with performance and reacting to dynamically added elements.&lt;/li&gt;
&lt;li&gt;That the new &lt;code&gt;.on()&lt;/code&gt; method is mostly syntax sugar that can mimic &lt;code&gt;.bind()&lt;/code&gt;, &lt;code&gt;.live()&lt;/code&gt;, or &lt;code&gt;.delegate()&lt;/code&gt; depending on how you call it.&lt;/code&gt; &lt;br /&gt;
&lt;li&gt;The new direction is to use the new &lt;code&gt;.on&lt;/code&gt; method. Get familiar with the syntax and start using it on all your jQuery 1.7+ projects.&lt;/li&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/ul&gt;Were there any pros or cons that you would have added to the above lists? Have you found yourself using the &lt;code&gt;.delegate&lt;/code&gt; method more recently? What are you thoughts on the new &lt;code&gt;.on&lt;/code&gt; method? Leave your thoughts in the comments. Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-3131166255414772837?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5SHnJ2S59i3ZGl8kmceXMsyI2EQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5SHnJ2S59i3ZGl8kmceXMsyI2EQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5SHnJ2S59i3ZGl8kmceXMsyI2EQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5SHnJ2S59i3ZGl8kmceXMsyI2EQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/3131166255414772837/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/02/differences-between-jquery-bind-vs-live.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3131166255414772837?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3131166255414772837?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/02/differences-between-jquery-bind-vs-live.html" title="Differences Between jQuery .bind() vs .live() vs .delegate() vs .on()" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkMMSHk7eCp7ImA9WhRbEEo.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-1888672182263177278</id><published>2012-01-31T00:00:00.000-06:00</published><updated>2012-01-31T23:34:49.700-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T23:34:49.700-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>How to Access jQuery's Internal Data</title><content type="html">As you may or may not be aware as of jQuery 1.7 the whole event system was rewritten from the ground up. The codebase is much faster and with the new &lt;code&gt;.on()&lt;/code&gt; method there is a lot of uniformity to wiring up event handlers. &lt;br /&gt;
&lt;br /&gt;
One used to be able to access the internal &lt;code&gt;events&lt;/code&gt; data and investiate what events are registered on any given element, but recently this internal information has been hidden based on the following ticket...&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"Ticket #8921: jQuery Private Data Should Stay Private&lt;br /&gt;
&lt;br /&gt;
It seems that the "private" data is ALWAYS stored on the .data(jQuery.expando) - For "objects" where the deletion of the object should also delete its caches this makes some sense.&lt;br /&gt;
&lt;br /&gt;
In the realm of nodes however, I think we should store these "private" members in a separate (private) cache so that they don't pollute the object returned by $.fn.data()" &lt;br /&gt;
&lt;br /&gt;
--&lt;a href="http://bugs.jquery.com/ticket/8921"&gt;http://bugs.jquery.com/ticket/8921&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
Although I agree with the above change to hide the internal data, I have found having access to this information can be helpful for debugging and unit testing.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="twitter-tweet"&gt;What was the new way of getting the internal jquery event object in jQuery 1.7? /cc @&lt;a href="https://twitter.com/DamianEdwards"&gt;DamianEdwards&lt;/a&gt; @&lt;a href="https://twitter.com/elijahmanor"&gt;elijahmanor&lt;/a&gt;&lt;br /&gt;
— Aaron Powell (@slace) &lt;a data-datetime="2012-01-30T03:10:00+00:00" href="https://twitter.com/slace/status/163821232440090624"&gt;January 30, 2012&lt;/a&gt;&lt;/blockquote&gt;&lt;script charset="utf-8" src="//platform.twitter.com/widgets.js"&gt;
&lt;/script&gt;&lt;br /&gt;
Thankfully, if you still need access to the internal data it is still accessible, however, you need to use a method that isn't officially documented... which means that you should be cautious about using it. I would encourage you to not use the undocumented &lt;code&gt;._data()&lt;/code&gt; method in production code.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1709046.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsbin.com/gist/1709046#javascript,html,live"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
On the plus side, if you access the old &lt;code&gt;.data()&lt;/code&gt; method with &lt;code&gt;"events"&lt;/code&gt; as a parameter that will retrieve the internal data containing events and event handlers. &lt;br /&gt;
&lt;br /&gt;
As a side note, if you are looking for events attached using the &lt;code&gt;.live()&lt;/code&gt; or &lt;code&gt;.delegate()&lt;/code&gt; methods then you will need to look at either the &lt;code&gt;document&lt;/code&gt; element or whatever element you delegated against.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Update: Rick Waldron informed me on &lt;a href="https://twitter.com/rwaldron/status/164575242952515585"&gt;twitter&lt;/a&gt; that the jQuery Core team plans on creating a supported plugin to access the internal data that jQuery maintains. This would be a much better solution than using the above undocumented &lt;code&gt;._data()&lt;/code&gt; method because undocumented methods are also unsupported methods ;) I only use the &lt;code&gt;._data()&lt;/code&gt; method for debugging or testing. You should try to avoid using it in any of your production code for this reason.&lt;/i&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-1888672182263177278?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RgWTBKeQ_sVug5GA3Hq8-3oD90M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RgWTBKeQ_sVug5GA3Hq8-3oD90M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RgWTBKeQ_sVug5GA3Hq8-3oD90M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RgWTBKeQ_sVug5GA3Hq8-3oD90M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/1888672182263177278/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/01/how-to-access-jquerys-internal-data.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1888672182263177278?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1888672182263177278?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/01/how-to-access-jquerys-internal-data.html" title="How to Access jQuery's Internal Data" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DkcDR3g5fyp7ImA9WhRUGU0.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-898438444193075365</id><published>2012-01-30T00:14:00.000-06:00</published><updated>2012-01-30T00:14:36.627-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T00:14:36.627-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #3: Give Me Truth</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view other posts in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html"&gt;Find the jQuery Bug #2: Point of No Return&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
We want to take the following HTML &lt;code&gt;div&lt;/code&gt; and build a simple &lt;code&gt;popover&lt;/code&gt; module that uses the jQuery UI Dialog widget. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1702566.js?file=_snippet.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The intent of the following code snippet is to verify that the &lt;code&gt;div&lt;/code&gt; being used in the modal dialog exists in the DOM and that it has not been already initialized. We have an &lt;code&gt;init&lt;/code&gt; method that should initialize the widget and then an &lt;code&gt;open&lt;/code&gt; method that should launch the dialog. The code snippet has some problems. Do you see them?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1702566.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsbin.com/gist/1702566#javascript,html"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
When we run the code, things seem pretty much like what we expected. The widget seems to have been initialized and then opens as expected. We don't actually see the error visually, but there is a problem hidden in the &lt;code&gt;init()&lt;/code&gt; code. If you debug through the code you'll notice something odd when calling &lt;code&gt;init()&lt;/code&gt; again. We put in checks to verify for the existence of the DOM element and that it hasn't been initialized yet, right? Well, that is where the problem lies. Do you see the problem now?&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
At the root of the problem is how we are testing for truth! Both the ways we are checking for existence and initial state are flawed.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"&lt;code&gt;jQuery( selector [, context] )&lt;/code&gt; Returns: jQuery&lt;br /&gt;
Description: Accepts a string containing a CSS selector which is then used to match a set of elements." --&lt;a href="http://api.jquery.com/jquery" target="_blank"&gt;http://api.jquery.com/jquery&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
The check for existence is incorrect, because just checking the result of &lt;code&gt;$( "dialog-modal" )&lt;/code&gt; doesn't get you anywhere. Where does it get you? It always evaluates as &lt;code&gt;true&lt;/code&gt; because a call to &lt;code&gt;$( selector )&lt;/code&gt; returns the jQuery object and based on our &lt;a href="http://james.padolsey.com/javascript/truthy-falsey/"&gt;truthy/falsey rules&lt;/a&gt; an object is always &lt;code&gt;truthy&lt;/code&gt;! What does this mean? Well, it means the code to initialize the DOM element would execute even if it didn't exist at all!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"&lt;code&gt;.not( selector )&lt;/code&gt; Returns: jQuery&lt;br /&gt;
Description: Remove elements from the set of matched elements." --&lt;a href="http://api.jquery.com/not" target="_blank"&gt;http://api.jquery.com/not&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
In a similar fashion the check we were making for the initial state of the DOM element is incorrect. The intent was to check if the element did not have a particular class (&lt;code&gt;.ui-dialog-content&lt;/code&gt;), which is added by jQuery UI when it initializes the dialog widget. If we take a look at the documentation for the &lt;code&gt;.not()&lt;/code&gt; method we'll see that it too returns the jQuery object! The purpose of the method is to filter down the matches by removing elements that match the selector provided. So, we run into the same problem as above where we are always evaluating as &lt;code&gt;truthy&lt;/code&gt;!&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
The solution to fix these problems are really simple and straightforward. All you really need to do is to check how many items where matched by a jQuery selection and to use the &lt;code&gt;.is()&lt;/code&gt; method instead of the &lt;code&gt;.not()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1702743.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsbin.com/gist/1702743#javascript,html,live"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
If you run the above code again you'll notice that the &lt;code&gt;console.log&lt;/code&gt; message only shows up the first time the &lt;code&gt;.init()&lt;/code&gt; method is called.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is to realize that testing against the jQuery object will always evaluate as &lt;code&gt;true&lt;/code&gt;. As shown above it is easy to adjust your code accordingly. &lt;br /&gt;
&lt;br /&gt;
There are other more advanced techniques that can be used for initialization as well. I'd encourage you to look into Doug Neiner's (&lt;a href="http://twitter.com/dougneiner"&gt;@dougneiner&lt;/a&gt;) Contextual jQuery series (&lt;a href="http://events.jquery.org/2010/boston/video/video.php?talk=doug-neiner"&gt;Part 1&lt;/a&gt; and &lt;a href="http://speakerdeck.com/u/dougneiner/p/contextual-jquery-in-practice"&gt;Part 2&lt;/a&gt;) that he gave at the jQuery Boston 2010 and 2011 Conferences. In particular he gave some really interesting just-in-time initialization techniques in the 2nd talk. I highly encourage you viewing these if you haven't already.&lt;br /&gt;
&lt;br /&gt;
Until next time...&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-898438444193075365?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LF5Q86fXiQIHz_zYJpSCcta2eZw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LF5Q86fXiQIHz_zYJpSCcta2eZw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LF5Q86fXiQIHz_zYJpSCcta2eZw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LF5Q86fXiQIHz_zYJpSCcta2eZw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/898438444193075365/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/898438444193075365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/898438444193075365?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/01/find-jquery-bug-3-give-me-truth.html" title="Find the jQuery Bug #3: Give Me Truth" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EARnk-eCp7ImA9WhRUFko.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-7447753122794388716</id><published>2012-01-27T00:09:00.000-06:00</published><updated>2012-01-27T07:40:47.750-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-27T07:40:47.750-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Humor" /><title>Having Fun with JavaScript and Skype Emoticons</title><content type="html">I was chatting with Jim Cowart (&lt;a href="http://twitter.com/ifandelse"&gt;@ifandelse&lt;/a&gt;) on Skype today about jQuery. He pasted in a snippet of code and Skype translated part of it into one of it's emoticons. He almost immediately updated the chat message to fix the issue, but it got me starting to think... and that can be very dangerous.&lt;br /&gt;
&lt;br /&gt;
I thought to myself that it would be fun to create a program that intentionally utilize Skype emoticons. The following screenshot is the result of the program I put together. It is a restaurant where you can listen, eat, and drink ;)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-ahfSeZKBxKs/TyKnzUcw1gI/AAAAAAAAMEU/HcXARGOVis8/s1600/Screen+Shot+2012-01-27+at+7.31.14+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-ahfSeZKBxKs/TyKnzUcw1gI/AAAAAAAAMEU/HcXARGOVis8/s1600/Screen+Shot+2012-01-27+at+7.31.14+AM.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
As you can tell, it is a silly little program. The code for the above screenshot can be found below. Some of the icons I used are &lt;a href="http://www.hiddenskypeemoticons.com/"&gt;secret emoticons&lt;/a&gt; that you can lookup.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1687251.js?file=skype-emoticon-restaurant.js"&gt;
&lt;/script&gt;&lt;br /&gt;
If you'd like to come up with your own Skype-enabled JavaScript program, then I'd like to see it. Share it in the comments. Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-7447753122794388716?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZX_jJoGYsD5jtusR2CbDHXsAjYY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZX_jJoGYsD5jtusR2CbDHXsAjYY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZX_jJoGYsD5jtusR2CbDHXsAjYY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZX_jJoGYsD5jtusR2CbDHXsAjYY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/7447753122794388716/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/01/skype-enabled-javascript-restaurant.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/7447753122794388716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/7447753122794388716?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/01/skype-enabled-javascript-restaurant.html" title="Having Fun with JavaScript and Skype Emoticons" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-ahfSeZKBxKs/TyKnzUcw1gI/AAAAAAAAMEU/HcXARGOVis8/s72-c/Screen+Shot+2012-01-27+at+7.31.14+AM.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkYGSXs6eip7ImA9WhRUGU0.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-532718932635099623</id><published>2012-01-25T08:09:00.000-06:00</published><updated>2012-01-30T00:15:28.512-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T00:15:28.512-06:00</app:edited><title>Find the jQuery Bug #2: Point of No Return</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;You can view my other post in this series...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html"&gt;Find the jQuery Bug #1: Chicken or the Egg&lt;/a&gt;&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;The Desired Feature&lt;/h3&gt;&lt;br /&gt;
We want to take the following HTML unordered list and build a JavaScript function that will determine if a specific value is present.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1670182.js?file=_snippet.html"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;The Buggy Code&lt;/h3&gt;&lt;br /&gt;
The following code snippets is our first attempt at solving the problem, but there is a subtle error. Do you see it?&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1670182.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsbin.com/gist/1670182#javascript,html,live"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
The results that we expected were &lt;code&gt;false, true, true, true, false&lt;/code&gt;, but instead the output in the console is &lt;code&gt;false, false, false, false, false&lt;/code&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
At the root of the problem is the special jQuery &lt;code&gt;.each()&lt;/code&gt; method we are using. The &lt;code&gt;.each()&lt;/code&gt; method is a very handy way to iterate over the jQuery collection, however there is a special meaning to &lt;code&gt;return false&lt;/code&gt; within a &lt;code&gt;.each()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"We can stop the loop from within the callback function by returning false." --&lt;a href="http://api.jquery.com/each" target="_blank"&gt;http://api.jquery.com/each&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
Upon further examination of the code it even makes further sense why it wouldn't work. Most of us are familiar that a &lt;code&gt;return&lt;/code&gt; statement exists the current function, but in this case we aren't invoking the function... jQuery is! So, jQuery has control over what happens when you exit your function prematurely and it recognizes &lt;code&gt;return false&lt;/code&gt; to mean something special.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;A Solution&lt;/h3&gt;&lt;br /&gt;
The solution to fix this problem is really simple and straightforward. All you really need to do is to introduce another variable &lt;code&gt;hasNumber&lt;/code&gt;. If the number was found, then set the &lt;code&gt;hasNumber&lt;/code&gt; variable to &lt;code&gt;true&lt;/code&gt; and then &lt;code&gt;return false;&lt;/code&gt; to exit the &lt;code&gt;.each()&lt;/code&gt; method.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1169945.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsbin.com/gist/1169945#javascript,html,live"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
If you test out the code again below you'll notice that now that we are getting the expected output of &lt;code&gt;false, true, true, true, false&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;An Alternate Solution&lt;/h3&gt;&lt;br /&gt;
An alternate way to solve this problem would be to use another technique completely. In the following example we will use the &lt;code&gt;jQuery.grep&lt;/code&gt; method. The &lt;code&gt;jQuery.grep&lt;/code&gt; method is defined as the following:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"Finds the elements of an array which satisfy a filter function. The original array is not affected." --&lt;a href="http://api.jquery.com/jquery.grep/"&gt;http://api.jquery.com/jquery.grep/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1670312.js?file=fiddle.js"&gt;&lt;/script&gt;&lt;br /&gt;
You can &lt;a href="http://jsbin.com/urofar/edit#javascript,html,live"&gt;view, run, and edit&lt;/a&gt; the above code sample from JSBin.&lt;br /&gt;
&lt;br /&gt;
Although the code looks shorter, it is less performant than the previous solution. Can you tell why? The code is not exiting once the number has been found, but instead goes through each array item and executes the callback function. We get the correct answer, but for a price. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is to be aware of the special mean of &lt;code&gt;return false;&lt;/code&gt; inside of a jQuery &lt;code&gt;.each()&lt;/code&gt; method to exit the loop. Even if you have never made this mistake before, maybe it has opened up your eyes to the fact you can exit out of a &lt;code&gt;.each()&lt;/code&gt; method!&lt;br /&gt;
&lt;br /&gt;
Until next time...&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-532718932635099623?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EVuTXuti8CT6OVrLjdQBUCGmOTs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EVuTXuti8CT6OVrLjdQBUCGmOTs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EVuTXuti8CT6OVrLjdQBUCGmOTs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EVuTXuti8CT6OVrLjdQBUCGmOTs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/532718932635099623/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/532718932635099623?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/532718932635099623?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html" title="Find the jQuery Bug #2: Point of No Return" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0YBRXY-cSp7ImA9WhRbGEU.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-5180194466589618284</id><published>2012-01-19T07:50:00.000-06:00</published><updated>2012-02-10T08:45:54.859-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-10T08:45:54.859-06:00</app:edited><title>Daily and Weekly Front-End Dev Resources</title><content type="html">If you are anything like me, you love and thrive on what is new in the front-end world. What is the latest in HTML5 buzz, what is the newest library that will solve all my needs, what is that new jQuery plugin that will make my client drool, and things of the like.&lt;br /&gt;
&lt;br /&gt;
I used to scour the internet for things like that myself and share them on Twitter and elsewhere, but I've recently changed focus so that I can blog more frequently. My desire for tech news has not diminished in the least, I am still a junkie for new articles and libraries.&lt;br /&gt;
&lt;br /&gt;
So, what am I to do? Well, that is easy. There are many fine resources that have been around for years and there are also some that have cropped up recently that should provide just the right amount of geek influx to quench my thirst and I hope yours as well.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Daily Technology News&lt;/h3&gt;&lt;br /&gt;
&lt;h4&gt;Twitter&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://twitter.com/#!/JavaScriptDaily"&gt;@JavaScriptDaily&lt;/a&gt; by Peter Cooper (&lt;a href="http://twitter.com/peterc"&gt;@peterc&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/#!/jscentral"&gt;@JSCentral&lt;/a&gt; by Béla Varga (&lt;a href="http://twitter.com/netzzwerg"&gt;@netzzwerg&lt;/a&gt;) and Axel Rauschmayer (&lt;a href="http://twitter.com/rauschma"&gt;@rauschma&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/#!/jsgoodies"&gt;@JSGoodies&lt;/a&gt; by Peter van der Zee (&lt;a href="http://twitter.com/kuvos"&gt;@kuvos&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/#!/dailyjs"&gt;@DailyJS&lt;/a&gt; by Alex Young (&lt;a href="http://twitter.com/alex_young"&gt;@alex_young&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/functionsource"&gt;@FunctionSource&lt;/a&gt; by Dion Almaer (&lt;a href="http://twitter.com/dalmaer"&gt;@dalmaer&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/echojs"&gt;@EchoJS&lt;/a&gt; by Frederic Cambus (&lt;a href="http://twitter.com/fcambus"&gt;@fcambus&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h4&gt;Blogs&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dailyjs.com/"&gt;DailyJS&lt;/a&gt;: A JavaScript Blog by Alex Young (&lt;a href="http://twitter.com/alex_young"&gt;@alex_young&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.cwa.me.uk/"&gt;The Morning Brew&lt;/a&gt;: A Daily .NET Software Development Link Blog by Chris Alcock (&lt;a href="http://twitter.com/calcock"&gt;@calcock&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.alvinashcraft.com/"&gt;The Morning Dew&lt;/a&gt;: Your Source for .NET Development Resources by Alvin Ashcraft (&lt;a href="http://twitter.com/alvinashcraft"&gt;@alvinashcraft&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://functionsource.com/"&gt;Function Source&lt;/a&gt;: Your Source for Developer News by Dion Almaer (&lt;a href="http://twitter.com/dalmaer"&gt;@dalmaer&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.echojs.com/"&gt;EchoJS&lt;/a&gt;: A HackerNews-like site dedicated to JavaScript and Front-end News by Frederic Cambus (&lt;a href="http://twitter.com/fcambus"&gt;@fcambus&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h3&gt;Weekly Technology News&lt;/h3&gt;&lt;br /&gt;
&lt;h4&gt;Newsletters&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://javascriptweekly.com/"&gt;JavaScript Weekly&lt;/a&gt; by Peter Cooper (&lt;a href="http://twitter.com/peterc"&gt;@peterc&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://html5weekly.com/"&gt;HTML5 Weekly&lt;/a&gt; by Peter Cooper (&lt;a href="http://twitter.com/peterc"&gt;@peterc&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web-design-weekly.com/"&gt;Web Design Weekly&lt;/a&gt; by Jake Bresnehan (&lt;a href="http://twitter.com/jake_bresnehan"&gt;@jake_bresnehan&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h4&gt;Blogs&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.jsmag.com/blog/category/news/"&gt;JsMag News Roundup&lt;/a&gt; by David Calhoun (&lt;a href="http://twitter.com/franksvalli"&gt;@franksvalli&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h4&gt;Podcasts&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://javascriptshow.com/"&gt;The JavaScript Show&lt;/a&gt; by Peter Cooper (&lt;a href="http://twitter.com/peterc"&gt;@peterc&lt;/a&gt;) and Jason Seifer (&lt;a href="http://twitter.com/jseifer"&gt;@jseifer&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://javascriptjabber.com/"&gt;JavaScript Jabber&lt;/a&gt;: Your Prototype for Great Code hosted by AJ O’Neal (&lt;a href="http://twitter.com/coolaj86"&gt;@coolaj86&lt;/a&gt;), Charles Max Wood (&lt;a href="http://twitter.com/cmaxw"&gt;@cmaxw&lt;/a&gt;), Jamison Dance (&lt;a href="http://twitter.com/jergason"&gt;@jergason&lt;/a&gt;), Peter Cooper (&lt;a href="http://twitter.com/peterc"&gt;@peterc&lt;/a&gt;), and Yehuda Katz (&lt;a href="http://twitter.com/wycats"&gt;@wycats&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://shoptalkshow.com/"&gt;ShopTalk Show&lt;/a&gt;: A live web design and development podcast by Chris Coyier (&lt;a href="chris_coyier"&gt;@chris_coyier&lt;/a&gt;) and Dave Rupert (&lt;a href="http://twitter.com/davatron5000"&gt;@davatron5000&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
[Cross posted from &lt;a href="http://freshbrewedcode.com/elijahmanor/2012/01/19/daily-and-weekly-front-end-dev-resources/"&gt;Fresh Brewed Code&lt;/a&gt;.]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-5180194466589618284?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dGQqEBnewbOeQv04SiC5ebTgAPo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dGQqEBnewbOeQv04SiC5ebTgAPo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dGQqEBnewbOeQv04SiC5ebTgAPo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dGQqEBnewbOeQv04SiC5ebTgAPo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/5180194466589618284/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/01/daily-and-weekly-front-end-dev.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5180194466589618284?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5180194466589618284?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/01/daily-and-weekly-front-end-dev.html" title="Daily and Weekly Front-End Dev Resources" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEACSHg4eip7ImA9WhRUE08.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-1509370407765590803</id><published>2012-01-16T07:52:00.001-06:00</published><updated>2012-01-23T07:52:49.632-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-23T07:52:49.632-06:00</app:edited><title>Bye Bye Tech Tweets</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
As you probably noticed I haven't been blogging as much as I used to. With church, family, work, and tech tweets it seems my free time has dwindled down to nothing.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I want to refocus on blogging again for this year. Not only do I enjoy sharing the things that I learn, but by doing so I tend to learn the topic even better than I did in the first place. Also, many of my conference presentations are based off blog posts that I've authored previously.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So, something needs to give for me to have extra time for blogging and giving up Tech Tweets is what I've chosen. Giving up Tech Tweets wasn't an easy&amp;nbsp;decision&amp;nbsp;for me because I've lived and breathed it for probably the past 5 years or so. It is now in my nature to scour the internet for the latest in front-end news. In order for this to work like I want to I'll need to resist the urge to research everything and share it immediately. I'll need to now depend on the others who are currently doing the research.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Thankfully there are many other avenues to get similar information that I've been providing. Many great&amp;nbsp;resources&amp;nbsp;have cropped up recently that allow you to get front-end news, articles, and library information in a daily or weekly manner. I'll be blogging about what resources I recommend you to follow in the near future. These are the same resources that I'll be using to keep myself up to speed on what is going on.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I am not giving up Twitter or anything. I still will be active on social media, but any tech tweets you see from me will probably be retweets from other resources or just interesting things that I came across that day. Who knows, I might get pulled back into the whole tech tweeting again, but even if I do I'd like to keep it somewhat unstructured.&lt;br /&gt;
&lt;br /&gt;
Thank you all for following me and for regularly retweeting my tech tweets. I do appreciate it. My habbits are changing, but hopfully the posts will be of value to you as well. I have planned out numerous jQuery and jQuery Mobile posts that should keep me busy for quite some time.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
In addition to a renewed interest in blogging I will also focus on posting some content to the newly created&amp;nbsp;&lt;a href="http://freshbrewedcode.com/"&gt;Fresh Brewed Code&lt;/a&gt;&amp;nbsp;website where many of my friends from the Nashville area are now blogging. I don't have any posts there yet, but expect some very soon!&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-1509370407765590803?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5hAFnaUHMGWFpZHiCYyP1SQbNFY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5hAFnaUHMGWFpZHiCYyP1SQbNFY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5hAFnaUHMGWFpZHiCYyP1SQbNFY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5hAFnaUHMGWFpZHiCYyP1SQbNFY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/1509370407765590803/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2012/01/bye-bye-tech-tweets.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1509370407765590803?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/1509370407765590803?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2012/01/bye-bye-tech-tweets.html" title="Bye Bye Tech Tweets" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUAHQ38_fCp7ImA9WhdXEEo.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-5504460820149412367</id><published>2011-08-22T23:28:00.001-05:00</published><updated>2011-08-22T23:28:52.144-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-22T23:28:52.144-05:00</app:edited><title>devLink: Extend your jQuery Application with AmplifyJS</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://j.mp/etm-amplifyjs-slides" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://1.bp.blogspot.com/-H-kZRxAIY0M/TlMqvRMa3zI/AAAAAAAAKOs/sq1f3swhGM4/s1600/15971538220_vjrHH.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Last week I attended the &lt;a href="http://devlink.net/"&gt;devLink conference&lt;/a&gt; in Chattanooga, TN. On Thursday I gave a presentation entitled &lt;i&gt;Extend your jQuery Application with AmplifyJS.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Thank you for everyone who was able to attend the session. Unfortunately the session was not recorded, but you can access &lt;a href="http://j.mp/etm-amplifyjs-slides" target="_blank"&gt;my slides&lt;/a&gt; and play around with the interactive jsFiddles that I demonstrated. You can launch the associated jsFiddles by clicking the "pencil" icon when you see one in the slide's title.&lt;br /&gt;
&lt;br /&gt;
The session was a combination of the &lt;a href="http://msdn.microsoft.com/en-us/scriptjunkie/hh147623"&gt;Script Junkie article&lt;/a&gt; I wrote, by the same name, and also some of the prototyping and unit testing concepts that I presented at the &lt;a href="http://events.jquery.org/2011/sf-bay-area/"&gt;San Francisco jQuery Conference&lt;/a&gt; earlier this year.&lt;br /&gt;
&lt;br /&gt;
Resources mentioned in the session...&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://amplifyjs.com/" target="_blank"&gt;AmplifyJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://swarm.amplifyjs.com/" target="_blank"&gt;AmplifyJS Test Swarm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mennovanslooten/mockJSON" target="_blank"&gt;mockJSON&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-5504460820149412367?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MHgRvLtoInYT8-HEcrRDkIx7kwQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MHgRvLtoInYT8-HEcrRDkIx7kwQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MHgRvLtoInYT8-HEcrRDkIx7kwQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MHgRvLtoInYT8-HEcrRDkIx7kwQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/5504460820149412367/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2011/08/extend-your-jquery-application-with.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5504460820149412367?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/5504460820149412367?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2011/08/extend-your-jquery-application-with.html" title="devLink: Extend your jQuery Application with AmplifyJS" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-H-kZRxAIY0M/TlMqvRMa3zI/AAAAAAAAKOs/sq1f3swhGM4/s72-c/15971538220_vjrHH.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkIFR344fip7ImA9WhdRGUo.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-3667908476630244577</id><published>2011-08-10T00:12:00.006-05:00</published><updated>2011-08-10T07:15:16.036-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-10T07:15:16.036-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Find the jQuery Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Find the jQuery Bug #1: Chicken or the Egg</title><content type="html">&lt;h3&gt;    Introduction&lt;/h3&gt;&lt;br /&gt;
In this open-ended series I'll be showcasing a snippet of buggy jQuery code that you might encounter, explain what the problem is, and then identify how you can easily resolve the issue.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;As this series progresses my example code may not use all the best practices that I would normally use in my everyday development. This is partly due to me wanting to show code you might encounter in the wild, but also because I want these code snippets to be easily understood so that the main concept can be revealed. In order to do that a healthy balance will need to be maintained, which is tricky ;)&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;    The Desired Feature&lt;/h3&gt;&lt;br /&gt;
You have a list of individuals in a table. Each row has an alternating background color (zebra). You can delete them by clicking an icon to the right of each row.&lt;br /&gt;
&lt;br /&gt;
When the trash icon is clicked, a request goes to the server to delete that individual by it's ID. If the action was successful then the row should fade out and then be removed from the DOM. After all is said and done, the rows should be zebra'ed again.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;The following code was inspired by an issue a friend of mine, &lt;a href="http://twitter.com/caseypicker" target="_blank"&gt;Casey Picker&lt;/a&gt; from &lt;a href="http://lamplightmedia.net/" target="_blank"&gt;LamplightMedia.net&lt;/a&gt;, had last week and I helped him isolate the problem. If you don't spot the error right away I have a simplified version of the same underlying issue at the end of the post.&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;    The Buggy Code&lt;/h3&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1124506.js?file=fiddle.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;h3&gt;    The Unexpected Result&lt;/h3&gt;&lt;br /&gt;
&lt;iframe src="http://jsfiddle.net/KyH2y/embedded/result,html,js" style="height: 300px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
When you execute the above code you'll notice that when you delete one of the rows the alternating background colors get all out of sync. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;   The Underlying Problem&lt;/h3&gt;&lt;br /&gt;
Since the row that is being deleted is happening in the success callback function It seemed logical to put the zebraTable call in the complete callback function. That seems right, right? Based on the jQuery documentation the complete callback is only fired after the success function. But why am I having this problem?&lt;br /&gt;
&lt;br /&gt;
Well, the problem is the classic case of treating asynchronous code as synchronous. You might think to yourself, "I know AJAX is asynchronous, but the problem is happening after we've received a response, right?" The answer to that is "Yes", but you the act of animating the fading of the row is also asynchronous.&lt;br /&gt;
&lt;br /&gt;
Once the program starts the hide animation the control of execution moves on to trigger the complete callback function (where the zebraTable call is taking place). After 500 milliseconds, when the row has completed fading out, control is given back to the hide callback which finally removes the row. The bug is that the code is zebra-fying the table before the row is deleted, which isn't what you intended.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;   The Solution&lt;/h3&gt;&lt;br /&gt;
The solution to fix this problem is really simple and straightforward. All you really need to do is to move the zebraTable function call out of the complete callback and immediately after you remove the row from the hide callback. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1124539.js?file=gistfile1.js"&gt;
&lt;/script&gt;&lt;br /&gt;
If you test out the code again below you'll notice that now we have the desired behavior that we were wanting all along. If you delete a row the rows will re-zebra-fy themselves as expected.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://jsfiddle.net/7y69R/embedded/result,html,js" style="height: 300px; width: 100%;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;   Simple Example of the Same Problem&lt;/h3&gt;&lt;br /&gt;
The above example was slightly complex, but the underlying problem of treating asynchronous code as synchronous is common. Here is another example, but this time dramatically simplified. &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1130095.js?file=fiddle.js"&gt;
&lt;/script&gt;&lt;br /&gt;
The above code snippet ( &lt;a href="http://jsfiddle.net/zhqry/" target="_blank"&gt;jsFiddle&lt;/a&gt; ) declares a contact variable and then makes an AJAX call to retrieve contact information from the server. On the &lt;b&gt;next statement&lt;/b&gt; the code is assuming that the contact is already available to display in the console. Unfortunately, since the AJAX is asynchronous the result will not be what you expected.&lt;br /&gt;
&lt;br /&gt;
The most simple fix to the above code snippet is to move the console.log statement to after the AJAX call has successfully returned the server with your contact data as show in the below code snippet ( &lt;a href="http://jsfiddle.net/vFjZJ/" target="_blank"&gt;jsFiddle&lt;/a&gt; ).&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1130097.js?file=fiddle.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;blockquote&gt;Technically this fixes your error, but you might additionally refactor this code to make a callback, trigger an event, or publish a message that the data was retrieved. This would help separate the data access code from your user interface code.&lt;/blockquote&gt;&lt;br /&gt;
&lt;h3&gt;   Conclusion&lt;/h3&gt;&lt;br /&gt;
The key concept to remember here is to &lt;strong&gt;not treat asynchronous code as synchronous&lt;/strong&gt;. Most of us are aware that AJAX calls are asynchronous, but we also need to remember that animations are asynchronous as well. In addition setTimeout and setInterval are also asynchronous.&lt;br /&gt;
&lt;br /&gt;
Until next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-3667908476630244577?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LVZnCB9F4Uwhvva0WAQkYjQx13s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LVZnCB9F4Uwhvva0WAQkYjQx13s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LVZnCB9F4Uwhvva0WAQkYjQx13s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LVZnCB9F4Uwhvva0WAQkYjQx13s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/3667908476630244577/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3667908476630244577?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/3667908476630244577?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2011/08/find-jquery-bug-1-chicken-or-egg.html" title="Find the jQuery Bug #1: Chicken or the Egg" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0MFQ309cCp7ImA9WhdRGE0.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-6434601510639630008</id><published>2011-08-08T08:14:00.004-05:00</published><updated>2011-08-08T08:16:52.368-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-08T08:16:52.368-05:00</app:edited><title>Top JavaScript Developers You Should Follow on Google+</title><content type="html">&lt;a href="http://gpc.fm/l/javascript" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/-duPruOoELgw/Tj_b9MkDK6I/AAAAAAAAKBM/Opi1lmq8mBM/s200/google_plus_logo.jpg" width="183" /&gt;&lt;/a&gt;Like many of you, I've hopped on the &lt;a href="https://plus.google.com/" target="_blank"&gt;Google+&lt;/a&gt; bangwagon and the 1st thing you do on most social networks is to find those individuals that you want to follow.&lt;br /&gt;
&lt;br /&gt;
As many of you are aware I work for &lt;a href="http://appendto.com/"&gt;appendTo&lt;/a&gt; and most of my work these days involves front-end web development ( JavaScript, jQuery, HTML5, etc ). &lt;br /&gt;
&lt;br /&gt;
So, I created the following list of &lt;a href="http://gpc.fm/l/javascript" target="_blank"&gt;60+ JavaScript Developers&lt;/a&gt; on the Google+ Counter website that you might consider circling ( a.k.a. following ).&lt;br /&gt;
&lt;blockquote&gt;Unfortunately since the Google+ API is not yet released you'll have to click each developer and circle them one at a time. Once the API is released hopefully this will be much less painful.&lt;/blockquote&gt;&lt;a href="http://gpc.fm/l/javascript" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-UWM4G3Gxhog/Tj_bhppzHvI/AAAAAAAAKBI/SpU5QXXVx60/s320/Top5JavaScriptGooglePlug.png" width="252" /&gt;&lt;/a&gt;The top 5 individuals that are circled are listed in the image to the right. Hopefully these names are not a surprise to you as they are all highly influential in the JavaScript space.&lt;br /&gt;
&lt;br /&gt;
Google+ is technically still invite only so I image these numbers will increase dramatically over time.&amp;nbsp;I find Google+ already to be a much more conversational way to share knowledge.&lt;br /&gt;
&lt;br /&gt;
Are you on Google+? If not I have &lt;a href="https://plus.google.com/_/notifications/ngemlink?path=%2F%3Fgpinv%3D3rGtJSJ9jKQ%3AesHtanFxNlQ"&gt;some invites&lt;/a&gt; left over. &lt;br /&gt;
&lt;br /&gt;
Also if you circle me ( &lt;a href="http://gplus.to/elijahmanor"&gt;http://gplus.to/elijahmanor&lt;/a&gt; )  I'll put you in my Developer circle and share with you the latest in web development links throughout the week. &lt;br /&gt;
&lt;br /&gt;
Am I missing your favorite JavaScript developer? If so, leave a comment and I'll see about adding them to the list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-6434601510639630008?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/R9pMHa4JYzKxG49sXVUoQC_-LlI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/R9pMHa4JYzKxG49sXVUoQC_-LlI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/R9pMHa4JYzKxG49sXVUoQC_-LlI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/R9pMHa4JYzKxG49sXVUoQC_-LlI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/6434601510639630008/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2011/08/top-javascript-developers-you-should.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/6434601510639630008?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/6434601510639630008?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2011/08/top-javascript-developers-you-should.html" title="Top JavaScript Developers You Should Follow on Google+" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-duPruOoELgw/Tj_b9MkDK6I/AAAAAAAAKBM/Opi1lmq8mBM/s72-c/google_plus_logo.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUQEQ3s7fSp7ImA9WhdRGEw.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-4746010167035092286</id><published>2011-08-02T02:49:00.005-05:00</published><updated>2011-08-08T10:28:22.505-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-08T10:28:22.505-05:00</app:edited><title>7 Chrome Tips Developers &amp; Designers May Not Know</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-wX_MlsWktmI/TjDlzHyAELI/AAAAAAAAJ6o/kT51-4FQMSU/s1600/chrome-firefox1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="128" src="http://1.bp.blogspot.com/-wX_MlsWktmI/TjDlzHyAELI/AAAAAAAAJ6o/kT51-4FQMSU/s200/chrome-firefox1.png" style="float: left; padding-bottom: 15px; padding-right: 15px;" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
I'm not sure about you, but Google Chrome has been my primary browser for quite some time. At first the simplicity and speed of Chrome&amp;nbsp;initially&amp;nbsp;drew me in. I do admit I went back to Firefox every so often for Firebug's rich set of debugging tools.&lt;br /&gt;
&lt;br /&gt;
However, &amp;nbsp;over the past year or so the amount of tooling for developers and designers in Chrome has grown&amp;nbsp;immensely.&lt;br /&gt;
&lt;br /&gt;
Here are some fairly recent features of Google Chrome that you may not be aware of...&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
 1. The ability to modify the source JavaScript and execute it&lt;/h3&gt;
&lt;br /&gt;
How many times have you been tinkering around JavaScript and wished you could tweak it out&amp;nbsp;temporarily&amp;nbsp;just to test something out? Well, if you are using IE or Firefox then you are out of luck, however in Chrome you can just double-click inside a JavaScript file, make changes, and then proceed to run the web application like normal ( see line 33 ).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-BYqkDXr0qTk/TjeJvZHo_uI/AAAAAAAAJ7w/lgIQJmI2m1o/s1600/UpdateScript1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://3.bp.blogspot.com/-NI_jzlTb6l0/TjeM4UgoK2I/AAAAAAAAJ8U/UFiwgOXZR_A/s1600/15602761547_CL8TT.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Usages for this could be as simple as adding a console.log or modifying a piece of code that you think is broken. Of course, you should note that if you refresh the page you will lose all of your changes, so this technique is only meant as a quick and&amp;nbsp;temporary&amp;nbsp;debugging solution.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
 2. The ability to Pretty Print ( a.k.a. unminify ) JavaScript source&lt;/h3&gt;
&lt;br /&gt;
Sometimes I'm trying to figure out a bug and&amp;nbsp;unfortunately&amp;nbsp;the JavaScript that was included has been minified. As you are aware trying to debug a minified file is nearly impossible. How do you set a break point on a line that is a bazillion characters long?&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-BYqkDXr0qTk/TjeJvZHo_uI/AAAAAAAAJ7w/lgIQJmI2m1o/s1600/UpdateScript1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://2.bp.blogspot.com/-gxQ1nFrM6uo/TjeMNclT-sI/AAAAAAAAJ8M/yeJ_e936Qk8/s1600/15602737155_vMBRP.jpg" style="float: left;" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-6n6vf-SMdgg/TjeNPkFTutI/AAAAAAAAJ8Y/sQ12cSIt9_4/s1600/Unminified3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://1.bp.blogspot.com/-MEtpXllQpjo/TjeNet65w_I/AAAAAAAAJ8g/jAOtWTQKwJI/s1600/15602795012_chhmv.jpg" style="float: right;" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="clear: both;"&gt;
&lt;/div&gt;
&lt;br /&gt;
Thankfully Chrome has a Pretty Print feature that will take a minified JavaScript file and format it property. All you need to do is to click the "{ }" icon on the bottom toolbar to activate this feature. Of course the names will still be&amp;nbsp;obfuscated&amp;nbsp;( depending on what program minfied the JavaScript in the first place ), but you will at least be able to set break points and debug the code.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
 3. The ability to break in JavaScript when an element has changed in the DOM&lt;/h3&gt;
&lt;br /&gt;
Let's say that you are tasked with finding the code that manipulates a&amp;nbsp;particular&amp;nbsp;DOM element. It can become quite difficult to track down code for a certain behavior especially if your codebase has grown quite large or if you are diving into a slightly unfamiliar project.&lt;br /&gt;
&lt;br /&gt;
Chrome thankfully saves the day again by providing the following unique features&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Break on subtree modifications&lt;/li&gt;
&lt;li&gt;Break on attributes modifications&lt;/li&gt;
&lt;li&gt;Break on node removal&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both;"&gt;
&lt;a href="http://1.bp.blogspot.com/-IEL7Q5UKAuc/TjeN_YbVOuI/AAAAAAAAJ8k/1VaYxylBUhc/s1600/BreakOfSubTree.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://4.bp.blogspot.com/-CcKSwPNqjI0/TjeOU5WXlfI/AAAAAAAAJ8s/6LCd03HCpKo/s1600/15602814146_rkHps.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This way you can find the DOM element in question and then right-click on it to select one of the above options. Then, when one of the above criteria happens a break point will occur where the JavaScript is performing that action. Brilliant!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both;"&gt;
&lt;a href="http://3.bp.blogspot.com/-eWtu4qme32k/TjeSkofwGbI/AAAAAAAAJ80/H08LSFZ74MY/s1600/BreakPointOnChange2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://4.bp.blogspot.com/-Mjq75MmuGmw/TjeSyvrUUyI/AAAAAAAAJ88/S9KSlr7U2Ao/s1600/15603015935_2GmSc.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Note: The breakpoint  you end up on might be way down in the heart of a minified library (such as jQuery), but fortunately you can use the call stack on the right to find your way back up to where your code lies. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
 4. The ability to change a CSS stylesheet file as if it were an editor&lt;/h3&gt;
&lt;br /&gt;
You are probably familiar with changing the styles on the Elements tab either by manipulating the HTML or by changing values individually on the right in the matched CSS rules section. This concept is very similar to your experiences in Firefox up till today.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-gC2SccbiQRo/TjeZizVWjsI/AAAAAAAAJ9A/Tkdo0GrZpQA/s1600/editcss.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://1.bp.blogspot.com/-145DVpd6fCU/TjeZu480MRI/AAAAAAAAJ9I/hwrny-fp4xY/s1600/15603272896_h3jXb.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Instead of modifying the CSS like above you can switch to the Resources tab and find the CSS file you are interested in, double click inside of it, and make changes to your heart's content ( see line 11 ). A quicker way I do this is by clicking the file &amp;amp;amp; line number link in the Matched CSS Rules pane which jumps me directly to the correct location in the Resources tab where I can start modifying rules.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
 5. The ability to inspect CSS&amp;nbsp;pseudo-class selectors&lt;/h3&gt;
&lt;br /&gt;
Trying to find the pseudo-class rule that matches an element has been considerably painful. How can you hover over an element and at the same time be interacting with the developer tools?&lt;br /&gt;
&lt;br /&gt;
Well, you can now with the Google Chrome. You can access it from the styles pane by clicking the little arrow inside a dashed box ( see the following image ). Then you just check the pseudo-classes that you want to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-zC_1v0Ijn3I/TjebiPOEHcI/AAAAAAAAJ9Q/BQoOmfAo6U8/s1600/csspsudeo2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://3.bp.blogspot.com/-0pOb72wnOis/TjebvqHTy2I/AAAAAAAAJ9Y/w26j9Q77L6o/s1600/15603353513_6zPQD.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Note: This is one of the newer features in Google Chrome and as a result you will need either the dev branch or the canary build for this to work. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
 6. The ability to access most features via keyboard shortcuts&lt;/h3&gt;
&lt;br /&gt;
I love myself some keyboard shortcuts! I've recently picked up MacVim and the Vico App and have really been enjoying it. The great news is that the Chrome Dev Tools also have keyboard shortcuts. When you are in the Elements tab type "?" and the following screen will pop up with a whole bunch of useful keyboard shortcuts. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-6WcUJkCsg1c/TjecvtqghKI/AAAAAAAAJ9c/MI_uGVK0Kis/s1600/keyboardshortcuts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://4.bp.blogspot.com/-4qRot1I5H6M/Tjec6xPLdFI/AAAAAAAAJ9k/0-TJEagn3nw/s1600/15603387250_GMsq9.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
 7. The ability to configure settings your way&lt;/h3&gt;
&lt;br /&gt;
The Dev Tools have a set of options that you may not be aware of. The two options that I find most useful are "Log XMLHttpRequests" ( a feature I missed from Firebug for a long time ) and "Preserve log upon navigation". &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-swwBXHP7JWo/TjedFItAPsI/AAAAAAAAJ9o/CpN3PcrfDQk/s1600/settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://1.bp.blogspot.com/-YQOtNTJo7Y0/TjedR_6YVMI/AAAAAAAAJ9w/n-EvCdaG_N4/s1600/15603404250_5PtL7.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
 &amp;amp;amp; Many, many, more...&lt;/h3&gt;
&lt;br /&gt;
Chrome has been adding a lot of great new features recently. &lt;a href="http://twitter.com/paul_irish"&gt;Paul Irish&lt;/a&gt; has put together several screencasts and videos describing some of these new features. I've highlighted some of these above, but there are many others. &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=nOEw9iiopwI"&gt;Google Chrome Developer Tools: 12 Tricks to Develop Quicker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://paulirish.com/2011/a-re-introduction-to-the-chrome-developer-tools/"&gt;A Re-introduction to the Chrome Developer Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://paulirish.com/2011/quick-color-manipulation-with-the-chrome-devtools/"&gt;Quick color manipulation with the Chrome DevTools &amp;amp;amp; more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=N8SS-rUEZPg&amp;amp;feature=youtu.be"&gt;Google I/O 2011: Chrome Dev Tools Reloaded&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
There is also a &lt;a href="https://github.com/borismus/DevTools-Lab/tree/master/cheatsheet"&gt;cheatsheet&lt;/a&gt; you might be interested in created by &lt;a href="http://twitter.com/borismus"&gt;Boris Smus&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-4746010167035092286?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YT3DOK1EZW_D3WaNic_phz_tUIo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YT3DOK1EZW_D3WaNic_phz_tUIo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YT3DOK1EZW_D3WaNic_phz_tUIo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YT3DOK1EZW_D3WaNic_phz_tUIo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/4746010167035092286/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2011/08/7-chrome-tips-developers-designers-may.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/4746010167035092286?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/4746010167035092286?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2011/08/7-chrome-tips-developers-designers-may.html" title="7 Chrome Tips Developers &amp; Designers May Not Know" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-wX_MlsWktmI/TjDlzHyAELI/AAAAAAAAJ6o/kT51-4FQMSU/s72-c/chrome-firefox1.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A08CSHo9eSp7ImA9WhdSGUQ.&quot;"><id>tag:blogger.com,1999:blog-30404818.post-6030925985187858579</id><published>2011-07-28T23:03:00.003-05:00</published><updated>2011-07-29T23:24:29.461-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-29T23:24:29.461-05:00</app:edited><title>Book Review: JavaScript Enlightenment</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-ajOpmSrycTU/TjIwP0TxWFI/AAAAAAAAJ6s/rwesgqQHFtU/s1600/474f072acc99a66a8d545b923ce75bdd.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" id=":current_picnik_image" src="http://1.bp.blogspot.com/-cDiNfWjVkk4/TjIwg_X9PyI/AAAAAAAAJ60/3DdZwV0GVkY/s1600/15525663053_jXWn9.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
This week jQuery team member &lt;a href="http://twitter.com/#%21/codylindley"&gt;Cody Lindley&lt;/a&gt; self-published the book entitled &lt;a href="http://www.javascriptenlightenment.com/"&gt;JavaScript Enlightenment&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
If you recall he wrote another great resource a year or so ago called &lt;a href="http://jqueryenlightenment.com/"&gt;jQuery Enlightenment&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
As you've probably heard me talk about before, it is important for a jQuery developer to really know the JavaScript language. Thankfully Cody has written this book to aid in this learning process.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Who is the Target Audience of this Book?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The book targets developers who are already &lt;i&gt;JavaScript Library User&lt;/i&gt; (jQuery, dojo, YUI, etc...) and seeks to deepen their knowledge and transform them into a &lt;i&gt;JavaScript Developer&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
The audience isn't intended for beginner JavaScript developers. There is an assumption that you somewhat familiar with using a JavaScript library. If you are a developer that wants to deepen your understanding of JavaScript then this book is for you!&lt;br /&gt;
&lt;br /&gt;
If you do consider yourself a beginner JavaScript or jQuery developer then you might consider going over to &lt;a href="http://appendto.com/"&gt;appendTo&lt;/a&gt;'s new &lt;a href="http://learn.appendto.com/"&gt;learning site&lt;/a&gt; where they have free videos and exercises to guide you through learning these concepts.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What does the book Cover?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The book covers JavaScript 1.5 (also known as ECMA-262 Edition 3), which is the most prevelant version of JavaScript. The book won't be covering some of the new ECMAScript 5 features, but Cody hints that another book might be coming out the in the future to cover some of these new features that are making themselves into current browsers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What to Expect in the book?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It is Cody's style to have lots of code examples in his book. The great thing about this is that he provides a jsFiddle link to the code so that you can pull it up in your browser and play around with it until the concept sinks in. I really enjoyed this in his last book (jQuery Enlightenment) and I'm also loving it in this book.&lt;br /&gt;
&lt;br /&gt;
Cody even goes to explain that the words in the book describing the code should be secondary to the code itself. The examples are there to help you understand what is going on, which is great!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;High Level Overview of Contents?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Cody's book has 15 main chapters and each of them are broken up into much smaller pieces, but to spare you the who table of contents I've just listed out the top level chapters for you to look over below...&lt;br /&gt;
&lt;br /&gt;
Chapter 01 - JavaScript Object&lt;br /&gt;
Chapter 02 - Working with Objects and Properties&lt;br /&gt;
Chapter 03 - Object()&lt;br /&gt;
Chapter 04 - Function()&lt;br /&gt;
Chapter 05 - The Head/Global Object&lt;br /&gt;
&lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/fully-understanding-the-this-keyword/"&gt;Chapter 06 - The this Keyword&lt;/a&gt;&lt;br /&gt;
Chapter 07 - Scope &amp;amp; Closures&lt;br /&gt;
Chapter 08 - Prototype Property&lt;br /&gt;
Chapter 09 - Array()&lt;br /&gt;
Chapter 10 - String()&lt;br /&gt;
Chapter 11 - Number()&lt;br /&gt;
Chapter 12 - Boolean&lt;br /&gt;
Chapter 13 - Null&lt;br /&gt;
Chapter 14 - Undefined&lt;br /&gt;
Chapter 15 - Math Function&lt;br /&gt;
&lt;br /&gt;
You can actually preview all of &lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/fully-understanding-the-this-keyword/"&gt;Chapter 6 - The this Keyword&lt;/a&gt; on the Nettuts website if you are curious as to what some of the content looks like in the book. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Should I Get this Book? &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There is a lot of great material in this book. Most of book is coding examples which means that you can get through it fairly quickly. The book is able to fit in a ton of information in less than 150 pages! I highly recommend this book. There is a lot of value jam packed in this book for a &lt;a href="http://www.javascriptenlightenment.com/"&gt;price tag of $15&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30404818-6030925985187858579?l=www.elijahmanor.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/u6gO7HQ1UjAYMq2rmswQAe0aflY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u6gO7HQ1UjAYMq2rmswQAe0aflY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/u6gO7HQ1UjAYMq2rmswQAe0aflY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u6gO7HQ1UjAYMq2rmswQAe0aflY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.elijahmanor.com/feeds/6030925985187858579/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.elijahmanor.com/2011/07/book-reivew-javascript-enlightenment.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/6030925985187858579?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/30404818/posts/default/6030925985187858579?v=2" /><link rel="alternate" type="text/html" href="http://www.elijahmanor.com/2011/07/book-reivew-javascript-enlightenment.html" title="Book Review: JavaScript Enlightenment" /><author><name>Elijah Manor</name><uri>https://profiles.google.com/110944993173615692737</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-AtW_qomCJAo/AAAAAAAAAAI/AAAAAAAAKA4/4uIXuytCsyM/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-cDiNfWjVkk4/TjIwg_X9PyI/AAAAAAAAJ60/3DdZwV0GVkY/s72-c/15525663053_jXWn9.jpg" height="72" width="72" /><thr:total>0</thr:total></entry></feed>

