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

<channel>
	<title>scriptNode &#187; Advanced</title>
	<atom:link href="http://scriptnode.com/category/advanced/feed/" rel="self" type="application/rss+xml" />
	<link>http://scriptnode.com</link>
	<description>Tips and tricks for web developers.</description>
	<lastBuildDate>Tue, 01 Sep 2009 18:46:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JSQL: JavaScript Query Language</title>
		<link>http://scriptnode.com/article/jsql-javascript-query-language/</link>
		<comments>http://scriptnode.com/article/jsql-javascript-query-language/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 06:12:20 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[lab]]></category>
		<category><![CDATA[script-sunday]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=286</guid>
		<description><![CDATA[About JSQL

When I started my new job, I had to make the transition from YUI to jQuery. I&#8217;d seen some jQuery code before (in fact, its terseness and use of $ as both an object and a function were easy to spot), but I wasn&#8217;t familiar with it. I actually thought that the query part [...]]]></description>
			<content:encoded><![CDATA[<h3>About JSQL</h3>
<p>
When I started <a href="http://richter.paletteswap.com/why-i-left-yahoo-for-a-startup/">my new job</a>, I had to make the transition from <a href="http://developer.yahoo.com/yui/">YUI</a> to <a href="http://jquery.com/">jQuery</a>. I&#8217;d seen some jQuery code before (in fact, its terseness and use of <code>$</code> as both an object and a function were easy to spot), but I wasn&#8217;t familiar with it. I actually thought that the <em>query</em> part of jQuery meant there was some kind of <a href="http://mysql.com/">Standard Query Language</a> interface. There isn&#8217;t, but there is a really cool <a href="http://www.css3.info/">CSS3</a> selector instead.
</p>
<p>
Turns out, I was a little disappointed; I wanted to use something query-based. So, I started to throw this script together. I call it <acronym title="JavaScript Query Language">JSQL</acronym>. Below are some quick examples of what it looks like in action:
</p>
<p><script src="/assets/js/jsql/jsql-min.js" type="text/javascript"></script></p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
var results = JSQL(&#8217;SELECT * FROM #ft WHERE nodeName = &#8220;LI&#8221;);<br />
</textarea></p>
<p>
JSQL always returns an object with an <code>error</code> property that&#8217;s either <code>Boolean false</code> or a <code>String</code> stating what error occurred (for example, &#8220;Unknown command UPDAT3&#8243;). If it successfully retrieves or operates on elements, it returns a <code>count:Number</code> property with the number of elements and an <code>elements:Array</code> property with those elements.
</p>
<p>
Here are some interactive examples:
</p>
<h3>Example 1: Checkboxes</h3>
<div class="section" id="jsql-example-1">
<div>
<input type="checkbox" value=""/> Option number 1
		</div>
<div>
<input type="checkbox" value=""/> Option number 2
		</div>
<div>
<input type="checkbox" value=""/> Option number 3
		</div>
</p></form>
</div>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8217;UPDATE #jsql-example-1 SET checked = true WHERE type = &#8220;checkbox&#8221;&#8216;);<br />
</textarea></p>
<p>
<button id="jsql-button-1">Set Checked</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-1').onclick = function() {
JSQL('UPDATE #jsql-example-1 SET checked = true WHERE type = "checkbox"');
};
</script><br />
<textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8217;UPDATE #jsql-example-1 SET checked = false WHERE type = &#8220;checkbox&#8221;&#8216;);<br />
</textarea></p>
<p>
<button id="jsql-button-1a">Uncheck</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-1a').onclick = function() {
JSQL('UPDATE #jsql-example-1 SET checked = false WHERE type = "checkbox"');
};
</script></p>
<h3>Example 2: Form Validation</h3>
<div class="section" id="jsql-example-2">
<p>
			First name:</p>
<input type="text" value=""/>
<p>
			Last name:</p>
<input type="text" value=""/>
<p>
			Email:</p>
<input type="text" value=""/>
</div>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8217;UPDATE #jsql-example-2 SET parentNode.className = &#8220;error&#8221; WHERE value = &#8220;&#8221;&#8216;);<br />
</textarea></p>
<p>
<button id="jsql-button-2">Highlight empty fields</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-2').onclick = function() {
JSQL('UPDATE #jsql-example-2 SET parentNode.className = "error" WHERE value = ""');
};
</script><br />
<textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8217;UPDATE #jsql-example-2 SET parentNode.className = &#8220;&#8221; WHERE value = &#8220;&#8221;&#8216;);<br />
</textarea></p>
<p>
<button id="jsql-button-2a">Reset</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-2a').onclick = function() {
JSQL('UPDATE #jsql-example-2 SET parentNode.className = "" WHERE value = ""');
};
</script></p>
<h3>Example 3: Removing Elements</h3>
<div class="section" id="jsql-example-3">
<strong>Lorem</strong> Ipsum is simply dummy text of the <strong>printing and</strong> typesetting industry. <strong>Lorem</strong> Ipsum has been the <strong>industry&#8217;s</strong> standard dummy text <strong>ever</strong> since the 1500s, when an unknown printer took a galley of type and scrambled it to make a <strong>type specimen</strong> book. It has survived not only <strong>five</strong> centuries, but also the leap into <strong>electronic</strong> typesetting<strong>, remaining essentially unchanged</strong>. It was popularised in the 1960s with the release of <strong>Letraset</strong> sheets containing <strong>Lorem Ipsum</strong> passages, and more recently with <strong>desktop publishing</strong> software like Aldus PageMaker including versions of <strong>Lorem</strong> Ipsum.
</div>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8217;DELETE FROM #jsql-example-3 WHERE nodeName = &#8220;STRONG&#8221;&#8216;);<br />
</textarea></p>
<p>
<button id="jsql-button-3">Remove strong tags</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-3').onclick = function() {
JSQL('DELETE FROM #jsql-example-3 WHERE nodeName = "STRONG"');
};
</script></p>
<p>
In the spirit of jQuery, I also stuck in a quick <code>each</code> method which you can use to iterate through the returned elements immediately instead of setting up your own loop. The context is the current element (like jQuery) and the return value is still the same:</p>
<h3>Example 4: Selecting Elements</h3>
<div class="section" id="jsql-example-4">
Give him that <em>gun</em>. Give him <em>ALL</em> the guns.
</div>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8221;SELECT * FROM #jsql-example-4 WHERE nodeName = &#8216;EM&#8217;&#8221;).each(function() {<br />
	this.style.background = &#8216;#ffff00&#8242;;<br />
});<br />
</textarea></p>
<p>
<button id="jsql-button-4">Select &amp; Operate</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-4').onclick = function() {
JSQL("SELECT * FROM #jsql-example-4 WHERE nodeName = 'EM'").each(function() {
	this.style.background = '#ffff00';
});
};
</script><br />
<textarea class="javascript" cols="50" name="code" rows="10"><br />
JSQL(&#8221;SELECT * FROM #jsql-example-4 WHERE nodeName = &#8216;EM&#8217;&#8221;).each(function() {<br />
	this.style.background = &#8221;;<br />
});<br />
</textarea></p>
<p>
<button id="jsql-button-4a">Undo</button>
</p>
<p><script type="text/javascript">
document.getElementById('jsql-button-4a').onclick = function() {
JSQL("SELECT * FROM #jsql-example-4 WHERE nodeName = 'EM'").each(function() {
	this.style.background = '';
});
};
</script></p>
<p>
I started coding this several months ago, and just recently decided to revisit it. I found the code hard to read myself when making some modifications before publishing it here. That typically means it&#8217;s poorly written. And I&#8217;m admittedly lousy at writing parsing code&#8230; so there&#8217;s that. I also doubt it&#8217;s realistic for any real-world websites (other libraries handle those jobs quite well), but I thought it would be fun to play with.
</p>
<p>
Some noticeable features lacking are equivalents to <code>ALTER</code> and <code>INSERT INTO</code>. I&#8217;ve also got it <a href="http://github.com/richtaur/jsql/tree/master">up on GitHub</a>, so feel free to fork it, and maybe add those methods yourself!
</p>
<ul>
<li><a href="/assets/js/jsql/jsql.js">[Download jsql.js]</a> (11k)</li>
<li><a href="/assets/js/jsql/jsql-min.js">[Download jsql-min.js]</a> (3,661 bytes)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/jsql-javascript-query-language/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Spacius! Source Code</title>
		<link>http://scriptnode.com/article/spacius-source-code/</link>
		<comments>http://scriptnode.com/article/spacius-source-code/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 05:52:23 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[code-style]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[just-for-fun]]></category>
		<category><![CDATA[lab]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=278</guid>
		<description><![CDATA[
I&#8217;ve been meaning to &#8220;release&#8221; this for quite some time now, but I wanted to do it in small doses, with in-depth explanations of the code. Making a game can be somewhat overwhelming, but it&#8217;s just like any other large task: if you break it up into smaller pieces, it becomes much easier to manage.


But [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve been meaning to &#8220;release&#8221; this for quite some time now, but I wanted to do it in small doses, with in-depth explanations of the code. Making a game can be somewhat overwhelming, but it&#8217;s just like any other large task: if you break it up into smaller pieces, it becomes much easier to manage.
</p>
<p>
But time is a commodity nowadays. I&#8217;ve got way less time to write, and when I do, I&#8217;d rather be writing <em>code</em> than tutorials (or honestly, <a href="http://raptr.com/richtaur"><em>playing</em> video games</a>). Sorry about that, but I hope the (well-commented!) source will help those of you out there who&#8217;d like to contribute to the <a href="http://games.nihilogic.dk/">slowly growing world of DHTML games</a>.
</p>
<p>
You&#8217;ll notice that this code is <a href="/article/spacius-a-space-adventure/">over 6 months old</a>. And I&#8217;m the kind of developer who constantly updates his <a href="/tag/code-style/">style, methods and patterns</a>. Given that, there may very well be many mistakes or bad practices in here, some of which I may have improved upon by now, but others maybe not. Either way, feel free to comment on them, and I&#8217;ll answer any questions as well.
</p>
<p>
Thanks for checking it out, and please be good to it. I&#8217;d love to know about any projects created with this source as a basis, and would appreciate links back here. Also please don&#8217;t claim it as your own, that&#8217;s not cool.
</p>
<div class="section">
For now I am hosting the source code with <a href="http://github.com/richtaur/spacius-/tree/master">GitHub</a>.
</div>
<p>
Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/spacius-source-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Seemingly Snappier User Interface</title>
		<link>http://scriptnode.com/article/a-seemingly-snappier-user-interface/</link>
		<comments>http://scriptnode.com/article/a-seemingly-snappier-user-interface/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 04:55:20 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=263</guid>
		<description><![CDATA[

Say you&#8217;ve got a fancy user interface. You&#8217;re leveraging AJAX well, you&#8217;re making good use of best practices, and you&#8217;ve got fast servers that respond quickly.
But your user actions still aren&#8217;t quite as fast as you&#8217;d like. What else can you do?


If you&#8217;ve done things correctly, you&#8217;ve got a user interface that reacts positively to [...]]]></description>
			<content:encoded><![CDATA[<p><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script></p>
<p>
Say you&#8217;ve got a fancy user interface. You&#8217;re leveraging <a href="http://ajaxian.com">AJAX</a> well, you&#8217;re making good use of <a href="http://yuiblog.com/">best practices</a>, and you&#8217;ve got fast servers that <a href="/tag/optimization/">respond quickly</a>.<br />
But your user actions still aren&#8217;t quite as fast as you&#8217;d like. What else can you do?
</p>
<p>
If you&#8217;ve done things correctly, you&#8217;ve got a user interface that reacts positively to successful flows, but will also handle errors gracefully.<br />
Even though you&#8217;re &#8220;doing it right,&#8221; consider restructuring your application: <strong>assume success</strong>. Normally, your server is up and running and operations<br />
will be completely successfully. The edge case (hopefully) is the error case. Assuming this, we can create a slightly faster user interface.
</p>
<p>
Let&#8217;s begin with a basic voting mechanism. You&#8217;ve got a control on your page that lets a user vote on an object, and a small bit of text to represent the state of said control.<br />
It may look something like this:
</p>
<div class="section">
	<button>Vote</button><br />
	<span>You haven&#8217;t voted yet</span>
</div>
<p>
This example is meant to be easy and functional; hopefully <strong>your</strong> controls are prettier.<br />
Regardless, here&#8217;s a common flow for this request and its callback states:
</p>
<ol>
<li>Listen for the <code>click</code> event on the control.</li>
<li>Send the request.</li>
<li>Display a <a href="http://ajaxload.info/">&#8220;loading&#8221; message or a typical spinner image</a>.
<li>If the call comes back successfully, provide &#8220;success&#8221; feedback to the user and update the control.</li>
<li>If the call throws an error, provide an error message.</li>
</ol>
<p>
This flow is <strong>extremely</strong> common in today&#8217;s web. But we want something more immediately responsive, so let&#8217;s restructure the flow:
</p>
<ol>
<li>
		Use <code>onmousedown</code> because it will fire off just slightly sooner than <code>onclick</code> would.<br />
		(This might not suit all user interfaces but in this case it&#8217;s fine, and it wins us a few milliseconds.)
	</li>
<li>Provide &#8220;success&#8221; feedback to the user and update the control.</li>
<li>Send the request.</li>
<li>If the call throws an error, reset the controls and provide an error message.</li>
</ol>
<p>
This structure might seem a little off. Indeed, the error case even &#8220;lies&#8221; to the user for a few milliseconds if the request fails.<br />
But it covers all of its bases; none of the previous flow is omitted.<br />
Keep in mind that <strong>the error case is the edge case</strong>, and a very large majority of the time it&#8217;s fine to assume success at first.
</p>
<p>
Using <a href="http://jquery.com/">jQuery</a>, here&#8217;s what the code might look like:
</p>
<p><textarea class="javascript" cols="10" name="code" rows="10"><br />
// Attach the mousedown event listener<br />
$(&#8217;#snappier-1-btn&#8217;).mousedown(function(e) {</p>
<p>	var el = $(this);</p>
<p>	// Go ahead and assume things went smoothly<br />
	el.attr(&#8217;disabled&#8217;, true);<br />
	el.next().html(&#8217;Voted!&#8217;);</p>
<p>	// Send the XHR<br />
	$.ajax({<br />
		error : function() {</p>
<p>			// Undo the success message and allow the user to repeat<br />
			el.attr(&#8217;disabled&#8217;, false);<br />
			el.next().html(&#8221;You haven&#8217;t voted yet&#8221;);</p>
<p>			// Let the user know what happened<br />
			alert(&#8221;Sorry, an error occurred! Please try again.&#8221;);</p>
<p>		},<br />
		type : &#8216;GET&#8217;,<br />
		url : &#8216;/feed/&#8217;<br />
	});</p>
<p>});<br />
</textarea></p>
<p>
And here&#8217;s this flow working right here on the page:
</p>
<div class="section">
	<button id="snappier-1-btn">Vote</button><br />
	<span id="snappier-1-msg">You haven&#8217;t voted yet</span>
</div>
<p><script type="text/javascript"></p>
<p>// Attach the mousedown event listener
$('#snappier-1-btn').mousedown(function(e) {</p>
<p>	var el = $(this);</p>
<p>	// Go ahead and assume things went smoothly
	el.attr('disabled', true);
	el.next().html('Voted!');</p>
<p>	// Send the XHR
	$.ajax({
		error : function() {</p>
<p>			// Undo the success message and allow the user to repeat
			el.attr('disabled', false);
			el.next().html("You haven't voted yet");</p>
<p>			// Let the user know what happened
			alert("Sorry, an error occurred! Please try again.");</p>
<p>		},
		type : 'GET',
		url : '/feed/'
	});</p>
<p>});</p>
<p></script></p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/a-seemingly-snappier-user-interface/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Evaluating Script Tags Dynamically</title>
		<link>http://scriptnode.com/article/evaluating-script-tags-dynamically/</link>
		<comments>http://scriptnode.com/article/evaluating-script-tags-dynamically/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 08:00:30 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[code-style]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[script-sunday]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=142</guid>
		<description><![CDATA[
First, a disclaimer: dynamically evaluating scripts is not recommended! Indeed, if your application requires the usage of this script, chances are you&#8217;re doing it wrong. The separation of design and logic likely hasn&#8217;t been properly enforced if you&#8217;re using this method. It&#8217;s just an awkward use-case that should be avoided. That said, here it is&#8230;


Many [...]]]></description>
			<content:encoded><![CDATA[<p>
First, a disclaimer: <strong>dynamically evaluating scripts is not recommended!</strong> Indeed, if your application requires the usage of this script, chances are <em>you&#8217;re doing it wrong</em>. The separation of design and logic likely hasn&#8217;t been properly enforced if you&#8217;re using this method. It&#8217;s just an awkward use-case that should be avoided. That said, here it is&#8230;
</p>
<p>
Many JavaScript libraries support the evaluating of data returned via <a href="http://www.w3.org/TR/XMLHttpRequest/" title="XML Http Request">XHR</a>. Some, like <a href="http://developer.yahoo.com/yui/">YUI</a>, do not (yet). In other cases, folks have rolled their own <a href="http://en.wikipedia.org/wiki/List_of_Ajax_frameworks">&#8220;<acronym title="Asynchronous JavaScript and XML">AJAX</acronym> library&#8221;</a> but still want this behavior. The below script supports searching <acronym title="Hypertext Markup Language">HTML</acronym> for scripts and evaluating them:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
/**<br />
 * Evaluate the passed content for &lt;script&gt; tags<br />
 * @param {String} html The string to parse<br />
 */<br />
var evalHTML = function(html) {</p>
<p>	var piece,<br />
		res = html.split(/&lt;script/);</p>
<p>	res.shift();</p>
<p>	for (var i = 0, len = res.length; i &lt; len; i++) {</p>
<p>		(piece = res[i].split(/&gt;/)).shift();</p>
<p>		try {<br />
			eval(piece.join(&#8217;>').split(&#8217;&lt;/scr&#8217; + &#8216;ipt&gt;&#8217;).shift());<br />
		} catch (e) {}</p>
<p>	}</p>
<p>};<br />
</textarea></p>
<p>You can execute some examples yourself below:</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
// Example 1 &#8211; script inside of a div<br />
evalHTML(&#8217;&lt;div&gt;&lt;scr&#8217; +<br />
&#8216;ipt&gt;alert(&#8221;Hello, JavaScript!&#8221;);&lt;/scr&#8217; +<br />
&#8216;ipt&gt;&#8217;);<br />
</textarea></p>
<p>
<button id="example-eval-1">Execute example 1</button>
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
// Example 2 &#8211; script sets a global variable then displays it<br />
evalHTML(&#8217;&lt;scr&#8217; + &#8216;ipt&gt;var foo = &#8220;bar&#8221;;&lt;/scr&#8217; +&#8217;ipt&gt;&#8217; +<br />
&#8216;&lt;scr&#8217; + &#8216;ipt&gt;alert(foo);&lt;/scr&#8217; +&#8217;ipt&gt;&#8217;);<br />
</textarea></p>
<p>
<button id="example-eval-2">Execute example 2</button>
</p>
<p><script type="text/javascript">
<!--//
var evalHTML=function(html){var piece,res=html.split(/<script/);res.shift();for(var i=0,len=res.length;i<len;i++){(piece=res[i].split(/>/)).shift();try{eval(piece.join(">").split("<\/script>").shift())}catch(e){}}};</p>
<p>YAHOO.util.Event.addListener('example-eval-1', 'click', function() {
evalHTML('
<div><scr' + 
'ipt>alert("Hello, JavaScript!");</scr' +
'ipt>');
});</p>
<p>YAHOO.util.Event.addListener('example-eval-2', 'click', function() {
evalHTML('<scr' + 'ipt>var foo = "bar";</scr' +'ipt>' +
'<scr' + 'ipt>alert(foo);</scr' +'ipt>');
});</p>
<p>//-->
</script></p>
<ul class="download">
<li><a href="/assets/js/dynamic-eval/eval.js">[Download eval.js]</a> (376 bytes)</li>
<li><a href="/assets/js/dynamic-eval/eval-min.js">[Download eval-min.js]</a> (214 bytes; compressed)</li>
</ul>
<p>
<strong>Update 9/28/08:</strong> Fixed a bug thanks to <a href="http://foohack.com/">Isaac Schlueter</a> (see <a href="/article/evaluating-script-tags-dynamically/#comment-197">comments</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/evaluating-script-tags-dynamically/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Conditional Benchmarks</title>
		<link>http://scriptnode.com/article/conditional-benchmarks/</link>
		<comments>http://scriptnode.com/article/conditional-benchmarks/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 07:08:30 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=83</guid>
		<description><![CDATA[

As most JavaScript programmers know (and many are all-too familiar with), speed is a major factor
when considering how to accomplish any given task.
Once in a while, a script will still run too slowly even after standard optimization tricks have been applied.
When this happens, it makes sense to revisit common practices to see if they can [...]]]></description>
			<content:encoded><![CDATA[<p><!-- i can no haz yuiblog :( --></p>
<p>
As most JavaScript programmers know (and many are all-too familiar with), speed is a major factor<br />
when considering how to accomplish any given task.<br />
Once in a while, a script will <em>still</em> run too slowly even after standard optimization tricks have been applied.<br />
When this happens, it makes sense to revisit common practices to see if they can be improved.</p>
<p>
I&#8217;ve noticed that much of the code that I write contains large <code>if</code> blocks and <code>switch</code> statements. Going back and reading what I&#8217;ve written,<br />
I sometimes can&#8217;t figure out why I chose one method over the other, given that they can both get the same job done. Usually I think readability is a factor, but which method is<br />
more readable is typically subjective, making that irrelevant.
</p>
<p>
One use case in which <code>if</code> may be an obvious choice is if the conditionals needed do not translate well into a <code>switch</code>. Here&#8217;s an example:</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
if (((foo === 1) &amp;&amp; (!bar)) || ((foo &gt;= 15) &amp;&amp; (bar !== false))) {<br />
	// It would be messy to make this a switch statement<br />
}<br />
</textarea></p>
<p>
The above block already lacks a bit in readability, and converting it to <code>switch</code> would be a nightmare.<br />
In this instance, <code>if</code> is the clear choice because of its flexibility. In many cases though, a single variable is being checked in a large set of conditionals.<br />
This is the use case that I wanted to explore.
</p>
<p>
To me, JavaScript is all about doing things in clever new ways to overcome limitations.<br />
Given that JavaScript is such an expressive, powerful language, is there a different approach that could be taken regarding these conditional blocks?<br />
One method that can be used is what I call an <em>object conditional</em>.<br />
(This concept is <a href="http://blogs.msdn.com/ie/archive/2006/11/16/ie-javascript-performance-recommendations-part-2-javascript-code-inefficiencies.aspx">not new to the front-end engineering world</a>.)<br />
In the example below I have setup a common, easily readable <code>if</code> block (commented out). After that is the same behavior as described in an object:</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
// Get the value from the select box<br />
var bro = document.getElementById(&#8217;example-1-select&#8217;).value;</p>
<p>/*<br />
if (bro == &#8216;mario&#8217;) {<br />
	alert(&#8221;You selected Mario Mario!!&#8221;);<br />
} else if (bro == &#8216;luigi&#8217;) {<br />
	alert(&#8221;You selected Luigi Mario!&#8221;);<br />
} else {<br />
	alert(&#8221;That&#8217;s not a Mario brother&#8221;);<br />
}<br />
*/</p>
<p>var testObject = {<br />
	&#8216;mario&#8217; : function() {<br />
		alert(&#8221;You selected Mario Mario!&#8221;);<br />
	},<br />
	&#8216;luigi&#8217; : function() {<br />
		alert(&#8221;You selected Luigi Mario!&#8221;);<br />
	}<br />
};</p>
<p>if (bro in testObject) {<br />
	testObject[bro]();<br />
} else {<br />
	alert(&#8221;That&#8217;s not a Mario brother&#8221;);<br />
}<br />
</textarea></p>
<p>
You can run this example by pressing the button below:
</p>
<p>
	<label for="example-1-select">Select a Mario brother:</label></p>
<select id="example-1-select">
		<option value="mario">Mario</option></p>
<p>		<option value="luigi">Luigi</option><br />
		<option value="princess">Princess Toadstool</option><br />
	</select>
<p>	<button id="example-1-exec">Execute this example</button>
</p>
<p><script type="text/javascript">
<!--//
YAHOO.util.Event.addListener('example-1-exec', 'click', function() {</p>
<p>	var bro = document.getElementById('example-1-select').value;</p>
<p>	var testObject = {
		'mario' : function() {
			alert("You selected Mario Mario!");
		},
		'luigi' : function() {
			alert("You selected Luigi Mario!");
		}
	};</p>
<p>	if (bro in testObject) {
		testObject[bro]();
	} else {
		alert("That's not a Mario brother");
	}</p>
<p>});
//-->
</script></p>
<p>There are many things to consider here.<br />
The first and most obvious being that the object conditional itself uses an <code>if</code> block, making it seem like it would be slower than the <code>if</code> alone right off the bat.<br />
The only other way to emulate both <code>else</code> and <code>default</code> without getting the error <em>testObject[bro] is not a function</em><br />
is with a <code>try...catch</code> statement.<br />
Since we all know that <a href="http://scriptnode.com/article/try-catch-benchmark/">catching errors is really slow</a>, that&#8217;s not an option when we&#8217;re going for<br />
high performance. So we&#8217;ll have to settle for using an <code>if</code>.</p>
<p>
Something else to consider is that the scope is lost when calling a function, a problem that&#8217;s not an issue using the other two methods.<br />
This is easily solved, however, by passing whatever you&#8217;d like into the <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function:call">function call</a>, for example:
</p>
<p>
<code>testObject[val].call(args, this, etc);</code>
</p>
<p>
Now that we&#8217;ve got our three different methods, let&#8217;s find out which is fastest!
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
var benchmark = function(runs, id, func) {</p>
<p>	var<br />
		mStart = new Date().getTime(),<br />
		vals = ['a','b','c','d','e'],<br />
		len = vals.length;</p>
<p>	for (var r = 0; r &lt; runs; r++) {<br />
		for (var i = 0; i &lt; len; i++) {<br />
			func(vals[i]);<br />
		}<br />
	}</p>
<p>	var mStop = new Date().getTime(),<br />
		elapsed = (mStop &#8211; mStart);</p>
<p>	document.getElementById(id).innerHTML = elapsed + &#8216; millisecond&#8217; + ((elapsed == 1) ? &#8221; : &#8217;s&#8217;);</p>
<p>};</p>
<p>function funcA() {};<br />
function funcB() {};<br />
function funcC() {};<br />
function funcD() {};<br />
function funcE() {};</p>
<p>var testIf = function(val) {<br />
	if (val == &#8216;a&#8217;) {<br />
		funcA();<br />
	} else if (val == &#8216;b&#8217;) {<br />
		funcB();<br />
	} else if (val == &#8216;c&#8217;) {<br />
		funcC();<br />
	} else if (val == &#8216;d&#8217;) {<br />
		funcD();<br />
	} else {<br />
		funcE();<br />
	}<br />
};</p>
<p>var testSwitch = function(val) {<br />
	switch (val) {<br />
		case &#8216;a&#8217; :<br />
			funcA();<br />
			break;<br />
		case &#8216;b&#8217;:<br />
			funcB();<br />
			break;<br />
		case &#8216;c&#8217;:<br />
			funcC();<br />
			break;<br />
		case &#8216;d&#8217;:<br />
			funcD();<br />
			break;<br />
		default :<br />
			funcE();<br />
			break;<br />
	}<br />
};</p>
<p>var testObject = {<br />
	&#8216;a&#8217; : funcA,<br />
	&#8216;b&#8217; : funcB,<br />
	&#8216;c&#8217; : funcC,<br />
	&#8216;d&#8217; : funcD<br />
};</p>
<p>var testObjectCond = function(val) {<br />
	if (val in testObject) {<br />
		testObject[val]();<br />
	} else {<br />
		funcE();<br />
	}<br />
};</p>
<p>benchmark(10000, &#8216;benchmark-if-res&#8217;, testIf);<br />
benchmark(10000, &#8216;benchmark-switch-res&#8217;, testSwitch);<br />
benchmark(10000, &#8216;benchmark-object-res&#8217;, testObjectCond);<br />
</textarea></p>
<p>
This benchmark sets up three different tests, one with <code>if</code>, one with <code>switch</code>, and one using an object conditional.<br />
Each method checks four different values and then falls into the default, for a total of five states.<br />
This is executed 10,000 times to get a good sampling to work with.<br />
You can execute this benchmark yourself below:
</p>
<div class="section">
<p>	<fieldset><br />
		<legend>Results:</legend></p>
<ul>
<li><code>if</code> block: <span id="benchmark-if-res">(execute to view)</span></li>
<li><code>switch</code> statement: <span id="benchmark-switch-res">(execute to view)</span></li>
<li>object conditional: <span id="benchmark-object-res">(execute to view)</span></li>
</ul>
<p>	</fieldset></p>
<p>	<button id="benchmark-exec">Execute benchmark</button></p>
</div>
<p><script type="text/javascript">
<!--//
YAHOO.util.Event.addListener('benchmark-exec', 'click', function() {</p>
<p>	var benchmark = function(runs, id, func) {</p>
<p>		var
			mStart = new Date().getTime(),
			vals = ['a','b','c','d','e'],
			len = vals.length;</p>
<p>		for (var r = 0; r < runs; r++) {
			for (var i = 0; i < len; i++) {
				func(vals[i]);
			}
		}</p>
<p>		var mStop = new Date().getTime(),
			elapsed = (mStop - mStart);</p>
<p>		document.getElementById(id).innerHTML = elapsed + ' millisecond' + ((elapsed == 1) ? '' : 's');</p>
<p>	};</p>
<p>	function funcA() {};
	function funcB() {};
	function funcC() {};
	function funcD() {};
	function funcE() {};</p>
<p>	var testIf = function(val) {
		if (val == 'a') {
			funcA();
		} else if (val == 'b') {
			funcB();
		} else if (val == 'c') {
			funcC();
		} else if (val == 'd') {
			funcD();
		} else {
			funcE();
		}
	};</p>
<p>	var testSwitch = function(val) {
		switch (val) {
			case 'a' :
				funcA();
				break;
			case 'b':
				funcB();
				break;
			case 'c':
				funcC();
				break;
			case 'd':
				funcD();
				break;
			default :
				funcE();
				break;
		}
	};</p>
<p>	var testObject = {
		'a' : funcA,
		'b' : funcB,
		'c' : funcC,
		'd' : funcD
	};</p>
<p>	var testObjectCond = function(val) {
		if (val in testObject) {
			testObject[val]();
		} else {
			funcE();
		}
	};</p>
<p>	benchmark(10000, 'benchmark-if-res', testIf);
	benchmark(10000, 'benchmark-switch-res', testSwitch);
	benchmark(10000, 'benchmark-object-res', testObjectCond);</p>
<p>});
//-->
</script></p>
<p>
Results will vary of course, but I compiled my findings in the table below.<br />
Using Windows XP, I ran the tests ten times in each of the common browsers and recorded the averages:
</p>
<table cellpadding="3" cellspacing="0" class="results">
<tr>
<th>Browser</th>
<th><code>if</code> block</th>
<th><code>switch</code> statement</th>
<th>object conditional</th>
</tr>
<tr>
<td>Firefox 2</td>
<td class="worst">444 milliseconds</td>
<td>425 milliseconds</td>
<td class="best">310 milliseconds</td>
</tr>
<tr class="toggle">
<td>Firefox 3</td>
<td class="worst">50 milliseconds</td>
<td class="best">38 milliseconds</td>
<td>42 milliseconds</td>
</tr>
<tr>
<td>Google Chrome</td>
<td class="best">11 milliseconds</td>
<td class="best">11 milliseconds</td>
<td>20 milliseconds</td>
</tr>
<tr class="toggle">
<td>Internet Explorer 6</td>
<td class="worst">353 milliseconds</td>
<td>347 milliseconds</td>
<td class="best">290 milliseconds</td>
</tr>
<tr>
<td>Internet Explorer 7</td>
<td class="worst">375 milliseconds</td>
<td>381 milliseconds</td>
<td class="best">344 milliseconds</td>
</tr>
<tr class="toggle">
<td>Opera 9.5</td>
<td class="best">50 milliseconds</td>
<td class="worst">55 milliseconds</td>
<td>54 milliseconds</td>
</tr>
<tr>
<td>Safari 3</td>
<td>150 milliseconds</td>
<td class="worst">156 milliseconds</td>
<td class="best">137 milliseconds</td>
</tr>
</table>
<p>
It looks like the winner in terms of speed is usually the clever contendor, the object conditional.<br />
But not by a large margin. There&#8217;s a lot to be said about code readability, so if<br />
using this method will make your application harder to maintain, it may not be worth it.<br />
Indeed, my colleague <a href="http://crockford.com/">Douglas Crockford</a> (Yahoo!&#8217;s JavaScript architect) has good cautionary advice here:
</p>
<blockquote><p>
In chosing how to structure a program, the first priority has to be clarity of expression. From clarity comes correctness and maintainability. Subordinating clarity to save milliseconds should be discouraged. That is the wrong motivation.
</p>
</blockquote>
<p>
This is certainly true, but sometimes structure unfortunately needs to take a back seat to performance.<br />
The most common use case that comes to my mind is animation.
</p>
<p>
Say for example, you are implementing an animation that moves an element across the screen and must perform complex calculations over each iteration.<br />
Using an animation library like <a href="http://developer.yahoo.com/yui/animation/">the one YUI provides</a>, the code might look something like this:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
var anim = new YAHOO.util.Anim(<br />
	&#8216;example&#8217;,<br />
	{left : {to : 1000}},<br />
	0.1<br />
);</p>
<p>anim.onTween.subscribe(function() {<br />
	// This function must be as optimal as possible<br />
});</p>
<p>anim.animate();<br />
</textarea></p>
<p>
Given this example, optimization is critical, and those few milliseconds gained by using a quicker pattern<br />
could make the difference between a great user experience and a sluggish one.
</p>
<p>
What are your thoughts? I look forward to your feedback in the comments section.
</p>
<p>
<strong>Edit 9/02/08:</strong> Added <a href="http://www.google.com/chrome">Google Chrome</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/conditional-benchmarks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Shark!</title>
		<link>http://scriptnode.com/article/shark/</link>
		<comments>http://scriptnode.com/article/shark/#comments</comments>
		<pubDate>Sun, 03 Aug 2008 10:56:42 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[just-for-fun]]></category>
		<category><![CDATA[lab]]></category>
		<category><![CDATA[script-sunday]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=48</guid>
		<description><![CDATA[
Well, this year&#8217;s Shark Week is over. In its memory, I offer up a script that makes sharks swim around on the screen. You should see a few sharks swimming about right now! Here&#8217;s the source code:


/**
 * Global Shark constructor
 * Options for ops: dir, speed, url, x, y, zIndex
 * @constructor
 * @public
 [...]]]></description>
			<content:encoded><![CDATA[<p>
Well, this year&#8217;s <a href="http://discovery.com/sharkweek/">Shark Week</a> is over. In its memory, I offer up a script that makes sharks swim around on the screen. You should see a few sharks swimming about right now! Here&#8217;s the source code:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
/**<br />
 * Global Shark constructor<br />
 * Options for ops: dir, speed, url, x, y, zIndex<br />
 * @constructor<br />
 * @public<br />
 */<br />
Shark = function(ops) {</p>
<p>	var Y = YAHOO.util,<br />
		DEFAULT_SPEED = 2,<br />
		DEFAULT_ZINDEX = 1000,<br />
		DELAY = 25,<br />
		LEFT = &#8216;l&#8217;,<br />
		RIGHT = &#8216;r&#8217;,<br />
		SCREEN_WIDTH = Y.Dom.getViewportWidth(),<br />
		SCREEN_HEIGHT = Y.Dom.getViewportHeight(),<br />
		SHARK_WIDTH = 242,<br />
		SHARK_HEIGHT = 82;</p>
<p>	var interval,<br />
		that = this;</p>
<p>	that.active = true;<br />
	that.dir = LEFT;<br />
	that.el = {};<br />
	that.onOutLeft = function(){};<br />
	that.onOutRight = function(){};<br />
	that.x = 0;<br />
	that.y = 0;</p>
<p>	/**<br />
	 * Initializes the shark variables<br />
	 * @private<br />
	 */<br />
	var init = function() {</p>
<p>		ops = ops || {};<br />
		ops.speed = ops.speed || rand(DEFAULT_SPEED, (DEFAULT_SPEED * 2));<br />
		ops.url = ops.url || &#8216;./&#8217;;<br />
		ops.zIndex = ops.zIndex || DEFAULT_ZINDEX;</p>
<p>		if (ops.dir) {<br />
			that.dir = ops.dir;<br />
		} else {<br />
			that.dir = [LEFT, RIGHT][rand(0, 1)];<br />
		}</p>
<p>		if (ops.x === undefined) {<br />
			if (that.dir == LEFT) {<br />
				that.x = (SCREEN_WIDTH &#8211; 1);<br />
			} else {<br />
				that.x = -SHARK_WIDTH;<br />
			}<br />
		} else {<br />
			that.x = ops.x;<br />
		}</p>
<p>		that.el = document.createElement(&#8217;div&#8217;);<br />
		that.el.className = &#8217;shark&#8217;; // Doesn&#8217;t do anything. Just in case you want to use it<br />
		that.el.style.position = &#8216;absolute&#8217;;<br />
		that.el.style.height = SHARK_HEIGHT + &#8216;px&#8217;;<br />
		that.el.style.zIndex = ops.zIndex;</p>
<p>		Y.Event.addListener(that.el, &#8216;click&#8217;, onclick);</p>
<p>		document.body.appendChild(that.el);<br />
		reset();</p>
<p>		if (ops.y !== undefined) {<br />
			that.y = ops.y<br />
			plot();<br />
		}</p>
<p>		that.start();</p>
<p>	};</p>
<p>	/**<br />
	 * Kills the shark<br />
	 * @param {Boolean} fade Whether to fade the shark in or not<br />
	 */<br />
	that.kill = function(fade) {</p>
<p>		that.active = false;</p>
<p>		var done = function() {<br />
			document.body.removeChild(that.el);<br />
			stop();<br />
		};</p>
<p>		if (fade) {</p>
<p>			var anim = new Y.Anim(that.el, {opacity : {to : 0}}, 0.5);</p>
<p>			anim.onComplete.subscribe(done);<br />
			anim.animate();</p>
<p>		} else {<br />
			done();<br />
		}</p>
<p>	};</p>
<p>	/**<br />
	 * Move the shark<br />
	 */<br />
	var move = function() {</p>
<p>		if (!that.active) {<br />
			return;<br />
		}</p>
<p>		if (that.dir == LEFT) {</p>
<p>			that.x -= ops.speed;</p>
<p>			if (that.x &lt; -SHARK_WIDTH) {<br />
				that.dir = RIGHT;<br />
				that.onOutLeft();<br />
				reset();<br />
			}</p>
<p>		} else {</p>
<p>			that.x += ops.speed;</p>
<p>			if (that.x &gt; (SCREEN_WIDTH &#8211; 1)) {<br />
				that.dir = LEFT;<br />
				that.x = (SCREEN_WIDTH &#8211; 1);<br />
				that.onOutRight();<br />
				reset();<br />
			}</p>
<p>		}</p>
<p>		if (that.x &gt; (SCREEN_WIDTH &#8211; SHARK_WIDTH)) {<br />
			that.el.style.width = (SHARK_WIDTH &#8211; (that.x &#8211; (SCREEN_WIDTH &#8211; SHARK_WIDTH))) + &#8216;px&#8217;;<br />
		} else {<br />
			that.el.style.width = SHARK_WIDTH + &#8216;px&#8217;;<br />
		}</p>
<p>		plot();</p>
<p>	};</p>
<p>	/**<br />
	 * Kills the shark. Note: intended to be overwritten<br />
	 */<br />
	var onclick = function() {<br />
		that.onclick();<br />
	};</p>
<p>	/**<br />
	 * Default onclick behavior<br />
	 */<br />
	that.onclick = function() {<br />
		that.kill(true);<br />
	};</p>
<p>	/**<br />
	 * Moves the shark element to the XY coordinates<br />
	 */<br />
	var plot = function() {<br />
		that.el.style.left = that.x + &#8216;px&#8217;;<br />
		that.el.style.top = that.y + &#8216;px&#8217;;<br />
	};</p>
<p>	/**<br />
	 * Returns a random number<br />
	 * @param {Number} from The starting point<br />
	 * @param {Number} to The stopping point<br />
	 * @return {Number} A random number within the range<br />
	 */<br />
	var rand = function(from, to) {<br />
		return (from + Math.floor((to &#8211; from + 1) * Math.random()));<br />
	}; </p>
<p>	/**<br />
	 * Sets the background based on direction and randomizes the Y position<br />
	 */<br />
	var reset = function() {</p>
<p>		that.el.style.background = &#8216;url(&#8217; + ops.url + &#8217;shark_&#8217; + that.dir + &#8216;.gif)&#8217;;<br />
		that.y = rand(0, (SCREEN_HEIGHT &#8211; SHARK_HEIGHT &#8211; 1));</p>
<p>		plot();</p>
<p>	};</p>
<p>	/**<br />
	 * Starts the move interval<br />
	 */<br />
	that.start = function() {</p>
<p>		if (interval) {<br />
			return;<br />
		}</p>
<p>		interval = setInterval(move, DELAY);</p>
<p>	};</p>
<p>	/**<br />
	 * Stops the move interval<br />
	 */<br />
	that.stop = function() {<br />
		if (interval) {<br />
			clearInterval(interval);<br />
			interval = false;<br />
		}<br />
	};</p>
<p>	init();</p>
<p>};<br />
</textarea></p>
<p>
You can create new sharks like this:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
var myShark = new Shark();</p>
<p>// Or setup some basics, like having him swim to the left<br />
var anotherShark = new Shark({dir : &#8216;l&#8217;});<br />
anotherShark.onclick = function() {<br />
alert(&#8221;I&#8217;m a shaaaaaaark!&#8221;);<br />
myShark.kill(true); // Kill it with a fade<br />
};</p>
<p>// You may also want to host the shark images yourself:<br />
var hostedShark = new Shark({url : &#8216;http://mydomain.com/shark/&#8217;});<br />
</textarea></p>
<p>
The last example above shows setting a custom <acronym title="Uniform Resource Locator">URL</acronym> for the shark images. You can download those here:
</p>
<p>
<a href="/lab/shark/shark_l.gif"><img alt="Shark!" src="/lab/shark/shark_l.gif"/></a><br />
<a href="/lab/shark/shark_r.gif"><img alt="Shark!" src="/lab/shark/shark_r.gif"/></a>
</p>
<p>
<a class="after" href="/lab/shark/"><img alt="Shark!" src="/assets/img/shark_thumbnail.jpg"/></a><br />
There are a few different events you can subscribe to including <code>onclick</code>, <code>onOutLeft</code> and <code>onOutRight</code>, which I think are pretty self-explanatory.<br />
Using these events, I put together <a href="http://scriptnode.com/lab/shark/">a very simple game</a> involving sharks, clicking and hopelessly trying to save a doomed diver. The ocean graphics came from one of my <a href="http://csszengarden.com/?cssfile=http://www.css-praxis.de/cssocean/zenocean.css">favorite CSS Zen Garden examples</a>.
</p>
<p>
The shark script requires <a href="http://developer.yahoo.com/yui/">YUI</a> (Animation, DOM and Event). I&#8217;ve included it in the third download option below:
</p>
<ul>
<li><a href="/assets/js/shark/shark.js">[Download shark.js]</a> (3,747 bytes)</li>
<li><a href="/assets/js/shark/shark-min.js">[Download shark-min.js]</a> (1,550 bytes; compressed)</li>
<li><a href="/assets/js/shark/shark-min-yui.js">[Download shark-min-yui.js]</a> (46k; compressed with YUI)</li>
</ul>
<p>
I&#8217;d love to see if anybody else has cool ideas of what to do with the shark script!
</p>
<p><script src="/assets/js/shark/shark-min-yui.js" type="text/javascript"></script><br />
<script type="text/javascript">
(function() {
new Shark({url : '/lab/shark/'});
new Shark({url : '/lab/shark/'});
})();
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/shark/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Weekly Round-up (Week of 7/13/08)</title>
		<link>http://scriptnode.com/article/weekly-round-up-week-of-71308/</link>
		<comments>http://scriptnode.com/article/weekly-round-up-week-of-71308/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 07:43:30 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[just-for-fun]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[weekly-roundup]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=41</guid>
		<description><![CDATA[
Last week was an amazing week for web development. If you haven&#8217;t heard about these cool new projects, here&#8217;s what you&#8217;ve been missing out on:



The first thing I saw last week was Scott Schiller&#8217;s amazing Experimental dynamic XBM test, favicon &#8220;VU meter&#8221;. He put his very useful Sound Manager 2 flash API to interesting use: [...]]]></description>
			<content:encoded><![CDATA[<p>
Last week was an <strong>amazing</strong> week for web development. If you haven&#8217;t heard about these cool new projects, here&#8217;s what you&#8217;ve been missing out on:
</p>
<p>
<a href="http://schillmania.com/projects/soundmanager2/demo/page-player/xbm-test.html"><img alt="VU meter" class="after" src="/assets/img/2008_7_13_favicon_vu.gif"/></a><br />
The first thing I saw last week was <a href="http://www.schillmania.com/">Scott Schiller&#8217;s</a> amazing <a href="http://schillmania.com/projects/soundmanager2/demo/page-player/xbm-test.html">Experimental dynamic XBM test, favicon &#8220;VU meter&#8221;</a>. He put his <a href="http://scriptnode.com/lab/spacius/">very useful</a> <a href="http://schillmania.com/projects/soundmanager2/">Sound Manager 2</a> flash API to interesting use: the <a href="http://en.wikipedia.org/wiki/Favicon">favicon</a> displayed in many browsers&#8217; tabs and other places is a VU meter of the current song playing. Awesome! So, using that cool premise, what other neat things could be done…
</p>
<p>
<a href="http://www.p01.org/releases/DHTML_contests/files/DEFENDER_of_the_favicon/"><img alt="DEFENDER of the favicon" class="before" src="/assets/img/defender_of_the_favicon.gif"/></a><br />
Enter <a href="http://www.p01.org/">Mathieu &#8216;p01&#8242; Henri&#8217;s</a> super cool <a href="http://www.p01.org/releases/DHTML_contests/files/DEFENDER_of_the_favicon/">DEFENDER of the favicon</a>! This unbelievable game is confined in a tiny <strong>16&#215;16</strong> box, just big enough for your favicon! You can also hit <code>Enter</code> to transfer the game into a <code>canvas</code> element on the page. So creative, so retro, so cool! I&#8217;ve already spent way too much time playing this game, much to the misfortune of my poor squinting eyes.
</p>
<p>
<a href="http://blog.nihilogic.dk/2008/07/house-of-canvas-radiohead-meets.html"><img alt="Radiohead" class="after" src="/assets/img/radiohead_canvas.gif"/></a><br />
Last but never least is the always impressive <a href="http://blog.nihilogic.dk/">Jacob Seidelin</a> with another mind-blowing demo of what <a href="/tag/javascript/">JavaScript</a> is capable of in the right hands. I&#8217;m sorry if it&#8217;s tiring that I keep reposting what Jacob is up to, but as long as he&#8217;s doing incredible things like this, it&#8217;s not gonna stop.
</p>
<p>
You may have already heard about <a href="http://www.radiohead.com/">Radiohead&#8217;s</a> new <a href="http://code.google.com/creative/radiohead/">video hosted on Google Code</a>. If not, here&#8217;s the gist of it:
</p>
<blockquote><p>
No cameras or lights were used.  Instead two technologies were used to capture 3D images: <a href="http://www.geometricinformatics.com/">Geometric Informatics</a> and <a href="http://www.velodyne.com/lidar/">Velodyne LIDAR</a>.  Geometric Informatics scanning systems produce structured light to capture 3D images at close proximity, while a Velodyne Lidar system that uses multiple lasers is used to capture large environments such as landscapes.  In this video, 64 lasers rotating and shooting in a 360 degree radius 900 times per minute produced all the exterior scenes.
</p>
</blockquote>
<p>
Awesome right? Well Jacob saw this as a challenge from Radiohead and did what he does: <a href="http://blog.nihilogic.dk/2008/07/house-of-canvas-radiohead-meets.html">implemented it in JavaScript and canvas</a>. As usual, super cool stuff.
</p>
<p>
Well, this week&#8217;s almost over, so here&#8217;s to hoping that <strong>next</strong> is half as cool as last week was!</p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/weekly-round-up-week-of-71308/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spacius! A Space Adventure</title>
		<link>http://scriptnode.com/article/spacius-a-space-adventure/</link>
		<comments>http://scriptnode.com/article/spacius-a-space-adventure/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 19:19:43 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[just-for-fun]]></category>
		<category><![CDATA[lab]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=38</guid>
		<description><![CDATA[



I must have been feeling nostalgic, missing my wasted hours playing old Nintendo games as a kid, because last weekend I put together Spacius! A Space Adventure. My goal was to make a fun, simple game using only JavaScript that would work in any browser. That&#8217;s right folks, this game was made using just div [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="/lab/spacius/"><img alt="Spacius! A Space Adventure" src="/assets/img/spacius-a-space-adventure/title.gif"/></a>
</p>
<p>
I must have been feeling nostalgic, missing my wasted hours playing <a href="http://gradius.classicgaming.gamespy.com/">old Nintendo games</a> as a kid, because last weekend I put together <a href="/lab/spacius/">Spacius! A Space Adventure</a>. My goal was to make a fun, simple game using only JavaScript that would work in any browser. That&#8217;s right folks, this game was made using just <code>div</code> elements! Really, there&#8217;s nothing hardcore in here that would require <code>canvas</code>, so I guess that shouldn&#8217;t blow any minds. But this game has been tested and works in IE6, IE7, FireFox 2/3, Opera 9.5 and Safari 3.
</p>
<p>
My one cop-out was falling back on flash for the audio, but until all browsers support HTML5 (or some <a href="http://blog.nihilogic.dk/">mad genius</a> makes a JavaScript-only audio player), this is the best I could do. Spacius! uses <a href="http://www.schillmania.com/">Scott Schiller&#8217;s</a> <em>fantastic</em> <a href="http://www.schillmania.com/projects/soundmanager2/">Sound Manager 2</a> to enable sound. There&#8217;s a little latency, but it otherwise works like a charm.
</p>
<p>
<a href="/lab/spacius/"><img alt="Spacius! A Space Adventure" src="/assets/img/spacius-a-space-adventure/screenshot.gif"/></a>
</p>
<p>
One really cool thing about the way Spacius! works is that it takes the shape of its containing element. So it was really trivial to make an <a href="/lab/spacius/?width=800&amp;height=600">800&#215;600 pixel version</a>.
</p>
<p>
<strong>Here&#8217;s how to play:</strong> Press the <strong>space bar</strong> to begin the game. Use the <strong>arrow keys</strong> to move the ship. Once playing, use the <strong>space bar</strong> to shoot balls of excitement. The <strong>S</strong> key toggles sound on/off.
</p>
<p>
There are <strong>six waves</strong> in Spacius!. The last one begins at <strong>10,000 points</strong>, and it&#8217;s <em>really hard</em> so only total badasses will be able to get super high scores (yes, that&#8217;s a challenge).
</p>
<p>
Here are the <acronym title="Unidentified Flying Object">UFO</acronym> scores:
</p>
<p>
<img alt="Bomber" src="/lab/spacius/ufo_bomber.gif"/><br />
<strong>Bomber:</strong> 15 points
</p>
<p>
<img alt="Bogey" src="/lab/spacius/ufo_bogey.gif"/><br />
<strong>Bogey:</strong> 20 points
</p>
<p>
<img alt="Meteor" src="/lab/spacius/ufo_meteor.gif"/><br />
<strong>Meteor:</strong> 50 points
</p>
<p>
<img alt="Death Star" src="/lab/spacius/ufo_ds.gif"/><br />
<strong>&#8220;Death Star&#8221;:</strong> 25 points
</p>
<p>
So what&#8217;re you waiting for?? <a href="/lab/spacius/">PLAY NOW!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/spacius-a-space-adventure/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>JavaScript print_r() or var_dump() Equivalent</title>
		<link>http://scriptnode.com/article/javascript-print_r-or-var_dump-equivalent/</link>
		<comments>http://scriptnode.com/article/javascript-print_r-or-var_dump-equivalent/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 00:47:24 +0000</pubDate>
		<dc:creator>Matt Hackett</dc:creator>
				<category><![CDATA[Advanced]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[script-sunday]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://scriptnode.com/?p=34</guid>
		<description><![CDATA[
I see a lot of newer JavaScript developers asking about debugging their variables. I think what happens is that they come from a
PHP background and expect to have handy functions available like
print_r() or
var_dump().
And why not? Those are fantastic functions that are infinitely valuable. Either way, being able to debug in this manner is almost
mandatory.


Honestly, my [...]]]></description>
			<content:encoded><![CDATA[<p>
I see a lot of newer JavaScript developers asking about debugging their variables. I think what happens is that they come from a<br />
<a href="http://php.net/">PHP</a> background and expect to have handy functions available like<br />
<code><a href="http://us3.php.net/manual/en/function.print-r.php">print_r()</a></code> or<br />
<code><a href="http://us3.php.net/manual/en/function.var-dump.php">var_dump()</a></code>.<br />
And why not? Those are fantastic functions that are infinitely valuable. Either way, being able to debug in this manner is almost<br />
mandatory.
</p>
<p>
Honestly, my preferred method is<br />
<a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a>&#8217;s <code>console.log()</code>, which lets a developer<br />
pass in a string or series of variables that it will display, like so:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
var myVar = {<br />
	key1 : &#8216;value1&#8242;,<br />
	key2 : &#8216;value2&#8242;,<br />
	key3 : ['a', 'b', 'c']<br />
};</p>
<p>try {<br />
	console.log(&#8217;myVar: &#8216;, myVar);<br />
} catch(e) {<br />
	alert(&#8221;You don&#8217;t have Firebug!\nFor shame&#8230;&#8221;);<br />
}<br />
</textarea></p>
<p>
<button id="example-a">Run this example</button>
</p>
<p><script type="text/javascript">
<!--//
YAHOO.util.Event.addListener('example-a', 'click', function() {
var myVar = {
	key1 : 'value1',
	key2 : 'value2',
	key3 : ['a', 'b', 'c']
};</p>
<p>try {
	console.log('myVar: ', myVar);
} catch(e) {
	alert("You don't have Firebug!\nFor shame...");
}
});
//-->
</script></p>
<p>
I think a large majority of webdevs use both <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a> and Firebug, so this<br />
is nothing new. But there are some edge cases in which it would be nice to have a <code>print_r()</code> equivalent.<br />
For example, if you must debug in a less developer-friendly browser such as<br />
<a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">Internet Explorer</a>.
</p>
<p>
To satisfy these edges cases, I&#8217;ve put together a function similar to <code>print_r()</code>:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
/**<br />
 * Concatenates the values of a variable into an easily readable string<br />
 * by Matt Hackett [scriptnode.com]<br />
 * @param {Object} x The variable to debug<br />
 * @param {Number} max The maximum number of recursions allowed (keep low, around 5 for HTML elements to prevent errors) [default: 10]<br />
 * @param {String} sep The separator to use between [default: a single space ' ']<br />
 * @param {Number} l The current level deep (amount of recursion). Do not use this parameter: it&#8217;s for the function&#8217;s own use<br />
 */<br />
function print_r(x, max, sep, l) {</p>
<p>	l = l || 0;<br />
	max = max || 10;<br />
	sep = sep || &#8216; &#8216;;</p>
<p>	if (l &gt; max) {<br />
		return &#8220;[WARNING: Too much recursion]\n&#8221;;<br />
	}</p>
<p>	var<br />
		i,<br />
		r = &#8221;,<br />
		t = typeof x,<br />
		tab = &#8221;;</p>
<p>	if (x === null) {<br />
		r += &#8220;(null)\n&#8221;;<br />
	} else if (t == &#8216;object&#8217;) {</p>
<p>		l++;</p>
<p>		for (i = 0; i &lt; l; i++) {<br />
			tab += sep;<br />
		}</p>
<p>		if (x &amp;&amp; x.length) {<br />
			t = &#8216;array&#8217;;<br />
		}</p>
<p>		r += &#8216;(&#8217; + t + &#8220;) :\n&#8221;;</p>
<p>		for (i in x) {<br />
			try {<br />
				r += tab + &#8216;[' + i + '] : &#8216; + print_r(x[i], max, sep, (l + 1));<br />
			} catch(e) {<br />
				return &#8220;[ERROR: " + e + "]\n&#8221;;<br />
			}<br />
		}</p>
<p>	} else {</p>
<p>		if (t == &#8217;string&#8217;) {<br />
			if (x == &#8221;) {<br />
				x = &#8216;(empty)&#8217;;<br />
			}<br />
		}</p>
<p>		r += &#8216;(&#8217; + t + &#8216;) &#8216; + x + &#8220;\n&#8221;;</p>
<p>	}</p>
<p>	return r;</p>
<p>};<br />
var_dump = print_r;<br />
</textarea></p>
<p>
This function collects the values of the passed variable and its children and returns them in a formatted string.<br />
The first parameter is the variable itself, the second is the maximum number of recursions to allow (to prevent errors),<br />
and the third is the string to use to separate or indent content (such as a space or a tab).<br />
Here are some examples:
</p>
<p><textarea class="javascript" cols="50" name="code" rows="10"><br />
// EXAMPLE 1<br />
var myVar1 = {&#8217;true&#8217; : true, &#8216;false&#8217; : false, num : 3};<br />
alert(print_r(myVar1));</p>
<p>// EXAMPLE 2<br />
var myVar2 = [{'legend' : 'zelda'}, {'foo' : {'bar' : null}}, 'a', 'b', [1, 2, { 'key' : 'value'}, 'bill', 'ted']];<br />
alert(print_r(myVar2, 10, &#8220;\t&#8221;));</p>
<p>// EXAMPLE 3 (this one outputs a LOT, even with a max of 5)<br />
var myVar3 = document.body;<br />
alert(print_r(myVar3, 5));<br />
</textarea></p>
<p>
<button id="example-1">Run example 1</button><br />
<button id="example-2">Run example 2</button><br />
<button id="example-3">Run example 3</button>
</p>
<p><script type="text/javascript">
<!--//
YAHOO.util.Event.addListener('example-1', 'click', function() {
var myVar1 = {'true' : true, 'false' : false, num : 3};
alert(print_r(myVar1));
});
YAHOO.util.Event.addListener('example-2', 'click', function() {
var myVar2 = [{'legend' : 'zelda'}, {'foo' : {'bar' : null}}, 'a', 'b', [1, 2, { 'key' : 'value'}, 'bill', 'ted']];
alert(print_r(myVar2, 10, "\t"));
});
YAHOO.util.Event.addListener('example-3', 'click', function() {
var myVar3 = document.body;
alert(print_r(myVar3, 5));
});
//-->
</script></p>
<p>
Even if you&#8217;re a devout Firebug user and this function has no use for you, I still thought it might be helpful to see how this kind<br />
of thing would be put together.
</p>
<ul>
<li><a href="/assets/js/print_r/print_r.js">[Download print_r.js]</a> (1,271 bytes)</li>
<li><a href="/assets/js/print_r/print_r-min.js">[Download print_r-min.js]</a> (427 bytes; compressed)</li>
</ul>
<p><script type="text/javascript">
<!--//</p>
<p>function print_r(x, max, sep, l) {</p>
<p>	l = l || 0;
	max = max || 10;
	sep = sep || ' ';</p>
<p>	if (l > max) {
		return "[WARNING: Too much recursion]\n";
	}</p>
<p>	var
		i,
		r = '',
		t = typeof x,
		tab = '';</p>
<p>	if (x === null) {
		r += "(null)\n";
	} else if (t == 'object') {</p>
<p>		l++;</p>
<p>		for (i = 0; i < l; i++) {
			tab += sep;
		}</p>
<p>		if (x &#038;&#038; x.length) {
			t = 'array';
		}</p>
<p>		r += '(' + t + ") :\n";</p>
<p>		for (i in x) {
			try {
				r += tab + '[' + i + '] : ' + print_r(x[i], max, sep, (l + 1));
			} catch(e) {
				return "[ERROR: " + e + "]\n";
			}
		}</p>
<p>	} else {</p>
<p>		if (t == 'string') {
			if (x == '') {
				x = '(empty)';
			}
		}</p>
<p>		r += '(' + t + ') ' + x + "\n";</p>
<p>	}</p>
<p>	return r;</p>
<p>};</p>
<p>//-->
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://scriptnode.com/article/javascript-print_r-or-var_dump-equivalent/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
