<?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>Sat, 04 Feb 2012 19:28:58 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3</generator> <item><title>Amazing 3D Animation with&#160;three.js</title><link>http://davidwalsh.name/threejs</link> <comments>http://davidwalsh.name/threejs#comments</comments> <pubDate>Mon, 23 Jan 2012 15:49:14 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5373</guid> <description><![CDATA[The hottest topic for client-side developers seems to be animation. Whether it be from CSS transformations, keyframe animations, or animations managed with JavaScript APIs, it seems like each day we come across another demo that shows us how can we&#8217;ve come outside of Flash. The latest shocker comes from the three.js project. The creators of [...]<p><a
href="http://davidwalsh.name/threejs">Amazing 3D Animation with&nbsp;three.js</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>The hottest topic for client-side developers seems to be animation. Whether it be from CSS transformations, keyframe animations, or animations managed with JavaScript APIs, it seems like each day we come across another demo that shows us how can we&#8217;ve come outside of Flash. The latest shocker comes from the three.js project. The creators of three.js explains the project best:</p><blockquote>The aim of the project is to create a lightweight 3D engine with a very low level of complexity; in other words, for dummies. The engine can render using &lt;canvas&gt;, &lt;svg&gt; and WebGL.</blockquote><p>The three.js engine allows developers to create mindblowing 2D and 3D animations with Canvas and WebGL, from <em
title="Since when were creating cubes basic?  Since three.js!">basic</em> cubes to advanced animations so smooth you&#8217;ll wet yourself.</p><h2>Favorite three.js&nbsp;Demos</h2><p>The three.js repository comes with several dozens examples of the engine&#8217;s capabilities. Here are a few of my favorites:</p><ul><li><a
href="http://mrdoob.github.com/three.js/examples/webgl_trails.html" rel="nofollow">http://mrdoob.github.com/three.js/examples/webgl_trails.html</a></li><li><a
href="http://mrdoob.github.com/three.js/examples/webgl_terrain_dynamic.html" rel="nofollow">http://mrdoob.github.com/three.js/examples/webgl_terrain_dynamic.html</a></li><li><a
href="http://mrdoob.github.com/three.js/examples/webgl_shading_physical.html" rel="nofollow">http://mrdoob.github.com/three.js/examples/webgl_shading_physical.html</a></li><li><a
href="http://mrdoob.github.com/three.js/examples/webgl_materials_cubemap_refraction.html" rel="nofollow">http://mrdoob.github.com/three.js/examples/webgl_materials_cubemap_refraction.html</a></li><li><a
href="http://mrdoob.github.com/three.js/examples/webgl_animation_skinning.html" rel="nofollow">http://mrdoob.github.com/three.js/examples/webgl_animation_skinning.html</a></li><li><a
href="http://mrdoob.github.com/three.js/examples/webgl_geometries.html" rel="nofollow">http://mrdoob.github.com/three.js/examples/webgl_geometries.html</a></li></ul><p>You can see all of the examples here: <a
href="http://mrdoob.github.com/three.js/">http://mrdoob.github.com/three.js/</a></p><p>Mind status: blown. three.js is an incredible project that allows developers to achieve amazing animations efficiently and without Flash. Mr.Doob: take a bow &#8212; three.js is ahead of its time.</p><p><a
href="http://davidwalsh.name/threejs">Amazing 3D Animation with&nbsp;three.js</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/threejs/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>JavaScript Enlightenment by Cody&#160;Lindley</title><link>http://davidwalsh.name/javascript-enlightenment</link> <comments>http://davidwalsh.name/javascript-enlightenment#comments</comments> <pubDate>Mon, 09 Jan 2012 16:02:35 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Books]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5366</guid> <description><![CDATA[JavaScript Guru Douglas Crockford famously said &#8220;JavaScript is the only language people feel like they don&#8217;t need to learn to use.&#8221; A quote that will surely provide a laugh, but it&#8217;s funny because it&#8217;s true. What furthers this sentiment is that JavaScript frameworks like jQuery have turned JavaScript into a language different than what it [...]<p><a
href="http://davidwalsh.name/javascript-enlightenment">JavaScript Enlightenment by Cody&nbsp;Lindley</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>JavaScript Guru Douglas Crockford famously said &#8220;JavaScript is the only language people feel like they don&#8217;t need to learn to use.&#8221; A quote that will surely provide a laugh, but it&#8217;s funny because it&#8217;s true. What furthers this sentiment is that JavaScript frameworks like jQuery have turned JavaScript into a language different than what it truly is, and has made client-side coding so easy that there&#8217;s sometimes no need to really <em>learn</em> JavaScript. Anyone worth their salt, however, knows that in order to expertly and efficiently use any tool, you have to start with the basics.<p><p>That&#8217;s where <a
href="http://jqueryenlightenment.com/" rel="nofollow"><em>JavaScript Enlightenment</em></a> comes in. <em>JavaScript Enlightenment</em> is an outstanding book by Cody Lindley, one of several members of the jQuery team. I&#8217;ll let book&#8217;s description speak for itself:</p><blockquote><p>This book is not about JavaScript design patterns or implementing an object-oriented paradigm with JavaScript code. It was not written to distinguish the good features of the JavaScript language from the bad. It is not meant to be a complete reference guide. It is not targeted at people new to programming or those completely new to JavaScript. Nor is this a cookbook of JavaScript recipes. Those books have been written. It was my intention to write a book to give the reader an accurate JavaScript worldview through an examination of native JavaScript objects and supporting nuances: complex values, primitive values, scope, inheritance, the head object, etc. I intend this book to be a short and digestible summary of the ECMA-262, Edition 3 specification, focused on the nature of objects in JavaScript.</p></blockquote><p>In short, <em>JavaScript Enlightment</em> takes JavaScript back to its basics. The chapter summary is really drives that point home:</p><ol><li>Constructing Objects</li><li>Working with Objects and Properties</li><li>Object()</li><li>Function()</li><li>The Head/Global Object</li><li>The this Keyword</li><li>Scope and Closures</li><li>Prototype Property</li><li>Array()</li><li>String()</li><li>Number()</li><li>Boolean()</li><li>Null</li><li>Undefined</li><li>Math Function</li></ol><p>There are a couple of things I really enjoyed about Cody&#8217;s writing style:</p><ul><li>Many authors write in a way to reinforce that they&#8217;re the smartest guy in the room. What people like them don&#8217;t understand is that eager-to-learn developers have already bought the book: they trust that you&#8217;re the expert, so you don&#8217;t have to use advanced verbiage to look intelligent. Cody skips that ego-centric exercise, explain JavaScript concepts in Leyman&#8217;s terms.</li><li>Each section covers one JavaScript object/concept, so the book is very focused. Too often development books bleed into and out of topics without true explanation.</li><li>Lindley&#8217;s book is packed full of code examples; if you&#8217;re anything like me, code examples tell you as much if not more than plan text. Every person has their own style of leaning, but there&#8217;s nothing like a solid code example you can play around with.</li></ul><p>The books itself, when it comes to topics covered, is great for beginners and intermediates a like; there&#8217;s a lot of learning and reinforcing of core JavaScript concepts. Each code snippet provides a link to a working version of the code, which comes in handy if you want to quickly tinker with such code. Lastly, there&#8217;s plenty of personality in Lindley&#8217;s book; it&#8217;s not simply a reference to flick through &#8212; designers and developers will enjoy reading <em>JavaScript Enlightenment</em>.</p><p>Cody Lindley&#8217;s <em>JavaScript Enlightenment</em> is an essential resource for any designer or developer looking to to understand JavaScript at its core, regardless of skill level or JavaScript framework. Lindley&#8217;s ability to explain key JavaScript concepts with realistic, useful code examples is what really makes <em>JavaScript Enlightenment</em> shine. Don&#8217;t be a slave to your JavaScript framework, because copy&#8217;n'paste is no way to go through a development life! Get enlightened by <em>JavaScript Enlightenment</em>!</p><p><a
href="http://davidwalsh.name/javascript-enlightenment">JavaScript Enlightenment by Cody&nbsp;Lindley</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-enlightenment/feed</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>JavaScript Battery&#160;API</title><link>http://davidwalsh.name/battery-api</link> <comments>http://davidwalsh.name/battery-api#comments</comments> <pubDate>Tue, 03 Jan 2012 15:12:56 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5362</guid> <description><![CDATA[Mozilla Aurora 11 was recently released with a bevy of new features. One of those great new features is their initial implementation of the Battery Status API. This simple API provides you information about the battery&#8217;s current charge level, its charging status, and allows you to be notified of changes via a few events. Let&#8217;s [...]<p><a
href="http://davidwalsh.name/battery-api">JavaScript Battery&nbsp;API</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>Mozilla Aurora 11 was recently released with <a
href="http://hacks.mozilla.org/2011/12/introducing-aurora-11-with-tons-of-new-features-and-improvements/" rel="nofollow">a bevy of new features</a>.  One of those great new features is their initial implementation of the <a
href="http://www.w3.org/TR/battery-status/" rel="nofollow">Battery Status API</a>.  This simple API provides you information about the battery&#8217;s current charge level, its charging status, and allows you to be notified of changes via a few events.  Let&#8217;s check it out!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/battery-api.php" class="demo">View Demo</a><div
class="clear"></div></div><p>The battery object is located at <code>window.navigator.battery</code>, but since this is Mozilla&#8217;s initial offering and the API is not yet cemented, you&#8217;ll need to use <code>window.navigator.mozBattery</code>.  The helpful <code>mozBattery</code> properties include:</p><ul><li><code>charging: </code>Represents if the system&#8217;s battery is charging. The attribute must be set to false if the battery is discharging, and set to true, if the battery is charging, full, the implementation is unable to report the state, or there is no battery attached to the system, or otherwise.</li><li><code>chargingTime: </code>Represents the time remaining in seconds until the system&#8217;s battery is fully charged.</li><li><code>dischargingTime: </code>Represents the time remaining in seconds until the system&#8217;s battery is completely discharged and the system is about to be suspended.</li><li><code>level: </code>Represents the current battery level scaled from 0 to 1.0. The attribute must be set to 0 if the system&#8217;s battery is depleted and the system is about to be suspended, and to 1.0 if the battery is full, the implementation is unable to report the battery&#8217;s level, or there is no battery attached to the system.</li></ul><p>Events for each of these statuses are provided, including <code>onchargingchange</code>, <code>onchargingtimechange</code>, <code>ondischargingtimechange</code>, and <code>onlevelchange</code>.  Basic usage is simple:</p><pre class="js">
// Get the battery!
var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;

