<?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/"
xmlns:series="http://unfoldingneurons.com/"
><channel><title>David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞. &#187; JavaScript</title> <atom:link href="http://davidwalsh.name/tutorials/javascript/feed" rel="self" type="application/rss+xml" /><link>http://davidwalsh.name</link> <description>Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</description> <lastBuildDate>Sun, 20 May 2012 22:40:48 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>QUOTA_EXCEEDED_ERR in Mobile&#160;Safari</title><link>http://davidwalsh.name/quota_exceeded_err</link> <comments>http://davidwalsh.name/quota_exceeded_err#comments</comments> <pubDate>Thu, 17 May 2012 19:21:35 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Mobile]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5431</guid> <description><![CDATA[I&#8217;ve been working on an HTML5 application for the new Mozilla Marketplace, writing a tutorial along the way to help all of you create and promote your HTML5 web-powered app.  The HTML5 app uses localStorage to save basic search history, as well as other newer APIs.  While testing my application on my iPhone, I was [...]<p><a
href="http://davidwalsh.name/quota_exceeded_err">QUOTA_EXCEEDED_ERR in Mobile&nbsp;Safari</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I&#8217;ve been working on an HTML5 application for the new <a
href="https://marketplace.mozilla.org/">Mozilla Marketplace</a>, writing a tutorial along the way to help all of you create and promote your HTML5 web-powered app.  The HTML5 app uses localStorage to save basic search history, as well as other newer APIs.  While testing my application on my iPhone, I was seeing the following error:</p><pre class="js">
localStorage.setItem("history", JSON.stringify(myObject));
</pre><p>The error caused my app to break, refreshing the page and rendering the app useless!  After a bit of research, I found that the reason for the error was that my Mobile Safari&#8217;s Private Browsing was turned on.  You&#8217;d expect a silent error when this mode is one, but nope &#8212; simply a bricked app.  Since there&#8217;s no way to detect if the user&#8217;s browser is in &#8220;Private Browsing&#8221; is turned on (feature detection still works), the best solution is to wrap localStorage setters in <code>try {} / catch() {}</code> blocks:</p><pre class="js">
try {
	localStorage.setItem("history", JSON.stringify(myObject));
}
catch(e) {}
</pre><p>I&#8217;m not seeing a better solution at the moment.  Since there&#8217;s now way to track Private Mode, and certain interactions break in this mode, using <code>try {} / catch() {}</code> blocks appears to be the best solution.</p><p><a
href="http://davidwalsh.name/quota_exceeded_err">QUOTA_EXCEEDED_ERR in Mobile&nbsp;Safari</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/quota_exceeded_err/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Selector Engines: Right to&#160;Left</title><link>http://davidwalsh.name/selectors</link> <comments>http://davidwalsh.name/selectors#comments</comments> <pubDate>Wed, 09 May 2012 01:33:59 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5428</guid> <description><![CDATA[One lessor known fact about CSS selectors, querySelectorAll, and JavaScript-based selector engines is that they read your selectors from right to left.  This news hit me as illogical at first, as you&#8217;d think that the first element in a selector string like &#8220;#myElement a.something .else&#8221; would provide a base context, but no:  the &#8220;.else&#8221; is [...]<p><a
href="http://davidwalsh.name/selectors">Selector Engines: Right to&nbsp;Left</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>One lessor known fact about CSS selectors, querySelectorAll, and JavaScript-based selector engines is that they read your selectors from right to left.  This news hit me as illogical at first, as you&#8217;d think that the first element in a selector string like &#8220;#myElement a.something .else&#8221; would provide a base context, but no:  the &#8220;.else&#8221; is search for first.  After more thought, searching for the right-most selector piece makes sense, as you instead collect the &#8220;.else&#8221; elements first (instead of, theoretically, all the elements under &#8220;#myElement&#8221;, then &#8220;a.something&#8221; elements, and so on) and then look up the chain for matches.  Essentially, you grab all the potential matches and then confirm by walking up the DOM tree, instead of grabbing the parent and look for matches on the way down.</p><p>I was recently looking at popular development site and found the following snippet:</p><pre class="js">
jQuery("#subscribe-main li:nth-child(4)")....
</pre><p>This snippet found the desired elements in 1ms according to FireBug&#8217;s console.  A millisecond is lightning fast, but if you slightly change the selector code, you get a faster result:</p><pre class="js">
jQuery("li:nth-child(4)", "#subscribe-main");