// A few useful battery properties
console.warn("Battery charging: ", battery.charging); // true
console.warn("Battery level: ", battery.level); // 0.58
console.warn("Battery discharging time: ", battery.dischargingTime);

// Add a few event listeners
battery.addEventListener("chargingchange", function(e) {
	console.warn("Battery charge change: ", battery.charging);
}, false);
battery.addEventListener("chargingtimechange", function(e) {
	console.warn("Battery charge time change: ", battery.chargingTime);
}, false);
battery.addEventListener("dischargingtimechange", function(e) {
	console.warn("Battery discharging time change: ", battery.dischargingTime);
}, false);
battery.addEventListener("levelchange", function(e) {
	console.warn("Battery level change: ", battery.level);
}, false);
</pre><p>I promised a simple API, didn&#8217;t I?  The battery API is the perfect API:  simple, effective, and focused!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/battery-api.php" class="demo">View Demo</a><div
class="clear"></div></div><p>So why use the battery API?  Since many mobile apps live inside a browser wrapper (aren&#8217;t completely &#8220;native&#8221;), it&#8217;s great to have access to system information.  Some processes are power-intensive and it may bear warning the user before starting the process that their device is low on battery.  Either way, this simple API&#8217;s true usefulness should become apparent soon!</p><p><a
href="http://davidwalsh.name/battery-api">JavaScript Battery&nbsp;API</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/battery-api/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>DOM Events in&#160;JavaScript</title><link>http://davidwalsh.name/dom-events-javascript</link> <comments>http://davidwalsh.name/dom-events-javascript#comments</comments> <pubDate>Thu, 15 Dec 2011 15:26:20 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5343</guid> <description><![CDATA[Mozilla Firefox 7 introduced CSS&#8217; useful text-overflow: ellipsis, an outstanding method of dynamically and elegantly concatenating strings within their parent elements. Firefox was late to the text-overflow party, so the Dojo Toolkit offered dojox.ellipsis, a resource that would shim ellipsis functionality with an iFrame. When perusing the dojox.ellipsis code, I found that the creators used [...]<p><a
href="http://davidwalsh.name/dom-events-javascript">DOM Events in&nbsp;JavaScript</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>Mozilla Firefox 7 introduced <a
href="http://davidwalsh.name/css-ellipsis">CSS&#8217; useful <code>text-overflow: ellipsis</code></a>, an outstanding method of dynamically and elegantly concatenating strings within their parent elements. Firefox was late to the <code>text-overflow</code> party, so the Dojo Toolkit offered <code>dojox.ellipsis</code>, a resource that would shim ellipsis functionality with an iFrame. When perusing the <code>dojox.ellipsis</code> code, I found that the creators used the <code>DOMSubtreeModified</code> event to recheck all nodes when the page structure changes. After a bit of research, I found a whole host of DOM events you can use to spy on the document.<p><h2>The DOM Tree&nbsp;Events</h2><p>Here are the DOM tree events you can listen for:</p><table
class="poll-results" style="width: auto;"><thead><tr><th
class="header">Event name</th><th
class="header">Spec</th><th
class="header">Description</th></tr></thead><tbody><tr><td><code>DOMActivate</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMActivate" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMActivate">W3C Draft</a></td><td>A user agent must dispatch this event when a button, link, or other state-changing element is activated. Refer to Activation triggers and behavior for more details. <em>(Deprecated in favor of <code>click</code>)</em></td></tr><tr><td><code>DOMAttrModified</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMAttrModified" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMAttrModified">W3C Draft</a></td><td>A user agent must dispatch this event after an Attr.value has been modified and after an Attr node has been added to or removed from an Element.</td></tr><tr><td><code>DOMAttributeNameChanged</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMAttributeNameChanged" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMAttributeNameChanged">W3C Draft</a></td><td>A user agent must dispatch this event after the namespaceURI and/or the nodeName of a Attr node have been modified (e.g., the attribute was renamed using Document.renameNode()).</td></tr><tr><td><code>DOMCharacterDataModified</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMCharacterDataModified" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMCharacterDataModified">W3C Draft</a></td><td>A user agent must dispatch this event after CharacterData.data or ProcessingInstruction.data have been modified, but the node itself has not been inserted or deleted.</td></tr><tr><td><code>DOMContentLoaded</code></td><td><a
title="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end">HTML5</a></td><td></td></tr><tr><td><code>DOMElementNameChanged</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMElementNameChanged" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMElementNameChanged">W3C Draft</a></td><td>A user agent must dispatch this event after the namespaceURI and/or the nodeName of an Element node have been modified (e.g., the element was renamed using Document.renameNode()).</td></tr><tr><td><code>DOMFocusIn</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMFocusIn" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMFocusIn">W3C Draft</a></td><td>A user agent must dispatch this event when an event target receives focus. The focus must be given to the element before the dispatch of this event type. This event type must be dispatched after the event type focus.</td></tr><tr><td><code>DOMFocusOut</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMFocusOut" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMFocusOut">W3C Draft</a></td><td>A user agent must dispatch this event when an event target loses focus. The focus must be taken from the element before the dispatch of this event type. This event type must be dispatched after the event type blur.</td></tr><tr><td><code>DOMNodeInserted</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInserted" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInserted">W3C Draft</a></td><td>A user agent must dispatch this event type when a node other than an Attr node has been added as a child of another node. A user agent may dispatch this event when an Attr node has been added to an Element node (see note below). This event must be dispatched after the insertion has taken place.</td></tr><tr><td><code>DOMNodeInsertedIntoDocument</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInsertedIntoDocument" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInsertedIntoDocument">W3C Draft</a></td><td>A user agent must dispatch this event when a node has been inserted into a document, either through direct insertion of the node or insertion of a subtree in which it is contained; a user agent may optionally treat an Attr node as part of an Element&#8217;s subtree. This event must be dispatched after the insertion has taken place.</td></tr><tr><td><code>DOMNodeRemoved</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemoved" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemoved">W3C Draft</a></td><td>A user agent must dispatch this event when a node other than an Attr node is being removed from its parent node. A user agent may dispatch this event when an Attr node is being removed from its ownerElement (see note below). This event must be dispatched before the removal takes place.</td></tr><tr><td><code>DOMNodeRemovedFromDocument</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemovedFromDocument" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemovedFromDocument">W3C Draft</a></td><td>A user agent must dispatch this event when a node is being removed from a document, either through direct removal of the node or removal of a subtree in which it is contained; a user agent may optionally treat an Attr node as part of an Element&#8217;s subtree. This event must be dispatched before the removal takes place.</td></tr><tr><td><code>DOMSubtreeModified</code></td><td><a
title="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified" href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified">W3C Draft</a></td><td>This is a general event for notification of all changes to the document. It can be used instead of the more specific mutation and mutation name events. It may be dispatched after a single modification to the document or, at the implementation&#8217;s discretion, after multiple changes have occurred. The latter case should generally be used to accommodate multiple changes which occur either simultaneously or in rapid succession. The target of this event must be the lowest common parent of the changes which have taken place. This event must be dispatched after any other events caused by the mutation(s) have occurred.</td></tr></tbody></table><p><em>Table provided by <a
href="https://developer.mozilla.org/en/DOM/DOM_event_reference">MDN documentation</a>.</em></p><p>The DOM event you&#8217;ll probably recognize is DOMContentLoaded, which is used to signal the domready we&#8217;re all used to seeing within our JavaScript toolkits. The event names are all fairly self-explanatory. Adding these events is as easy as adding any other type of event:</p><pre class="js">// Notify us when any node within the document is modified, added removed, etc.
document.addEventListener("DOMSubtreeModified", function(e) {
	// Notify of change!
	console.warn("change!", e);
}, false);

// Now create a new element to see what it will look like
var a = document.createElement("a");
document.body.appendChild(a);

/*
	Result:

	{
		ADDITION: 2,
		MODIFICATION: 1,
		REMOVAL: 3,
		attrChange: 0,
		attrName: "", 
		defaultPrevented: false,
		newValue: "",
		prevValue: "",
		relatedNode: null,
		initMutationEvent: initMutationEvent(),
		bubbles: true,
		cancelable: false,
		constructor: MutationEvent { MODIFICATION=1, ADDITION=2, REMOVAL=3},
		currentTarget: Document en,
		eventPhase: 3,
		explicitOriginalTarget: body.home,
		isTrusted: true,
		originalTarget: body.home,
		target: body.home,
		timeStamp: 0,
		type: "DOMSubtreeModified"
	}

*/</pre><p>What if you want to listen to simple node changes?</p><pre class="js">
// Listen to when an image src or alt gets changed (ex: slideshow, etc.)
document.getElementById("slideshowImage").addEventListener("DOMAttrModified", function(e) {
	// Record the occurrence
	console.warn(e.attrName + " changed from ", e.prevValue," to: ", e.newValue);
}, false);
</pre><p>The <code>attrName</code>, <code>prevValue</code>, and <code>newValue</code> values tell you which attribute changed and its previoius and current values.  Each event type has its own custom event properties so experiment with events when creating them.  You can also learn the event properties by checking out the <a
href="http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMAttrModified">spec list</a>.</p><p>These DOM events are really nice to plug into if you&#8217;re looking for complete control over Document. The one caution to throw to you is that since these events can fire so often, attaching to them can be heavy on your app. The ability to attach to them when needed is incredibly useful in a sophisticated web application.</p><p><a
href="http://davidwalsh.name/dom-events-javascript">DOM Events in&nbsp;JavaScript</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/dom-events-javascript/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Page Visibility&#160;API</title><link>http://davidwalsh.name/page-visibility</link> <comments>http://davidwalsh.name/page-visibility#comments</comments> <pubDate>Mon, 21 Nov 2011 15:26:36 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[MooTools]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5335</guid> <description><![CDATA[One event that&#8217;s always been lacking within the document is a signal for when the user is looking at a given tab, or another tab. When does the user switch off our site to look at something else? When do they come back? The Page Visibility API allows developers to react to changes in page [...]<p><a
href="http://davidwalsh.name/page-visibility">Page Visibility&nbsp;API</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 event that&#8217;s always been lacking within the document is a signal for when the user is looking at a given tab, or another tab.  When does the user switch off our site to look at something else?  When do they come back?  The Page Visibility API allows developers to react to changes in page visibility via the <code>visibilitychange document</code> event.  New <code>document.hidden</code> and <code>document.visibilityChange</code> properties are also available.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/page-visibility.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>document.hidden</h2><p>This new document property, <code>document.hidden</code>, returns true the page is currently not visible.</p><h2>document.visibilityState</h2><p>The <code>visibilityState</code> will either be <code>visibile</code> (the page is the foreground tab of a non-minimized window), <code>hidden</code> (document is either a background tab or part of a minimized window), or <code>prerender</code> (the page content is being prerendered and is not visible to the user).</p><h2>visibilitychange&nbsp;Event</h2><p>Listening for changes in window visibility is as easy as:</p><pre class="js">
// Adapted slightly from Sam Dutton
// Set name of hidden property and visibility change event
// since some browsers only offer vendor-prefixed support
var hidden, state, visibilityChange; 
if (typeof document.hidden !== "undefined") {
	hidden = "hidden";
	visibilityChange = "visibilitychange";
	state = "visibilityState";
} else if (typeof document.mozHidden !== "undefined") {
	hidden = "mozHidden";
	visibilityChange = "mozvisibilitychange";
	state = "mozVisibilityState";
} else if (typeof document.msHidden !== "undefined") {
	hidden = "msHidden";
	visibilityChange = "msvisibilitychange";
	state = "msVisibilityState";
} else if (typeof document.webkitHidden !== "undefined") {
	hidden = "webkitHidden";
	visibilityChange = "webkitvisibilitychange";
	state = "webkitVisibilityState";
}

// Add a listener that constantly changes the title
document.addEventListener(visibilityChange, function() {
	document.title = document[state];
}, false);

// Set the initial value
document.title = document[state];
</pre><p>The example above changes the <code>document.title</code> property during every visibility change!</p><h2>Supporting visibilityChange in&nbsp;MooTools</h2><p>MooTools doesn&#8217;t support visibilityChange out of the box, so you&#8217;ll need to add this bit of JavaScript:</p><pre class="js">
// Set it up!
Element.NativeEvents[visibilityChange] = 2;
Element.Events[visibilityChange] = {
	base: visibilityChange,
	condition: function(event) {
		event[state] = document[state];
		event.visibilityState = document[state];
		return true;
	}
};

// Now use it!
document.addEvent(visibilityChange, function(e) {
	document.title = document[state];
});
</pre><p>Don&#8217;t you love it when it&#8217;s that easy?!  This mirror the code needed to add <code>onMessage</code> events to the list of supported events.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/page-visibility.php" class="demo">View Demo</a><div
class="clear"></div></div><p>So what could <code>visibilitychange</code> be used for?  You could stop periodically refreshing content when the page is no longer visible, then pull new content when the page becomes visible again.  You could <a
href="http://www.samdutton.com/pageVisibility/" rel="nofollow">pause and resume a video during visibility changes</a>.  Audio too.  You could adjust your site statistics to count only time spent on site while the page is visible.  There&#8217;s loads you can do!  So&#8230;the question is&#8230;what would you do with this?</p><p><a
href="http://davidwalsh.name/page-visibility">Page Visibility&nbsp;API</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/page-visibility/feed</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>iPhone Scrollbars with&#160;iScroll</title><link>http://davidwalsh.name/iphone-scrollbars</link> <comments>http://davidwalsh.name/iphone-scrollbars#comments</comments> <pubDate>Mon, 31 Oct 2011 14:45:04 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Mobile]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5324</guid> <description><![CDATA[Since we&#8217;ve had web browsers and JavaScript, we&#8217;ve been intent on replacing native browser functionalities, and for many reasons. Whether it be that the native look or functionality is ugly, doesn&#8217;t work the same across browsers, or isn&#8217;t as feature-rich as it should be, we&#8217;ve always pushed the browser&#8217;s limits to do better. One functionality [...]<p><a
href="http://davidwalsh.name/iphone-scrollbars">iPhone Scrollbars with&nbsp;iScroll</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>Since we&#8217;ve had web browsers and JavaScript, we&#8217;ve been intent on replacing native browser functionalities, and for many reasons.  Whether it be that the native look or functionality is ugly, doesn&#8217;t work the same across browsers, or isn&#8217;t as feature-rich as it should be, we&#8217;ve always pushed the browser&#8217;s limits to do better.  One functionality we&#8217;ve tried desperately to emulate is scrollbars. <a
href="http://cubiq.org/iscroll-4" rel="nofollow">iScroll</a>, a fairly new scrolling lib, has done an exceptional job in emulating scrolling both within desktop and mobile browsers.  iScroll also allows for scrolling of elements with overflow on older versions of Mobile Safari.  Let&#8217;s have a look at iScroll!</p><div
class="actions"> <a
href="http://davidwalsh.name/dw-content/iscroll.html" class="demo">Desktop Demo</a> <a
href="http://davidwalsh.name/dw-content/iscroll/examples/pull-to-refresh/" class="demo">Mobile Demo</a></div><h2>The&nbsp;HTML</h2><p>iScroll requires a two-DIV pattern for declaring where iScroll will be used.  The first DIV is the wrapper, the second DIV is the scrollable area:</p><pre class="html">
&lt;div id="wrapper"&gt;
	&lt;div id="scroller"&gt;
		&lt;div style="padding:15px 30px;"&gt; &lt;!-- padding for content --&gt;
		
			&lt;!-- content goes here --&gt;
			
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre><p>iScroll will create and inject the scrollbar within the <code>wrapper</code> DIV.  The content is held within the <code>scroller</code> DIV.</p><h2>The&nbsp;CSS</h2><p>The CSS is where iScroll can get a bit fuzzy.  For iScroll to work optimally, both the wrapper and scroller DIVs need to be positioned absolutely and be styled to widths of 100%:</p><pre class="css">
#wrapper {
	position:absolute;
	z-index:1;
	top:0; 
	bottom:0; 
	left:0;
	width:100%;
	overflow:auto;
}

#scroller {
	position:absolute; z-index:1;
/*	-webkit-touch-callout:none;*/
	-webkit-tap-highlight-color:rgba(0,0,0,0);
	width:100%;
	padding:0;
}
</pre><p>As a result, the third DIV of the structure needs the contain enough padding-right to keep the text and scrollbar far enough way from each other.  Be sure to position those elements properly or iScroll wont work at all <em>(as I found out the hard way)</em>!</p><h2>The&nbsp;JavaScript</h2><p>The most obvious piece of using iScroll is including its .js file:</p><pre class="html">
&lt;script type="text/javascript" src="iscroll/src/iscroll.js"&gt;&lt;/script&gt;
</pre><p>With iScroll now available within the page, the next step is creating the iScroll instance that suits the needs of your desired usage.  The most simple of uses provides only the wrapper ID:</p><pre class="js">
var scroller = new iScroll('wrapper');
</pre><p>Awesome; the page&#8217;s native scrollbar disappears and is replaced by an iOS-style scrollbar!  But like every good JavaScript lib, iScroll provides a host of features that allow you to customize your scrollbar.  Options include setting flags for bounce, momentum, fade and hide settings, and whether scrollbars should be allowed both vertically and horizontally.  Here&#8217;s another example of how you can create a pull-to-refresh scrollbar:</p><pre class="js">
var myScroll,
	pullDownEl, pullDownOffset,
	pullUpEl, pullUpOffset,
	generatedCount = 0;