// Could use this as well
// jQuery("#subscribe-main").find("li:nth-child(4)")....
</pre><p>The selection code above returns the same elements in 0ms.  A millisecond difference is negligible in one instance, but in a large application, these milliseconds will add up!</p><p>This post simply acts a a reminder that selector composition is important.  Here&#8217;s a task for you:  go to the sites you&#8217;ve written the JavaScript selectors for and compare your selectors like I have above.  If you aren&#8217;t familiar with basic selector time testing via the console, here&#8217;s how you do it:</p><pre class="js">
console.time("someKey");
jQuery("#mySelector .more .stuff")...
console.timeEnd("someKey");
</pre><p>The console doesn&#8217;t do better than millisecond precision, but a different result at that precision gets you started in selector enhancement.  Happy selector revising!</p><p><a
href="http://davidwalsh.name/selectors">Selector Engines: Right to&nbsp;Left</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/selectors/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>JavaScript Canvas Image&#160;Conversion</title><link>http://davidwalsh.name/convert-canvas-image</link> <comments>http://davidwalsh.name/convert-canvas-image#comments</comments> <pubDate>Tue, 08 May 2012 15:53:56 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Markup]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5426</guid> <description><![CDATA[At last week&#8217;s Mozilla WebDev Offsite, we all spent half of the last day hacking on our future Mozilla Marketplace app. One mobile app that recently got a lot of attention was Instagram, which sold to Facebook for the bat shit crazy price of one billion dollars. Since I wouldn&#8217;t mind having a bill in [...]<p><a
href="http://davidwalsh.name/convert-canvas-image">JavaScript Canvas Image&nbsp;Conversion</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>At last week&#8217;s Mozilla WebDev Offsite, we all spent half of the last day hacking on our future Mozilla Marketplace app.  One mobile app that recently got a lot of attention was Instagram, which sold to Facebook for the <del>bat shit crazy</del> price of one billion dollars.  Since I wouldn&#8217;t mind having a bill in my back account, I decided to create an Instagram-style app (which I&#8217;ll share with you in the future).  This post details how you can convert an image to canvas and convert a canvas back to an image.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/convert-canvas-image.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>Convert an Image to Canvas with&nbsp;JavaScript</h2><p>To convert an image to canvas, you use a canvas element&#8217;s context&#8217;s <code>drawImage</code> method:</p><pre class="js">
// Converts image to canvas; returns new canvas element
function convertImageToCanvas(image) {
	var canvas = document.createElement("canvas");
	canvas.width = image.width;
	canvas.height = image.height;
	canvas.getContext("2d").drawImage(image, 0, 0);

	return canvas;
}
</pre><p>The <code>0, 0</code> arguments map to coordinates on the canvas where the image data should be placed.</p><h2>Convert Canvas to an Image with&nbsp;JavaScript</h2><p>Assuming modifications to the image have been made, you can easily convert the canvas data to image data with the following snippet:</p><pre class="js">
// Converts canvas to an image
function convertCanvasToImage(canvas) {
	var image = new Image();
	image.src = canvas.toDataURL("image/png");
	return image;
}
</pre><p>The code above magically converts the canvas to a PNG data URI!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/convert-canvas-image.php" class="demo">View Demo</a><div
class="clear"></div></div><p>Alas, converting an image to canvas and canvas to an image is probably much easier than you think.  In future posts, I&#8217;ll detail how you can apply different image filters to your canvased image.  In the mean time, start buying fancy cars and houses with the future billion you&#8217;ll have!</p><p><a
href="http://davidwalsh.name/convert-canvas-image">JavaScript Canvas Image&nbsp;Conversion</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/convert-canvas-image/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Detect DOM Node Insertions with JavaScript and CSS&#160;Animations</title><link>http://davidwalsh.name/detect-node-insertion</link> <comments>http://davidwalsh.name/detect-node-insertion#comments</comments> <pubDate>Mon, 07 May 2012 14:20:20 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5425</guid> <description><![CDATA[I work with an awesome cast of developers at Mozilla, and one of them in Daniel Buchner. Daniel&#8217;s shared with me an awesome strategy for detecting when nodes have been injected into a parent node without using the deprecated DOM Events API. This hack uses JavaScript, as you would expect, but another technology you wouldn&#8217;t [...]<p><a
href="http://davidwalsh.name/detect-node-insertion">Detect DOM Node Insertions with JavaScript and CSS&nbsp;Animations</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I work with an awesome cast of developers at Mozilla, and one of them in <a
href="http://www.backalleycoder.com/">Daniel Buchner</a>.  Daniel&#8217;s shared with me an awesome strategy for detecting when nodes have been injected into a parent node without using the deprecated <a
href="http://davidwalsh.name/dom-events-javascript">DOM Events API</a>.  This hack uses JavaScript, as you would expect, but another technology you wouldn&#8217;t expect:  CSS animations.  Let me prove to you that it works!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/detect-node-insertion.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>The&nbsp;HTML</h2><p>All that&#8217;s required is a parent element with which we&#8217;d like to listen to node insertions within:</p><pre class="html">
&lt;ul id="parentElement"&gt;&lt;/ul&gt;
</pre><p>You can use any selector helper you&#8217;d like, but I&#8217;ve chosen an ID here.</p><h2>The&nbsp;CSS</h2><p>In order to get a handle on node insertion detection, we need to set up a series of keyframe animations which will start when the node is inserted.  The clip property is used since it has no effect on the node itself:</p><pre class="css">
/* set up the keyframes */
@keyframes nodeInserted {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }  
}

@-moz-keyframes nodeInserted {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}

@-webkit-keyframes nodeInserted {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}

@-ms-keyframes nodeInserted {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}

@-o-keyframes nodeInserted {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}
</pre><p>With the keyframes created, the animation needs to be applied on the elements you&#8217;d like to listen for.  Note the tiny duration;  that relaxes the animation footprint on the browser.</p><pre class="css">
#parentElement > li {
    animation-duration: 0.001s;
    -o-animation-duration: 0.001s;
    -ms-animation-duration: 0.001s;
    -moz-animation-duration: 0.001s;
    -webkit-animation-duration: 0.001s;
    animation-name: nodeInserted;
    -o-animation-name: nodeInserted;
    -ms-animation-name: nodeInserted;        
    -moz-animation-name: nodeInserted;
    -webkit-animation-name: nodeInserted;
}
</pre><p>Add the animation to the child nodes you are listening for.  When the animation ends, the insertion event will fire!</p><h2>The&nbsp;JavaScript</h2><p>The first step is creating an function which will act as the event listener callback.  Within the function, an initial event.animationName check must be made to ensure it&#8217;s the animation name we want to listen for in this specific case:</p><pre class="js">
var insertListener = function(event){
	if (event.animationName == "nodeInserted") {
		// This is the debug for knowing our listener worked!
		// event.target is the new node!
		console.warn("Another node has been inserted! ", event, event.target);
	}
}
</pre><p>If the animation name matches the desired animation, we know a DOM node has been injected.  Now it&#8217;s time to add the event listener to the parent:</p><pre class="js">
document.addEventListener("animationstart", insertListener, false); // standard + firefox
document.addEventListener("MSAnimationStart", insertListener, false); // IE
document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari
</pre><p>How awesomely simple is that?!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/detect-node-insertion.php" class="demo">View Demo</a><div
class="clear"></div></div><p>Daniel created this solution to aid in his forthcoming web components initiative, an initiative I&#8217;ll be covering more in depth very soon.  This node insertion hack is useful and uses no framework, so it&#8217;s an incredible mechanism that can be used by anyone.  Well done to Daniel!</p><p><a
href="http://davidwalsh.name/detect-node-insertion">Detect DOM Node Insertions with JavaScript and CSS&nbsp;Animations</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/detect-node-insertion/feed</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>JavaScript CSS&#160;Helpers</title><link>http://davidwalsh.name/javascript-css</link> <comments>http://davidwalsh.name/javascript-css#comments</comments> <pubDate>Wed, 04 Apr 2012 00:12:44 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5410</guid> <description><![CDATA[I spend a good amount of time looking at JavaScript framework source code. Regardless of which frameworks you have allegiance to, you can learn an awful lot by looking under the hood of widely used code collections. One of many handy snippets can be found within the MooTools source code: functions to camelize and hyphenate [...]<p><a
href="http://davidwalsh.name/javascript-css">JavaScript CSS&nbsp;Helpers</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I spend a good amount of time looking at JavaScript framework source code.  Regardless of which frameworks you have allegiance to, you can learn an awful lot by looking under the hood of widely used code collections.  One of many handy snippets can be found within the MooTools source code:  functions to camelize and hyphenate strings so that your own min framework can accept either form of CSS setter or getter.  Here are the functions in all of their glory.</p><h2>The&nbsp;JavaScript</h2><p>As you could probably guess, this task is best accomplished with regular expressions:</p><pre class="js">
function camelize(str) {
	return (str + "").replace(/-\D/g, function(match) {
		return match.charAt(1).toUpperCase();
	});
}
camelize("border-bottom-color"); // "borderBottomColor"