function pullDownAction () {
	setTimeout(function () {	// &lt;-- Simulate network congestion, remove setTimeout from production!
		var el, li, i;
		el = document.getElementById('thelist');

		for (i=0; i&lt;3; i++) {
			li = document.createElement('li');
			li.innerText = 'Generated row ' + (++generatedCount);
			el.insertBefore(li, el.childNodes[0]);
		}
		
		myScroll.refresh();		// Remember to refresh when contents are loaded (ie: on ajax completion)
	}, 1000);	// &lt;-- Simulate network congestion, remove setTimeout from production!
}

function pullUpAction () {
	setTimeout(function () {	// &lt;-- Simulate network congestion, remove setTimeout from production!
		var el, li, i;
		el = document.getElementById('thelist');

		for (i=0; i&lt;3; i++) {
			li = document.createElement('li');
			li.innerText = 'Generated row ' + (++generatedCount);
			el.appendChild(li, el.childNodes[0]);
		}
		
		myScroll.refresh();		// Remember to refresh when contents are loaded (ie: on ajax completion)
	}, 1000);	// &lt;-- Simulate network congestion, remove setTimeout from production!
}

function loaded() {
	pullDownEl = document.getElementById('pullDown');
	pullDownOffset = pullDownEl.offsetHeight;
	pullUpEl = document.getElementById('pullUp');	
	pullUpOffset = pullUpEl.offsetHeight;
	
	myScroll = new iScroll('wrapper', {
		useTransition: true,
		topOffset: pullDownOffset,
		onRefresh: function () {
			if (pullDownEl.className.match('loading')) {
				pullDownEl.className = '';
				pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
			} else if (pullUpEl.className.match('loading')) {
				pullUpEl.className = '';
				pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
			}
		},
		onScrollMove: function () {
			if (this.y &gt; 5 &amp;&amp; !pullDownEl.className.match('flip')) {
				pullDownEl.className = 'flip';
				pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...';
				this.minScrollY = 0;
			} else if (this.y &lt; 5 &amp;&amp; pullDownEl.className.match('flip')) {
				pullDownEl.className = '';
				pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
				this.minScrollY = -pullDownOffset;
			} else if (this.y &lt; (this.maxScrollY - 5) &amp;&amp; !pullUpEl.className.match('flip')) {
				pullUpEl.className = 'flip';
				pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Release to refresh...';
				this.maxScrollY = this.maxScrollY;
			} else if (this.y &gt; (this.maxScrollY + 5) &amp;&amp; pullUpEl.className.match('flip')) {
				pullUpEl.className = '';
				pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
				this.maxScrollY = pullUpOffset;
			}
		},
		onScrollEnd: function () {
			if (pullDownEl.className.match('flip')) {
				pullDownEl.className = 'loading';
				pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';				
				pullDownAction();	// Execute custom function (ajax call?)
			} else if (pullUpEl.className.match('flip')) {
				pullUpEl.className = 'loading';
				pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Loading...';				
				pullUpAction();	// Execute custom function (ajax call?)
			}
		}
	});
	
	setTimeout(function () { document.getElementById('wrapper').style.left = '0'; }, 800);
}
</pre><p>Since we live in the world of AJAX-driven websites that allow content to come and go, calling the refresh method is all you need to do for iScroll to reevaluate the scrollbar position and size:</p><pre class="js">
// When the AJAX is done, refresh the scrollbar sizing and positioning...
scroller.refresh();
</pre><p>It&#8217;s also important to point out that iScroll allows zooming and pinching, as well as snapping to elements:</p><pre class="js">
var myScroll = new iScroll('wrapper', {
	/* snap: true, */ 		// Would snap logically
	snap: "p",				// Snaps to each "P" tag
	momentum: false,
	hScrollbar: false,
	vScrollbar: false 
});
</pre><p>Lastly, iScroll-Lite is available for those looking to support only mobile browsers (iScroll allows for desktop support as well).  The mischievous part of me would prefer iOS-style scrollbars  instead of native browser scrollbars!</p><div
class="actions"> <a
href="http://davidwalsh.name/dw-content/iscroll.html" class="demo">Desktop Demo</a> <a
href="http://davidwalsh.name/dw-content/iscroll/examples/pull-to-refresh/" class="demo">Mobile Demo</a></div><p>Possibly my favorite part of iScroll is that it&#8217;s a standalone library;  no external JavaScript library is required.  iScroll has many configuration parameters so I encourage you to <a
href="http://cubiq.org/iscroll-4" rel="nofollow">visit the iScroll page</a> to check out everything you can do. Matteo Spinelli&#8217;s iScroll is an outstanding piece of work;  grab iScroll and start controlling your scrollbars today!</p><p><a
href="http://davidwalsh.name/iphone-scrollbars">iPhone Scrollbars with&nbsp;iScroll</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/iphone-scrollbars/feed</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>Detect Scrollbar Width with&#160;JavaScript</title><link>http://davidwalsh.name/detect-scrollbar-width</link> <comments>http://davidwalsh.name/detect-scrollbar-width#comments</comments> <pubDate>Tue, 25 Oct 2011 13:58:54 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5323</guid> <description><![CDATA[I&#8217;ve recently been working on an advanced JavaScript-based grid solution and let me tell you: it&#8217;s quite an undertaking. Making sure the grid is accessible, reactive, efficient, and cross-browser compatible is difficult, but even the minor workings of each of those are hard. One small task was detecting the width of the vertical scrollbar so [...]<p><a
href="http://davidwalsh.name/detect-scrollbar-width">Detect Scrollbar Width with&nbsp;JavaScript</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 recently been working on an advanced JavaScript-based grid solution and let me tell you:  it&#8217;s quite an undertaking.  Making sure the grid is accessible, reactive, efficient, and cross-browser compatible is difficult, but even the minor workings of each of those are hard.  One small task was detecting the width of the vertical scrollbar so that I know how wide the grid body truly was.  Here&#8217;s the tiny snippet to do it:</p><h2>The&nbsp;CSS</h2><p>The element we create for measurement will need to be positioned off screen so the user doesn&#8217;t notice it:</p><pre class="css">
/* way the hell off screen */
.scrollbar-measure {
	width: 100px;
	height: 100px;
	overflow: scroll;
	position: absolute;
	top: -9999px;
}
</pre><p>You could add these styles directly to the element, but they&#8217;d bloat the JavaScript portion a bit.</p><h2>The&nbsp;JavaScript</h2><p>The obvious parts is creating a <code>DIV</code> to inject into the DOM and adding the CSS class we created above:</p><pre class="js">
// Create the measurement node
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);