function hyphenate(str) {
	return (str + "").replace(/[A-Z]/g, function(match) {
		return "-" + match.toLowerCase();
	});
}
hyphenate("borderBottomColor"); // "border-bottom-color"
</pre><p>A couple of really handy JavaScript String to corresponding String format functions.  Instead of expecting strings in only one format, your mini library can now accept both!</p><p><a
href="http://davidwalsh.name/javascript-css">JavaScript CSS&nbsp;Helpers</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/javascript-css/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Load CSS Files via AMD with&#160;XStyle</title><link>http://davidwalsh.name/amd-xstyle</link> <comments>http://davidwalsh.name/amd-xstyle#comments</comments> <pubDate>Tue, 27 Mar 2012 15:54:41 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5408</guid> <description><![CDATA[AMD loaders are letting us load just about anything: AMD modules, basic JavaScript files (from any origin), text-based files (HTML templates, for example), and more. Unfortunately most loaders don&#8217;t have CSS loading capabilities, most likely because &#8220;onLoad&#8221;-style events aren&#8217;t provided by all browsers for stylesheets. Luckily my SitePen colleague Kris Zyp has created XStyle, an [...]<p><a
href="http://davidwalsh.name/amd-xstyle">Load CSS Files via AMD with&nbsp;XStyle</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>AMD loaders are letting us load just about anything: AMD modules, basic JavaScript files (from any origin), text-based files (HTML templates, for example), and more.  Unfortunately most loaders don&#8217;t have CSS loading capabilities, most likely because &#8220;onLoad&#8221;-style events aren&#8217;t provided by all browsers for stylesheets.  Luckily my SitePen colleague Kris Zyp has created XStyle, an AMD package available to AMD loaders for reliable stylesheet loading.  Let&#8217;s take a brief look at XStyle!</p><div
class="actions"><a
href="https://github.com/kriszyp/xstyle" rel="nofollow" class="demo">View Demo</a><div
class="clear"></div></div><p>In fairness to XStyle, it&#8217;s more than just an AMD plugin for loading stylesheets.  XStyle provides the capability to:</p><ul><li>Shim and extend CSS</li><li>Load stylesheets and execute callbacks</li><li>Nested @import loading</li></ul><p>Shimming and extending CSS is great but doesn&#8217;t seem to be something I would need often;  loading CSS with JavaScript modules is nice because:</p><ol><li>Loading modules and templates together but needing to add LINK tags manually sucks</li><li>One define() to define a <em>complete</em> widget from JS, to template, and CSS, is ideal;  especially for third party components</li></ol><p>So consider a great JavaScript loader like <a
href="https://github.com/cujojs/curl" rel="nofollow">curl.js</a>.  With curl.js, all you need to do to load a CSS file is:</p><pre class="js">
curl(["css!path/to/file.css"], function() {
    // defineCSS loaded, do stuff!
});
</pre><p>Sweet, right?  With a different loader, you can load your CSS files with other modules by coding:</p><pre class="js">
define(["xstyle!./path/to/file.css"], function(){
    // module starts after css is loaded
});
</pre><p>Outstanding!  With XStyle we can define a <em>complete</em> component, stylesheet and all!</p><div
class="actions"><a
href="https://github.com/kriszyp/xstyle" rel="nofollow" class="demo">View Demo</a><div
class="clear"></div></div><p>XStyle is capable of much more than what I&#8217;ve presented above, but just the ability to load stylesheets with every other piece of a given module is priceless.  Improves organization and speed of coding;  well done Kris!</p><p>&nbsp;</p><p><a
href="http://davidwalsh.name/amd-xstyle">Load CSS Files via AMD with&nbsp;XStyle</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/amd-xstyle/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>curl.js: Incredible AMD&#160;Loader</title><link>http://davidwalsh.name/curljs</link> <comments>http://davidwalsh.name/curljs#comments</comments> <pubDate>Mon, 26 Mar 2012 13:40:50 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[AJAX]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5383</guid> <description><![CDATA[Today there are dozens of AMD JavaScript loaders available, the most popular being RequireJS. There are also lesser known JavaScript loaders like YepNope, $script.js, LABjs, and Dojo&#8217;s new native loader. My favorite JavaScript loader, however, is John Hann (unscriptable)&#8217;s curl. While allowing for maximum configuration and reliable loading, curl also allows for loading of simple [...]<p><a
href="http://davidwalsh.name/curljs">curl.js: Incredible AMD&nbsp;Loader</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Today there are dozens of AMD JavaScript loaders available, the most popular being RequireJS.  There are also lesser known JavaScript loaders like YepNope, $script.js, LABjs, and Dojo&#8217;s new native loader.  My favorite JavaScript loader, however, is John Hann (unscriptable)&#8217;s <a
href="https://github.com/unscriptable/curl">curl</a>.  While allowing for maximum configuration and reliable loading, curl also allows for loading of simple JavaScript files as well as CSS files.  Let me show you how to use it!</p><div
class="actions"><a
href="https://github.com/unscriptable/curl" class="demo">View Demo</a><div
class="clear"></div></div><h2>Super Quick AMD&nbsp;Primer</h2><p>If you aren&#8217;t familiar with AMD structure, I&#8217;m going to give you the most oversimplified explanation you&#8217;ll ever hear.  AMD is a system by which you define and require modules asynchronously.  A define returns one or zero objects.  The first argument of both define and require is (usually) an array of dependencies.  The second argument is a function;  the define returns the result, the require executes a basic callback:</p><pre class="js">
// "define" a module
define(["namespace/dependencyA", "namespace/dependencyB"], function(depA, depB) {
	// Whole bunch of processing
	
	
	// Return what this module defines
	return function() {
		// Or an object, or whatever
	}
});

// "require" to use modules:
require(["namespace/dependencyC"], function(depC) {
	
	// depC can be used in here only
	// Yay for modularity!
	
});
</pre><p>The slashes in the dependency array items represent paths to module JavaScript files.  Once dependencies are loaded, the action is allowed to begin.</p><p><em>As I said, this is a very simple, vanilla example;  there are exceptions to every rule, so don&#8217;t bother pointing out what-ifs.</em></p><h2>Configuring Module Loading with&nbsp;curl</h2><p>And of course I start out with a few of the exceptions to the rule.  Instead of a <code>require</code> function, curl.js defines <code>curl</code> in its place.  Additionally, curl.js allows for an object literal as a first parameter, allowing for configuration of loaded modules:</p><pre class="js">
curl({
		baseUrl: "/path/to/js",
		pluginPath: "curl/src/curl/plugin"
	}, 
	["namespace/depC", "namespace/otherDep"],
	function(depC, otherDep) {
		// Do stuff
	}
);
</pre><p>This configuration allows you to provide plugin paths, modules paths, and more.</p><h2>Basic define and require with&nbsp;curl.js</h2><p>Basic usage of curl.js is as you would expect from a JavaScript loader;  dependency array as the first argument, callback with the second:</p><pre class="js">
define(["namespace/depA", "namespace/depB"], function(depA, depB) {
	// Do something with the dependencies
	
	// Pump out a return obj
	return myFinalObject;
});
</pre><p>With a module defined, the same syntax requires and works with the dependencies:</p><pre class="js">
curl(["namespace/depC"], function(depC) {
	// Do some stuff!
});
</pre><p>This is the same syntax you will have used with any JS loader, with the obvious exception of <code>require</code> being replaced by <code>curl</code>.</p><h2>curl.js with&nbsp;next</h2><p>The next method allows for chaining of module loading:</p><pre class="js">
curl(["js!someFile.js"])
	.next(["dep1", "dep2", "dep3"], function (dep1, dep2, dep3) {
		// Execute regardless of domReady status
	})
	.next(["domReady!"])
	.then(
		function () {
		// do something after the dom is ready
		},
		function (ex) {
		// show an error to the user
		}
	);