// Get the scrollbar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
console.warn(scrollbarWidth); // Mac:  15

// Delete the DIV 
document.body.removeChild(scrollDiv);
</pre><p>With the element in the page, subtracting the <code>clientWidth</code> from the <code>offsetWidth</code> gives the scrollbar size!  The last step is removing the <code>DIV</code> from the DOM and done!</p><p>Since the scrollbar size is different between Mac and Windows (and even Internet Explorer 7 vs. other IE versions), this small but dynamic snippet is just what I needed to find the true content area of the container.  Feel free to convert this JavaScript snippet into whatever JavaScript framework your prefer!</p><p><a
href="http://davidwalsh.name/detect-scrollbar-width">Detect Scrollbar Width with&nbsp;JavaScript</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-scrollbar-width/feed</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Face Detection with&#160;jQuery</title><link>http://davidwalsh.name/face-detection-jquery</link> <comments>http://davidwalsh.name/face-detection-jquery#comments</comments> <pubDate>Thu, 20 Oct 2011 15:54:13 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5317</guid> <description><![CDATA[I&#8217;ve always been intrigued by recognition software because I cannot imagine the logic that goes into all of the algorithms. Whether it&#8217;s voice, face, or other types of detection, people look and sound so different, pictures are shot differently, and from different angles, I cannot fathom how it&#8217;s all done. Since I already covered booby [...]<p><a
href="http://davidwalsh.name/face-detection-jquery">Face Detection with&nbsp;jQuery</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[<a
href="http://davidwalsh.name/dw-content/face-recognition.php"><img
src="http://davidwalsh.name/dw-content/face-detection.png" alt="jQuery Face Detection" class="image" /></a><p>I&#8217;ve always been intrigued by recognition software because I cannot imagine the logic that goes into all of the algorithms.  Whether it&#8217;s voice, face, or other types of detection, people look and sound so different, pictures are shot differently, and from different angles, I cannot fathom how it&#8217;s all done.  Since I already covered <del>booby</del> <a
href="http://davidwalsh.name/nudejs">nudity detection with JavaScript</a>, I thought it would be worth some time to explore face detection.  Facebook uses it, so maybe it has application in your websites.</p><p>One face detection library I found is <a
href="https://github.com/jaysalvat/jquery.facedetection">Face Detection by Jay Salvat</a> and Liu Liu.  This is a standard jQuery plugin that receives an image and returns an array of coordinates of faces found within the image.  Let&#8217;s have a look at how to use it!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/face-recognition.php" class="demo">View Demo</a><div
class="clear"></div></div><h2>jQuery.faceDetection</h2><p>Four JS files are required for this jQuery plugin:</p><pre class="html">
%MINIFYHTML6d0d016c2c19f02f35e3835699b764790%%MINIFYHTML6d0d016c2c19f02f35e3835699b764791%%MINIFYHTML6d0d016c2c19f02f35e3835699b764792%%MINIFYHTML6d0d016c2c19f02f35e3835699b764793%</pre><p>The faceDetection plugin wraps functionality within the first two JavaScript files, and returns an array of objects which represent the coordinates of the faces within the photo (if any are found).  An example would be:</p><pre class="js">
var coords = jQuery("#myImage").faceDetection();
/* Returns:
	{
		x: 525
		y: 435,
		width: 144,
		height: 144,
		positionX: 532.6353328125226,
		positionY: 443.240976080536,
		offsetX: 532.6353328125226,
		offsetY: 443.240976080536,
		confidence: 12.93120119,
		neighbour: undefined,
	}
*/
</pre><p>You may also add event callbacks to every call:</p><pre class="js">
var coords = jQuery("#myImage").faceDetection({
	complete: function(image, coords) {
		// Do something
	},
	error: function() {
		console.warn("Could not process image");
	}
});
</pre><p>It&#8217;s up to you what you&#8217;d like to do when the faces have been found.  You could add a square around the person&#8217;s face:</p><pre class="js">
jQuery("img").each(function() {
	var img = this;
	// Get faces cooridnates
	var coordinates = jQuery(img).faceDetection();
	// Make boxes if faces are found
	if(coordinates.length) {
		coordinates.forEach(function(coord) {
			jQuery("<div>", {
				css: {
					position: "absolute",
					left: coord.positionX + 5 + "px",
					top: coord.positionY + 5 + "px",
					width: coord.width + "px",
					height: coord.height + "px",
					border: "3px solid white"
				}
			}).appendTo(img.parentNode);
		});
	}
});
</pre><p>There&#8217;s not much more to it than that!</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/face-recognition.php" class="demo">View Demo</a><div
class="clear"></div></div><p>I tried to vary the photos I used faceDetection on and as I expected, the results are the not perfect.  They are, however, quite good;  no software will be perfect for all cases.  The software also does not do facial comparison, so you would need to provide suggestions as to the face&#8217;s identity via another method.  For what this plugin is meant to do, however, it does pretty well.  I encourage you to give this a try!</p><p><a
href="http://davidwalsh.name/face-detection-jquery">Face Detection with&nbsp;jQuery</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/face-detection-jquery/feed</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>DOM Manipulation with&#160;put-selector</title><link>http://davidwalsh.name/put-selector</link> <comments>http://davidwalsh.name/put-selector#comments</comments> <pubDate>Mon, 17 Oct 2011 15:12:08 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Markup]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5316</guid> <description><![CDATA[DOM node manipulation is a big part of the web today; just look at how popular the jQuery JavaScript framework has gotten. The ability to easily work with the DOM allows us to do a lot of work in a little bit of code. Thanks to a new JavaScript module by Dojo Toolkit developer Kris [...]<p><a
href="http://davidwalsh.name/put-selector">DOM Manipulation with&nbsp;put-selector</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>DOM node manipulation is a big part of the web today;  just look at how popular the jQuery JavaScript framework has gotten.  The ability to easily work with the DOM allows us to do a lot of work in a little bit of code.  Thanks to a new JavaScript module by Dojo Toolkit developer Kris Zyp, working with the DOM just got a lot more compact.  With a name as short as the syntax itself, <a
href="https://github.com/kriszyp/put-selector" rel="nofollow">put</a> could make you change the way you work with the DOM.</p><h2>Creating DOM&nbsp;Nodes</h2><p>Creating new nodes is just about as simple as it gets:</p><pre class="js">
// Create an empty DIV
var div = put("div");
</pre><p>Boom, there&#8217;s your new DIV element!  And if you want your new code to have a few CSS classes:</p><pre class="js">
// Create a DIV with some CSS classes
var div2 = put("div.classOne.classTwo");
</pre><p>How about creating nodes with attributes?</p><pre class="js">
// Create a DIV with some CSS classes and attributes
var div3 = put("div.classOne.classTwo[title=Hover over me][style=display:inline-block]");
</pre><p>The syntax for inserting the DOM node is a bit different because the parent then becomes the first argument in the put signature:</p><pre class="js">
// Create an INPUT with an ID and an attribute, place it into the body
// The body text goes into the third argument;  not(!) innerHTML, just text
var div4 = put(document.body, "input[type=text]#myInput", "This is inner html");
</pre><h2>Manipulating Existing DOM&nbsp;Nodes</h2><p>Manipulating DOM nodes is actually very much like creating the nodes themselves:</p><pre class="js">
var myInput = document.getElementById("myInput");
put(myInput, ".anotherClass");

// Add CSS classes attributes to the element
put(myInput, "[placeholder=first name][required=true][title=first name element].yetAnotherClass");
</pre><p>Just remove the tagName and you can modify the node.</p><h2>Node, Class, and Attribute&nbsp;Deletion</h2><p>The &#8220;!&#8221; character is meaningful in that it represents deletion within put.  Let&#8217;s remove a few classes and attributes from a given node, then let&#8217;s remove the node itself:</p><pre class="js">
// Remove a CSS class from the INPUT element
put(myInput, "!anotherClass");

// Remove attributes from the INPUT element
put(myInput, "[!required][!title]");

// Delete a node!
put(myInput, "!");
</pre><p>The syntax for deletion is short but sweet.  The only criticism I have is that if this could create a maintenance problem if developers are not experience with put.</p><h2>Creating and Managing Child&nbsp;Nodes</h2><p>Creating childNodes for an existing node is another functionality made easier by put:</p><pre class="js">
// Create a base node so we can add nodes around it
var baseNode = put(document.body, "div#baseNode");

// Add two DIVs *after* the baseNode
put(baseNode, "+div +div");

// Add a SPAN element *before* the baseNode
put(baseNode, "-span");

// Create the parent list element 
var ul = put(document.body, "ul");

// Create a child list item
var firstItem = put(ul, "li");
</pre><h2>Moving and ReParenting&nbsp;Nodes</h2><p>Reparenting and moving elements within the DOM is another basic task that, when you use JavaScript&#8217;s native functions, takes far too much code.  Let&#8217;s have a look at moving nodes around with put:</p><pre class="js">
// Move one node to another parent
// parent > child
put(ul, ">", firstItem);

// Put one element after the first
put(div1, "+", div2);
</pre><p>A simple series of symbols designates where within the node try an element should go!</p><h2>More Traditional Node Property&nbsp;Management</h2><p>For those who prefer a more verbose element creation syntax, put-selector provides that as well:</p><pre class="js">
var span = put(parent, "span", {
	title: "Hover over me!",
	style: "font-style: italic;"
});
</pre><p>Kris&#8217; tool is great in that it&#8217;s ultra-efficient, modular, and easy to learn.  On the other side, it&#8217;s possible that the syntax may be a bit <em>too</em> compact for persons try to maintain an application that they didn&#8217;t write.  What do you think of put?  An easy to use utility or a &#8220;simple but complicated&#8221; resource?  If I&#8217;m honest, I&#8217;m teetering on the fence &#8212; maybe you can convince me?</p><p><a
href="http://davidwalsh.name/put-selector">DOM Manipulation with&nbsp;put-selector</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/put-selector/feed</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>File Uploads and&#160;C:\fakepath\</title><link>http://davidwalsh.name/fakepath</link> <comments>http://davidwalsh.name/fakepath#comments</comments> <pubDate>Thu, 29 Sep 2011 01:24:48 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5300</guid> <description><![CDATA[I was recently working on a project that required providing an AJAX uploading widget to users. I decided to use Dojo&#8217;s dojox.form.FileInput widget so the &#8220;Upload&#8221; button would look just like every other button within the web application. Everything worked great until I tested the widget in Chrome and found that the value of the [...]<p><a
href="http://davidwalsh.name/fakepath">File Uploads and&nbsp;C:\fakepath\</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 project that required providing an AJAX uploading widget to users.  I decided to use Dojo&#8217;s dojox.form.FileInput widget so the &#8220;Upload&#8221; button would look just like every other button within the web application.  Everything worked great until I tested the widget in Chrome and found that the value of the input node was being set to <code>C:\fakepath</code>\{Original File Name}.  I then checked Internet Explorer and Safari;  both of them were prepending &#8220;<code>C:\fakepath</code>&#8221; to the file name.  WTF?!</p><p>After doing some research, I found <a
href="http://acidmartin.wordpress.com/2009/06/09/the-mystery-of-cfakepath-unveiled/" rel="nofollow">this blog post</a>, which explained:</p><blockquote><p>According to the specifications of HTML5, a file upload control should not reveal the real local path to the file you have selected, if you manipulate its value string with JavaScript. Instead, the string that is returned by the script, which handles the file information is <code>C:\fakepath</code>.</p><p>This requirement is already implemented in Internet Explorer 8 – the real path to the file will be shown only if the page that contains the control is added to the trusted sites collection of the browser.</blockquote></p><p>That made sense;  essentially the browser is feeding that lame <code>C:\fakepath</code>\ text in.  Luckily all I needed to do was fix the issue by doing a simple string replace call:</p><pre class="js">
// Change the node's value by removing the fake path
inputNode.value = fileInput.value.replace("C:\\fakepath\\", "");
</pre><p>Whew &#8212; dodged a bullet there.  Just wanted to post this for everyone in case you run into it in the future.</p><p><a
href="http://davidwalsh.name/fakepath">File Uploads and&nbsp;C:\fakepath\</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/fakepath/feed</wfw:commentRss> <slash:comments>4</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/62 queries in 0.041 seconds using disk: basic
Object Caching 1437/1535 objects using disk: basic

Served from: davidwalsh.name @ 2012-02-08 13:57:39 -->