</pre><p>This syntax may suit your fancy more than others.</p><h2>curl.js with Deferred&nbsp;Syntax</h2><p>If you work with the Dojo Toolkit, or more recently with jQuery, Deferreds are becoming more prevalent and incredibly useful;  curl.js provides you the ability to write your loader JavaScript in the same fashion:</p><pre class="js">
curl(["namespace/depA"]).then(
	function(depA) { // success callback
	
	},
	function(depB) { // errback
	
	}
);
</pre><p>The deferred format and ability to pass the result of an XHR pool can be very powerful.</p><h2>Loading Non-AMD JavaScript&nbsp;Files</h2><p>Sometimes you need to load JavaScript files that aren&#8217;t in AMD format, like loading MooTools or jQuery from CDN.  curl.js makes that easy:</p><pre class="js">
curl(
	["js!https://ajax.googleapis.com/ajax/libs/mootools/1.4.1/mootools-yui-compressed.js"]
).next(["namespace/MooModule"], function() {
	// We loaded Moo first, then once loaded, loaded a dependency that requires MooTools
	// At this point, both are loaded and we can work with them!
	
});
</pre><p>All you need to do add the <code>js!</code> prefix to the dependency string and you&#8217;re set;  your callback will be fire when the basic JavaScript file is loaded.  Note that you can mix AMD modules with basic JavaScript files:</p><pre class="js">
curl(
	[
		"js!https://ajax.googleapis.com/ajax/libs/mootools/1.4.1/mootools-yui-compressed.js",
		"js!http://davidwalsh.name/mootools-ftw.js",
		"namespace/independentModule"
	]
).next(["namespace/MooModule"], function() {
	// We loaded Moo first, then once loaded, loaded a dependency that requires MooTools
	// At this point, both are loaded and we can work with them!
	
});	
</pre><h2>Loading CSS&nbsp;Files</h2><p>Of course one of the strengths of AMD is modularity, so why not load your stylesheets with your scripts?</p><pre class="js">
curl(
	[
		"namespace/MyWidget",
		"css!namespace/resources/MyWidget.css"
	], 
	function(MyWidget) {
		// Do something with MyWidget
		// The CSS reference isn't in the signature because we don't care about it;
		// we just care that it is now in the page
	}
});
</pre><p>LINK tags don&#8217;t provide an onLoad event in all browsers, but curl.js&#8217; shim provides a reliable method of detecting stylesheet load.  Since stylesheets are a large part of UI-driven, JavaScript-powered widgets, creating modules with stylesheet dependencies is becoming much more abundant.</p><h2>More curl&nbsp;Plugins</h2><p>curl is much more than just a basic JS loader.  I&#8217;ve already mentioned the JS and CSS plugins above, but curl has a few more.  curl features a domReady  plugin, as well as a text plugin and an internationalization plugin:</p><pre class="js">
curl(
	[
		"i18n!stuff/nls/strings", // Load string content for the user's namespace
		"text!myWidget/resources/template.html", // Loads a file as text,
		"domReady!" // Don't fire the callback until the DOM is ready
	],
	function(nlsStringObject, template) { // Callback
		// Do something now that we have the NLS object, template, and domContentLoaded has fired
	}
);
</pre><p>These plugins are quick and easy enhancers to existing functionality!</p><div
class="actions"><a
href="https://github.com/unscriptable/curl" class="demo">View Demo</a><div
class="clear"></div></div><p>curl is an absolute beast of a JavaScript loader.  Beyond simple AMD loading, curl is fit with numerous configuration options, plugins, and multiple syntax structures to all the developer to code the way they want.  This blog uses curl.js to asynchronously load JavaScript modules and stylesheets, manage domReady, and more;  the best endorsement I can give!</p><p><a
href="http://davidwalsh.name/curljs">curl.js: Incredible AMD&nbsp;Loader</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/curljs/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Detect Orientation Change on Mobile&#160;Devices</title><link>http://davidwalsh.name/orientation-change</link> <comments>http://davidwalsh.name/orientation-change#comments</comments> <pubDate>Tue, 20 Mar 2012 13:50:39 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Mobile]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5405</guid> <description><![CDATA[Unless your mobile application allows for only portrait or only landscape views, there&#8217;s a good chance you will need to adjust a few things. Even if you&#8217;ve built your layouts in a fluid fashion, you may need to programmatically make some changes. There are a few strategies for knowing when pages have changed, so let&#8217;s [...]<p><a
href="http://davidwalsh.name/orientation-change">Detect Orientation Change on Mobile&nbsp;Devices</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Unless your mobile application allows for only portrait or only landscape views, there&#8217;s a good chance you will need to adjust a few things.  Even if you&#8217;ve built your layouts in a fluid fashion, you may need to programmatically make some changes.  There are a few strategies for knowing when pages have changed, so let&#8217;s check out how we can detect orientation changes on mobile devices.</p><h2>orientationchange&nbsp;Event</h2><p>This method is what you would expect from a mobile API;  a simple orientationchange event on the window:</p><pre class="js">
// Listen for orientation changes
window.addEventListener("orientationchange", function() {
	// Announce the new orientation number
	alert(window.orientation);
}, false);
</pre><p>During these changes, the <code>window.orientation</code> property may change.  A value of 0 means portrait view, -90 means a the device is landscape rotated to the right, and 90 means the device is landscape rotated to the left.</p><h2>resize&nbsp;Event</h2><p>Some devices haven&#8217;t provided the <code>orientationchange</code> event, but do fire the window&#8217;s resize event:</p><pre class="js">
// Listen for resize changes
window.addEventListener("resize", function() {
	// Get screen size (inner/outerWidth, inner/outerHeight)
	
}, false);
</pre><p>A bit less obvious than the <code>orientationchange</code> event, but works very well.</p><h2>Screen&nbsp;Sizing</h2><p>There are a few properties you can retrieve from the window object to get screen size and what I consider &#8220;virtual&#8221; screen size:</p><ul><li><code>outerWidth</code>, <code>outerHeight</code>:  the real pixel realestate (ex:  320&#215;356 on iPhone, portrait)</li><li><code>innerWidth</code>, <code>innerHeight</code>:  the virtual pixel realestate (ex: 980&#215;1091 on iPhone, portrait)</li></ul><p>These don&#8217;t give you the orientation, of course, but using some simple math, you can find out if the window is currently wider or taller.</p><h2>Media&nbsp;Queries</h2><p>We can identify orientation by CSS media queries as well:</p><pre class="css">
/* portrait */
@media screen and (orientation:portrait) {
	/* portrait-specific styles */
}
/* landscape */
@media screen and (orientation:landscape) {
	/* landscape-specific styles */
}
</pre><p>If you&#8217;d like to get clever, you can code a periodical &#8220;watcher&#8221; with JavaScript to check the background color of a block and fire your own orientation change.</p><h2>matchMedia</h2><p>The native <code>window.matchMedia</code> method allows for live media-querying.  We can use the media queries above to find out if we&#8217;re in portrait or landscape view:</p><pre class="js">
// Find matches
var mql = window.matchMedia("(orientation: portrait)");

// If there are matches, we're in portrait
if(mql.matches) {  
	// Portrait orientation
} else {  
	// Landscape orientation
}

// Add a media query change listener
mql.addListener(function(m) {
	if(m.matches) {
		// Changed to portrait
	}
	else {
		// Changed to landscape
	}
});
</pre><p>So there are a few ideas and options for you.  I&#8217;d love to hear any more practical techniques you&#8217;ve used!</p><p><a
href="http://davidwalsh.name/orientation-change">Detect Orientation Change on Mobile&nbsp;Devices</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/orientation-change/feed</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Sort an Array of Objects by Property Using&#160;sort(fn)</title><link>http://davidwalsh.name/array-sort</link> <comments>http://davidwalsh.name/array-sort#comments</comments> <pubDate>Tue, 28 Feb 2012 03:35:46 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5399</guid> <description><![CDATA[Believe it or not, there&#8217;s more to JavaScript than the helper methods and classes they provide your JavaScript library. No, like seriously bro; these JavaScript-given methods do exist. One of those methods, sort, is provided to every Array instance via its prototype. I&#8217;ve used this method once or twice in the history of ever, bro, [...]<p><a
href="http://davidwalsh.name/array-sort">Sort an Array of Objects by Property Using&nbsp;sort(fn)</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Believe it or not, there&#8217;s more to JavaScript than the helper methods and classes they provide your JavaScript library.  No, like seriously bro;  these JavaScript-given methods do exist.  One of those methods, sort, is provided to every Array instance via its prototype.  I&#8217;ve used this method once or twice in the history of ever, bro, since I make every effort to ensure proper sort on the server side, but sometimes you may receive a JSON dump and need to sort on the client side.</p><p>Most people would assume that sort would take no method and simply sort the basic items within the array:</p><pre class="js">
[1, 3, 9, 2].sort();
	// Returns: [1, 2, 3, 9]
	
[1, "a", function(){}, {}, 12, "c"].sort();
	// Returns: [1, 12, Object, "a", "c", function (){}]
</pre><p>But nay, broseph!  If you provide a function expression to the sort method, you can sort objects within the array using simple logic.  Let&#8217;s say you have an array of objects representing persons and you want to sort them by age.  Oh yes, it can be done, and quite easily:</p><pre class="js">
[
	{ name: "Robin Van Persie", age: 28 },
	{ name: "Theo Walcott", age: 22 },
	{ name: "Bacary Sagna", age: 26  }
].sort(function(obj1, obj2) {
	// Ascending: first age less than the previous
	return obj1.age - obj2.age;
});
	// Returns:  
	// [
	//	  { name: "Theo Walcott", age: 22 },
	//	  { name: "Bacary Sagna", age: 26  },
	//	  { name: "Robin Van Persie", age: 28 }
	// ]
	
</pre><p>The anonymous function returns whether or not the first object&#8217;s age is less than the second&#8217;s, thus sorting the entire array in ascending order by age.  Reverse the first and second arguments to sort in descending order.</p><p>So brochacho, now you know how to sort an array of objects using JavaScript.  Get to it!</p><p><a
href="http://davidwalsh.name/array-sort">Sort an Array of Objects by Property Using&nbsp;sort(fn)</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/array-sort/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>HTML5 Element Printing in Internet&#160;Explorer</title><link>http://davidwalsh.name/html5-print</link> <comments>http://davidwalsh.name/html5-print#comments</comments> <pubDate>Tue, 28 Feb 2012 02:50:37 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5397</guid> <description><![CDATA[I was recently working on a website created with HTML5 elements like header, footer, section, and more, and got a rude awakening by Internet Explorer 8. I knew about the hack to ensure the elements render and style as they should on screen&#8230; // For discussion and comments, see: http://remysharp.com/2009/01/07/html5-enabling-script/ (function(){if(!/*@cc_on!@*/0)return;var e = "abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(',');for(var i=0;i&#60;e.length;i++){document.createElement(e[i])}})(); [...]<p><a
href="http://davidwalsh.name/html5-print">HTML5 Element Printing in Internet&nbsp;Explorer</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I was recently working on a website created with HTML5 elements like header, footer, section, and more, and got a rude awakening by Internet Explorer 8.  I knew about the hack to ensure the elements render and style as they should on screen&#8230;</p><pre class="js">
// For discussion and comments, see: http://remysharp.com/2009/01/07/html5-enabling-script/
(function(){if(!/*@cc_on!@*/0)return;var e = "abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(',');for(var i=0;i&lt;e.length;i++){document.createElement(e[i])}})();
</pre><p>..but ensuring styling during print was a whole different story.  Despite the JavaScript shim above, the elements still wouldn&#8217;t style correctly when I went to print.  After trying a variety of solutions, my last attempt was the most successful; <a
href="https://github.com/aFarkas/html5shiv/blob/master/src/html5shiv-printshiv.js" rel="nofollow">Modernizr&#8217;s &#8220;print-shiv&#8221; extra</a>!  This shim wraps your HTML5 elements with printer-friendly elements during the onbeforeprint event, then cleans up after itself when the onafterprint event is fired.  There are no special configurations to set, simply include the JavaScript file within the page.   Just wanted to pass this quick tip on; head over to <a
href="https://github.com/aFarkas/html5shiv/blob/master/src/html5shiv-printshiv.js" rel="nofollow">GitHub and download it</a>!</p><p><a
href="http://davidwalsh.name/html5-print">HTML5 Element Printing in Internet&nbsp;Explorer</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/html5-print/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (User agent is rejected)
Database Caching 1/66 queries in 0.096 seconds using disk: basic
Object Caching 1431/1540 objects using disk: basic

Served from: davidwalsh.name @ 2012-05-23 22:47:39 -->
