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

<channel>
	<title>SitePoint &#187; JavaScript &amp; CSS</title>
	<atom:link href="http://www.sitepoint.com/blogs/category/tech/dhtml-css/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sitepoint.com/blogs</link>
	<description>News, opinion, and fresh thinking for web developers and designers. The official podcast of sitepoint.com.</description>
	<lastBuildDate>Sat, 21 Nov 2009 02:38:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google Releases its JavaScript Closure Tools</title>
		<link>http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/</link>
		<comments>http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 07:52:52 +0000</pubDate>
		<dc:creator>Craig Buckler</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[library]]></category>

		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15743</guid>
		<description><![CDATA[Do we need more JavaScript libraries and tools? Perhaps not, but since these power Google Search, GMail, Docs and Maps, they're worth another look.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/02/26/server-side-javascript/' rel='bookmark' title='Permanent Link: Will Server-Side JavaScript ever catch on?'>Will Server-Side JavaScript ever catch on?</a> <small>Server-side JavaScript appears to be a logical choice for web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/10/server-side-javascript-will-be-as-common-as-php/' rel='bookmark' title='Permanent Link: Server-side JavaScript Will Be as Common as PHP'>Server-side JavaScript Will Be as Common as PHP</a> <small>Despite the fact that JavaScript has been typecast as the...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/197-google-closure-tools.png" width="125" height="125" alt="Google Closure" class="imgright" />New JavaScript libraries and frameworks appear all the time, but it&#8217;s not every day that Google release the client-side code that powers Search, GMail, Google Maps, Google Docs, and more. The company has open-sourced their Closure Tools and they are now available to download from <a href="http://code.google.com/closure/">Google Code Labs</a>.</p>
<p>Three systems are provided for eager client-side developers:</p>
<h2>1. The Google Closure Compiler</h2>
<p>&#8220;Compiler&#8221; is a confusing term &#8212; this is a Java-powered JavaScript optimizer that reduces file sizes by removing dead code, renaming variables, and removing whitespace and comments. </p>
<div id="adz" class="vertical"></div><p>You can either:</p>
<ol>
<li><a href="http://code.google.com/p/closure-compiler/downloads/list">download the Closure Compiler</a>, or</li>
<li><a href="http://closure-compiler.appspot.com/">use the online Closure Compiler tool</a>.</li>
</ol>
<p>In my brief tests, a 28Kb JavaScript file was reduced to 15Kb (46% reduction) using &#8220;Simple&#8221; compression to remove white-space and comments. The reduction factor was almost identical to <a href="http://developer.yahoo.com/yui/compressor/">Yahoo&#8217;s YUI Compressor</a>. </p>
<p>&#8220;Advanced&#8221; compression with variable and function renaming reduced the file size to a little under 10Kb (64% reduction). The code continued to work correctly, although a couple JavaScript warnings were generated about uninitialized variables which were not evident in the uncompressed version.</p>
<p>The Closure Compiler is certainly worth trying if you want to speed up your web page&#8217;s download speeds. However, be careful to fully test the resulting JavaScript code.</p>
<h2>2. The Google Closure Library</h2>
<p>The <a href="http://code.google.com/closure/library/">Closure library</a> is an alternative to <a href="http://jquery.com/">jQuery</a> or the <a href="http://developer.yahoo.com/yui/">YUI Library</a>. The usual features are available, e.g. helper functions, Ajax, DOM manipulation, event handlers, CSS control, animation, effects, etc.</p>
<p>The code, comments, and <a href="http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/index.html">documentation</a> are generally good, although I could not find information about browser support. Some of the examples are a little basic but I suspect they will be improved over time.</p>
<p><a href="http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/">Kevin Yank&#8217;s recent article</a> features comments from Dmitry Baranovskiy who has expressed concerns about the quality of the code. They are valid criticisms and I doubt the Closure will win over many jQuery aficionados, but choice is always a good thing and the library is will improve now it&#8217;s in the public domain.</p>
<h2>3. Google Closure Templates</h2>
<p><a href="http://code.google.com/closure/templates/">Closure Templates</a> is a templating system for client-side JavaScript and server-side Java. It&#8217;s a system that allows you to add small language-neutral components that create a full user interface.</p>
<p>Documentation is sparse and there are few examples. Server-side Java developers may adopt the system, but I&#8217;m not convinced it will appeal to ASP.NET or PHP developers.</p>
<p>Will you try Google&#8217;s Closure Tools? Or has the choice of tools become so bewildering you&#8217;ll stick with what you know?</p>
<p>See also: <a href="http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/">Google Closure: How not to write JavaScript</a></p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/02/26/server-side-javascript/' rel='bookmark' title='Permanent Link: Will Server-Side JavaScript ever catch on?'>Will Server-Side JavaScript ever catch on?</a> <small>Server-side JavaScript appears to be a logical choice for web...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/10/server-side-javascript-will-be-as-common-as-php/' rel='bookmark' title='Permanent Link: Server-side JavaScript Will Be as Common as PHP'>Server-side JavaScript Will Be as Common as PHP</a> <small>Despite the fact that JavaScript has been typecast as the...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Google Closure: How not to write JavaScript</title>
		<link>http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/</link>
		<comments>http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 03:38:19 +0000</pubDate>
		<dc:creator>Kevin Yank</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
<category>development</category><category>Google</category><category>JavaScript</category>
		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15780</guid>
		<description><![CDATA[What if Google released a JavaScript library that sucked, and no one noticed? JavaScript expert Dmitry Baranovskiy has peeked under the hood of Google’s new Closure Library, and he doesn’t like what he sees. Follow along as he points out a few of the library’s many failings, and why the Web deserves better from Google.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/' rel='bookmark' title='Permanent Link: Google Releases its JavaScript Closure Tools'>Google Releases its JavaScript Closure Tools</a> <small>Do we need more JavaScript libraries and tools? Perhaps not,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/' rel='bookmark' title='Permanent Link: Fixing Object Instances in JavaScript'>Fixing Object Instances in JavaScript</a> <small>Even experienced coders can get caught out by object handling...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>At the <a href="http://www.edgeoftheweb.org.au/">Edge of the Web</a> conference in Perth last week I got to catch up with <a href="http://dmitry.baranovskiy.com/">Dmitry Baranovskiy</a>, the creator of the <a href="http://raphaeljs.com/">Raphaël</a> and <a href="http://g.raphaeljs.com/">gRaphaël</a> JavaScript libraries. Perhaps the most important thing these libraries do is make sophisticated vector graphics possible in Internet Explorer, where JavaScript performance is relatively poor. Dmitry, therefore, has little patience for poorly-written JavaScript like the code he found in Google’s just-released <a href="http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html">Closure Library</a>.</p>
<p>Having delivered a talk on <a href="http://www.slideshare.net/Dmitry.Baranovskiy/your-javascript-library">how to write your own JavaScript library</a> (<a href="http://passingcuriosity.com/2009/notes-on-dmitry-baranovskiys-talk-on-your-javascript-library/">detailed notes</a>) at the conference, Dmitry shared his thoughts on the new library over breakfast the next morning. “Just what the world needs—another sucky JavaScript library,” he said. When I asked him what made it ‘sucky’, he elaborated. “It’s a JavaScript library written by Java developers who clearly don’t <em>get</em> JavaScript.”</p>
<p>For the rest of the day, to anyone who would listen, Dmitry cited example after example of the terrible code he had found when he went digging through Closure. His biggest fear, he told me, was that people would switch from truly excellent JavaScript libraries like <a href="http://jquery.com/">jQuery</a> to Closure on the strength of the Google name.</p>
<p>“I’ll make you a deal,” I told him. “Send me some examples of this terrible code and I’ll publish it on SitePoint.”</p>
<h2>The Slow Loop</h2>
<p>From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/array/array.js?r=2">array.js</a>, line 63:</p>
<pre><code class="javascript">for (var i = fromIndex; i &lt; arr.length; i++) {</code></pre>
<p>This <code>for</code> loop looks up the <code>.length</code> property of the array (<code>arr</code>) each time through the loop. Simply by setting a variable to store this number at the start of the loop, you can make the loop run much faster:</p>
<pre><code class="javascript">for (var i = fromIndex, ii = arr.length; i &lt; ii; i++) {</code></pre>
<p>Google’s developers seem to have figured this trick out later on in the same file. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/array/array.js?r=2">array.js</a>, line 153:</p>
<pre><code class="javascript">var l = arr.length;  // must be fixed during loop... see docs
⋮
for (var i = l - 1; i >= 0; --i) {</code></pre>
<p>This loop is better in that it avoids a property lookup each time through the loop, but this particular <code>for</code> loop is so simple that it could be further simplified into a <code>while</code> loop, which will run much faster again:</p>
<pre><code class="javascript">var i = arr.length;
⋮
while (i--) {</code></pre>
<p>But not all of Closure Library’s performance woes are due to poorly optimized loops. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/dom/dom.js?r=2">dom.js</a>, line 797:</p>
<pre><code class="javascript">switch (node.tagName) {
  case goog.dom.TagName.APPLET:
  case goog.dom.TagName.AREA:
  case goog.dom.TagName.BR:
  case goog.dom.TagName.COL:
  case goog.dom.TagName.FRAME:
  case goog.dom.TagName.HR:
  case goog.dom.TagName.IMG:
  case goog.dom.TagName.INPUT:
  case goog.dom.TagName.IFRAME:
  case goog.dom.TagName.ISINDEX:
  case goog.dom.TagName.LINK:
  case goog.dom.TagName.NOFRAMES:
  case goog.dom.TagName.NOSCRIPT:
  case goog.dom.TagName.META:
  case goog.dom.TagName.OBJECT:
  case goog.dom.TagName.PARAM:
  case goog.dom.TagName.SCRIPT:
  case goog.dom.TagName.STYLE:
    return false;
}
return true;</code></pre>
<p>This kind of code is actually pretty common in Java, and will perform just fine there. In JavaScript, however, this <code>switch</code> statement will perform like a dog each and every time a developer checks if a particular HTML element is allowed to have children.</p>
<p>Experienced JavaScript developers know that it’s much quicker to create an object to encapsulate this logic:</p>
<pre><code class="javascript">var takesChildren = {}
takesChildren[goog.dom.TagName.APPLET] = 1;
takesChildren[goog.dom.TagName.AREA] = 1;
⋮</code></pre>
<p>With that object set up, the function to check if a tag accepts children can run much quicker:</p>
<pre><code class="javascript">return !takesChildren[node.tagName];</code></pre>
<p>This code can be further bulletproofed against outside interference using <code>hasOwnProperty</code> (see below for a full explanation of this).</p>
<pre><code class="javascript">return !takesChildren.hasOwnProperty(node.tagName);</code></pre>
<p>If there’s one thing we expect from Google it’s a focus on performance. Heck, Google released its own browser, Google Chrome, primarily to take JavaScript performance to the next level!</p>
<p>Seeing code like this, one has to wonder if Google could have achieved the same thing by teaching its engineers to write better JavaScript code.</p>
<h2>Six Months in a Leaky Boat</h2>
<p>It would be unfair to suggest that Google has <em>ignored</em> performance in building Closure. In fact, the library provides a generic method for caching the results of functions that run slowly, but which will always return the same result for a given set of arguments. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/memoize/memoize.js?r=2">memoize.js</a>, line 39:</p>
<pre><code class="javascript">goog.memoize = function(f, opt_serializer) {
  var functionHash = goog.getHashCode(f);
  var serializer = opt_serializer || goog.memoize.simpleSerializer;
  
  return function() {
    // Maps the serialized list of args to the corresponding return value.
    var cache = this[goog.memoize.CACHE_PROPERTY_];
    if (!cache) {
      cache = this[goog.memoize.CACHE_PROPERTY_] = {};
    }
    var key = serializer(functionHash, arguments);
    if (!(key in cache)) {
      cache[key] = f.apply(this, arguments);
    }
    return cache[key];
  };
};</code></pre>
<p>This is a clever performance trick employed in a number of major JavaScript libraries; the problem is, Google has not provided any means of limiting the size of the cache! This is fine if a cached function is only ever called with a small collection of different arguments, but this is a dangerous assumption to make in general.</p>
<div id="adz" class="vertical"></div><p>Used to cache a function’s results based on, say, the coordinates of the mouse pointer, this code’s memory footprint will rapidly grow out of control, and slow the browser to a crawl.</p>
<p>In Dmitry’s words, “I’m not sure what this pattern is called in Java, but in JavaScript it’s called a ‘memory leak’.”</p>
<h2>Code in a Vacuum</h2>
<p>In his talk on building JavaScript libraries, Dmitry compared JavaScript’s global scope to a public toilet. “You can’t avoid going in there,” he said. “But try to limit your contact with surfaces when you do.”</p>
<p>For a general-purpose JavaScript library to be reliable, it must not only avoid interfering with any other JavaScript code that might be running alongside it, but it must also protect itself from other scripts that aren’t so polite. </p>
<p>From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/object/object.js?r=2">object.js</a>, line 31:</p>
<pre><code class="javascript">goog.object.forEach = function(obj, f, opt_obj) {
  for (var key in obj) {
    f.call(opt_obj, obj[key], key, obj);
  }
};</code></pre>
<p><code>for</code>-<code>in</code> loops like this one are inherently dangerous in JavaScript libraries, because you never know what other JavaScript code might be running in the page, and what it might have added to JavaScript’s standard <code>Object.prototype</code>.</p>
<p><code>Object.prototype</code> is the JavaScript object that contains the properties shared by all JavaScript objects. Add a new function to <code>Object.prototype</code>, and every JavaScript object running in the page will have that function added to it—even if it was created beforehand! Early JavaScript libraries like <a href="http://www.prototypejs.org/">Prototype</a> made a big deal of adding all sorts of convenience features to <code>Object.prototype</code>.</p>
<p>Unfortunately, unlike the built-in properties supplied by <code>Object.prototype</code>, custom properties added to <code>Object.prototype</code> will show up as an object property in any <code>for</code>-<code>in</code> loop in the page.</p>
<p>In short, Closure Library cannot coexist with any JavaScript code that adds features to <code>Object.prototype</code>.</p>
<p>Google could have made its code more robust by using <code>hasOwnProperty</code> to check each item in the <code>for</code>-<code>in</code> loop to be sure it belongs to the object itself:</p>
<pre><code class="javascript">goog.object.forEach = function(obj, f, opt_obj) {
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      f.call(opt_obj, obj[key], key, obj);
    }
  }
};</code></pre>
<p>Here’s another especially fragile bit of Closure Library. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js?r=2">base.js</a>, line 677:</p>
<pre><code class="javascript">goog.isDef = function(val) {
 return val !== undefined;
};</code></pre>
<p>This function checks if a particular variable has a value defined. Or it does, unless a 3rd party script sets the global <code>undefined</code> variable to something else. This single line of code anywhere in the page will bring Closure Library crashing down:</p>
<pre><code class="javascript">var undefined = 5;</code></pre>
<p>Relying on the global <code>undefined</code> variable is another rookie mistake for JavaScript library authors.</p>
<p>You might think that anyone who assigns a value to <code>undefined</code> deserves what they get, but the fix in this case is trivial: simply declare a local <code>undefined</code> variable for use within the function!</p>
<pre><code class="javascript">goog.isDef = function(val) {
  var undefined;
  return val !== undefined;
};</code></pre>
<h2>Typical Confusion</h2>
<p>One of the most confusing aspects of JavaScript for developers coming from other languages is its system of data types. Closure Library contains plenty of bloopers that further reveal that its authors lack extensive experience with the finer points of JavaScript.</p>
<p>From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/string/string.js?r=2">string.js</a>, line 97:</p>
<pre><code class="javascript">// We cast to String in case an argument is a Function. …
var replacement = String(arguments[i]).replace(…);</code></pre>
<p>This code converts <code>arguments[i]</code> to a string object using the <code>String</code> conversion function. This is possibly the slowest way to perform such a conversion, although it would be the most obvious to many developers coming from other languages.</p>
<p>Much quicker is to add an empty string (<code>""</code>) to the value you wish to convert:</p>
<pre><code class="javascript">var replacement = (arguments[i] + "").replace(…);</code></pre>
<p>Here’s some more string-related type confusion. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js?r=2">base.js</a>, line 742:</p>
<pre><code class="javascript">goog.isString = function(val) {
  return typeof val == 'string';
};</code></pre>
<p>JavaScript actually represents text strings in two different ways—as primitive string values, and as string objects:</p>
<pre><code class="javascript">var a = "I am a string!";
alert(typeof a); // Will output "string"
var b = new String("I am also a string!");
alert(typeof b); // Will output "object"</code></pre>
<p>Most of the time strings are efficiently represented as primitive values (<code>a</code> above), but to call any of the built-in methods on a string (e.g. <code>toLowerCase</code>) it must first be converted to a string object (<code>b</code> above). JavaScript converts strings back and forth between these two representations automatically as needed. This feature is called “autoboxing”, and appears in many other languages.</p>
<p>Unfortunately for Google’s Java-savvy developers, Java only ever represents strings as objects. That’s my best guess for why Closure Library overlooks the second type of string in JavaScript:</p>
<pre><code class="javascript">var b = new String("I am also a string!");
alert(goog.isString(b)); // Will output FALSE</code></pre>
<p>Here’s another example of Java-inspired type confusion. From <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/color/color.js?r=2">color.js</a>, line 633:</p>
<pre><code class="javascript">return [
  Math.round(factor * rgb1[0] + (1.0 - factor) * rgb2[0]),
  Math.round(factor * rgb1[1] + (1.0 - factor) * rgb2[1]),
  Math.round(factor * rgb1[2] + (1.0 - factor) * rgb2[2])
];</code></pre>
<p>Those <code>1.0</code>s are telling. Languages like Java represent integers (<code>1</code>) differently from floating point numbers (<code>1.0</code>). In JavaScript, however, numbers are numbers. <code>(1 - factor)</code> would have worked just as well.</p>
<p>Yet another example of JavaScript code with a whiff of Java about it can be seen in <a href="http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/fx/fx.js?r=2">fx.js</a>, line 465:</p>
<pre><code class="javascript">goog.fx.Animation.prototype.updateCoords_ = function(t) {
  this.coords = new Array(this.startPoint.length);
  for (var i = 0; i < this.startPoint.length; i++) {
    this.coords[i] = (this.endPoint[i] - this.startPoint[i]) * t +
        this.startPoint[i];
  }
};</code></code></pre>
<p>See how they create an array on the second line?</p>
<pre><code class="javascript">this.coords = new Array(this.startPoint.length);</code></pre>
<p>Although it is necessary in Java, it is entirely pointless to specify the length of an array ahead of time in JavaScript. It would make just as much sense to create a new variable for storing numbers with <code>var i = new Number(0);</code> instead of <code>var i = 0;</code>.</p>
<p>Rather, you can just set up an empty array and allow it to grow as you fill it in. Not only is the code shorter, but it runs faster too:</p>
<pre><code class="javascript">this.coords = [];</code></pre>
<p>Oh, and did you spot yet another inefficient <code>for</code> loop in that function?</p>
<h2>API Design</h2>
<p>If all the low-level code quality nitpicks above don’t convince you, I defy you to try using some of the APIs Google has built into Closure Library.</p>
<p>Closure’s <a href="http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/closure_goog_graphics_graphics.js.html">graphics classes</a>, for example, are modeled around the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">HTML5 canvas API</a>, which is about what you’d expect from a JavaScript API designed by an HTML standards body. In short, it’s repetitive, inefficient, and downright unpleasant to code against.</p>
<p>As the author of <a href="http://raphaeljs.com/">Raphaël</a> and <a href="http://g.raphaeljs.com/">gRaphaël</a>, Dmitry has plenty of experience designing usable JavaScript APIs. If you want to grasp the full horror of the canvas API (and by extension, Closure’s graphics API), check out the audio and slides from <a href="http://www.webdirections.org/resources/dmitry-baranovskiy-canvas/">Dmitry’s Web Directions South 2009 talk</a> on the subject.</p>
<h2>Google’s Responsibility to Code Quality</h2>
<p>By this point I hope you’re convinced that Closure Library is not a shining example of the best JavaScript code the Web has to offer. If you’re looking for that, might I recommend more established players like <a href="http://jquery.com/">jQuery</a>?</p>
<p>But you might be thinking “So what? Google can release crappy code if it wants to—nobody’s forcing <em>you</em> to use it.” And if this were a personal project released by some googler on the side under his or her own name, I’d agree with you, but Google has endorsed Closure Library by stamping it with the Google brand.</p>
<p>The truth is, developers <em>will</em> switch to Closure because it bears the Google name, and that’s the real tragedy here. Like it or not, Google is a trusted name in the development community, and it has a responsibility to that community to do a little homework before deciding a library like Closure deserves public exposure.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-open-source-javascript-closure-library/' rel='bookmark' title='Permanent Link: Google Releases its JavaScript Closure Tools'>Google Releases its JavaScript Closure Tools</a> <small>Do we need more JavaScript libraries and tools? Perhaps not,...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/' rel='bookmark' title='Permanent Link: Fixing Object Instances in JavaScript'>Fixing Object Instances in JavaScript</a> <small>Even experienced coders can get caught out by object handling...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/feed/</wfw:commentRss>
		<slash:comments>113</slash:comments>
		</item>
		<item>
		<title>Video: CSS Frameworks – Make the Right Choice</title>
		<link>http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/</link>
		<comments>http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 08:11:00 +0000</pubDate>
		<dc:creator>Kevin Yank</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
<category>CSS</category><category>video</category>
		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15746</guid>
		<description><![CDATA[Choose the right framework and you’ll save yourself a lot of work. Choose the wrong one, and you’ll find your projects weighed down by restrictive assumptions and masses of code that you don’t understand. When it comes to CSS frameworks, making the right choice is everything.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/02/17/whats-so-bad-about-css-frameworks/' rel='bookmark' title='Permanent Link: What&#8217;s So Bad About CSS Frameworks?'>What&#8217;s So Bad About CSS Frameworks?</a> <small>Standards-aware web developers often feel conflicted about using CSS frameworks....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/' rel='bookmark' title='Permanent Link: CSS Frameworks and Semantic Class Names'>CSS Frameworks and Semantic Class Names</a> <small>CSS frameworks often contain crufty, non-semantic code. Does it have...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/09/win-signed-sitepoint-books-at-web-directions-south/' rel='bookmark' title='Permanent Link: Win Signed SitePoint Books at Web Directions South'>Win Signed SitePoint Books at Web Directions South</a> <small>If you're at the Web Directions South conference in Sydney...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>In the past couple of months, I have had the great pleasure of presenting a talk entitled “CSS Frameworks: Make the Right Choice” at both of Australia’s premier web design conferences: <a href="http://south09.webdirections.org/">Web Directions South 2009</a> and <a href="http://www.edgeoftheweb.org.au/">Edge of the Web 2009</a>.</p>
<p>Of course, even the most dedicated SitePoint fan could find it hard to justify a trip to Australia to see me speak; thankfully, the folks at Web Directions were kind enough to share the audio recorded at the event under a Creative Commons license that enables me to share it with you in a richer format.</p>
<p>I am delighted, therefore, to present this video re-creation of the talk including my animated slides, a screencast video demo, and the audio recorded live at Web Directions South 2009. Be sure to visit <a href="http://www.webdirections.org/">the Web Directions site</a> for the accumulated audio and slides from the entire conference series!</p>
<p><object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7530607&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=7530607&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object>
<p><a href="http://vimeo.com/7530607">CSS Frameworks: Make the Right Choice (WDS09)</a> from <a href="http://vimeo.com/sitepoint">SitePoint Staff</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<div id="adz" class="vertical"></div><blockquote>
<p>SitePoint CTO Kevin Yank presented this talk at Web Directions South 2009 in Sydney, Australia on Friday, October 9th, 2009.</p>
<p>With the proliferation and widespread adoption of JavaScript frameworks, smart developers have wondered if a similar approach to smoothing over the rough spots of CSS might work. Thus, CSS frameworks like Blueprint, YUI Library CSS Tools, Boilerplate, and many others were born. In this session, we will survey the landscape of CSS frameworks and consider how each of them deals with the unique challenge of creating generalised, reusable CSS styles.</p>
<p>There are a number of different approaches, and some are better than others. Choose the right framework and you’ll save yourself a lot of work. Choose the wrong one, and you’ll find your projects weighed down by restrictive assumptions and masses of code that you don’t understand. When it comes to CSS frameworks, making the right choice is everything. By the end of this session, you might just decide that the right framework for you is no framework at all.</p>
</blockquote>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/02/17/whats-so-bad-about-css-frameworks/' rel='bookmark' title='Permanent Link: What&#8217;s So Bad About CSS Frameworks?'>What&#8217;s So Bad About CSS Frameworks?</a> <small>Standards-aware web developers often feel conflicted about using CSS frameworks....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/' rel='bookmark' title='Permanent Link: CSS Frameworks and Semantic Class Names'>CSS Frameworks and Semantic Class Names</a> <small>CSS frameworks often contain crufty, non-semantic code. Does it have...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/10/09/win-signed-sitepoint-books-at-web-directions-south/' rel='bookmark' title='Permanent Link: Win Signed SitePoint Books at Web Directions South'>Win Signed SitePoint Books at Web Directions South</a> <small>If you're at the Web Directions South conference in Sydney...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Fixing Object Instances in JavaScript</title>
		<link>http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/</link>
		<comments>http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 15:59:34 +0000</pubDate>
		<dc:creator>Craig Buckler</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
		<category><![CDATA[javascript]]></category>
<category>javascript</category>
		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=15206</guid>
		<description><![CDATA[Even experienced coders can get caught out by object handling in JavaScript, and handing your code to other developers can intensify problems. Craig looks at the problem of creating object instances and provides a quick solution.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/01/javascript-truthy-falsy/' rel='bookmark' title='Permanent Link: Truthy and Falsy: When All is Not Equal in JavaScript'>Truthy and Falsy: When All is Not Equal in JavaScript</a> <small>Anything in JavaScript can be considered to be either truthy...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="imgright" src="http://blogs.sitepointstatic.com/images/tech/179-js-object-instance.jpg" alt="JavaScript objects" width="190" height="190" />Do you know your JavaScript? Take a look at the following code sample and work out what value is shown in the final alert statement …</p>
<pre><code class="javascript">
// object constructor
function ObjectConstructor(a, b, c) {

	this.A = a;
	this.B = b;
	this.C = c;
	this.Total = a + b + c;

}

var obj = ObjectConstructor(1, 2, 3);

alert(obj.Total);
</code></pre>
<p>Hands up everyone who answered &#8220;6.&#8221;</p>
<p>Sorry, you&#8217;re wrong. The answer is … nothing &#8212; or an error stating that &#8216;obj&#8217; is undefined. So what&#8217;s gone wrong?</p>
<p>The simple answer is that we&#8217;ve forgotten the &#8216;new&#8217; operator so an object instance is never created. The statement should be:</p>
<div id="adz" class="horizontal"></div><pre><code class="javascript">
var obj = new ObjectConstructor(1, 2, 3);
</code></pre>
<p>It&#8217;s an easy mistake to make. Novice developers are unlikely to spot the missing operator because the code looks almost identical. Even experienced coders could find it tough to debug (especially since many assume JavaScript is a <a href="http://en.wikipedia.org/wiki/Procedural_language">procedural programming language</a> … which it can be, if you choose to write it that way).</p>
<p>The main problem is that <code>var obj = ObjectConstructor(1, 2, 3);</code> is a perfectly valid JavaScript statement and the interpretor engine will not throw an error. In that context, the value of obj is set to the value returned from the function ObjectConstructor; since no value is returned, obj remains &#8220;undefined&#8221; (a top-level JavaScript property).</p>
<p>This is unlikely to become a major problem if you&#8217;re developing, testing and debugging your own code. However, it could be a different matter when you&#8217;re providing a library or API to thousands of third-party developers. At some point, someone, somewhere, will miss that &#8216;new&#8217; operator and they will blame your code rather than theirs.</p>
<p>Fortunately, JavaScript is a flexible language. We can fix our constructor so an object is correctly created even when the &#8216;new&#8217; operator is omitted:</p>
<pre><code class="javascript">
// object constructor
function ObjectConstructor(a, b, c) {

	if (!(this instanceof arguments.callee)) {
		return new ObjectConstructor(a, b, c);
	}

	this.A = a;
	this.B = b;
	this.C = c;
	this.Total = a + b + c;

}
</code></pre>
<p>The additional &#8216;if&#8217; statement at the top of the constructor checks whether &#8216;this&#8217; is an instance of the object and returns one if necessary. The code <code>var obj = ObjectConstructor(1, 2, 3);</code> will now set obj to an object instance and &#8220;6&#8243; will be output by the alert statement.</p>
<p>Have you ever encountered this problem in your code or when using another library?</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/07/01/javascript-truthy-falsy/' rel='bookmark' title='Permanent Link: Truthy and Falsy: When All is Not Equal in JavaScript'>Truthy and Falsy: When All is Not Equal in JavaScript</a> <small>Anything in JavaScript can be considered to be either truthy...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/10/21/javascript-object-instances/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>CSS Frameworks and Semantic Class Names</title>
		<link>http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/</link>
		<comments>http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 23:17:53 +0000</pubDate>
		<dc:creator>Kevin Yank</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
<category>CSS</category><category>design</category><category>frameworks</category>
		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14814</guid>
		<description><![CDATA[CSS frameworks often contain crufty, non-semantic code. Does it have to be that way? Kevin shows us how semantic markup and CSS frameworks can coexist happily.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/02/17/whats-so-bad-about-css-frameworks/' rel='bookmark' title='Permanent Link: What&#8217;s So Bad About CSS Frameworks?'>What&#8217;s So Bad About CSS Frameworks?</a> <small>Standards-aware web developers often feel conflicted about using CSS frameworks....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/' rel='bookmark' title='Permanent Link: Video: CSS Frameworks – Make the Right Choice'>Video: CSS Frameworks – Make the Right Choice</a> <small>Choose the right framework and you’ll save yourself a lot...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/01/13/add-semantic-richness-to-your-markup-with-rdf-ease/' rel='bookmark' title='Permanent Link: Add Semantic Richness To Your Markup With (RDF) Ease'>Add Semantic Richness To Your Markup With (RDF) Ease</a> <small>Meitar takes another look at bleeding edge Semantic Web technologies...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="imgright size-thumbnail wp-image-14817" title="CSS Dozer" src="http://www.sitepoint.com/blogs/wp-content/uploads/2009/10/dozer-150x150.png" alt="A bulldozer pushing the letters C S S" width="150" height="150" /></p>
<p><strong>One of the most common complaints about CSS frameworks like <a href="http://blueprintcss.org/">Blueprint</a>, <a href="http://developer.yahoo.com/yui/grids/">YUI Grids</a>, and <a href="http://960.gs/">960.gs</a> is that they require designers to dirty their fingers by adding presentational class names to their HTML documents, like so:</strong></p>
<pre><code>&lt;div class="span-9 last"&gt;
&lt;div class="grid_6 alpha"&gt;</code></pre>
<p>Class names like <code>"span-9"</code> really bother designers who care about the quality of their HTML code, because they describe the <strong>appearance</strong> of an element; this should really be left to the CSS properties defined in your site&#8217;s style sheets. The problem with presentational class names is explained especially well by the W3C QA tip, <a href="http://www.w3.org/QA/Tips/goodclassnames"><cite>Use <code>class</code> with semantics in mind</cite></a>:</p>
<blockquote cite="http://www.w3.org/QA/Tips/goodclassnames"><p><strong>Good names don&#8217;t change.</strong> Think about <em>why</em> you want something to look a certain way, and not really about <em>how</em> it should look. Looks can always change, but the reasons for giving something a look stay the same.</p></blockquote>
<div id="adz" class="vertical"></div><p>Maybe you&#8217;re the pragmatic type who takes no issue with this sort of thing, or decides that it&#8217;s a necessary evil given the limitations of the CSS language. Nevertheless, there are plenty of front-end ninjas out there who refuse to use CSS frameworks for this very reason.</p>
<p>It turns out, however, that the latest crop of CSS frameworks provide clever solutions to the problem of presentational class names.</p>
<p><a href="http://blueprintcss.org/">Blueprint CSS</a>, the granddaddy of CSS layout frameworks, now includes a clever Ruby script called compress.rb in its download package. In <a href="http://www.jdclayton.com/blueprints_compress_a_walkthrough.html"><cite>Blueprint&#8217;s compress.rb: A Walkthrough</cite></a>, Blueprint author Joshua Clayton explains how to use the script to generate a custom version of the Blueprint style sheets using your own semantic class names.</p>
<p>The process boils down to writing a simple configuration file that tells the script how to map Blueprint&#8217;s presentational class names to your own semantically meaningful class names. The file will look like this:</p>
<pre><code>demo:
  path: /Users/kyank/Documents/myproject
  semantic_classes:
    ".header, .footer": ".span-24, div.span-24"
    ".content": ".span-18, div.span-18"
    ".sidebar": ".span-6, div.span-6,
                 .last, div.last"</code></pre>
<p>The <code>semantic_classes</code> section provides the mapping. In this example, the <code>header</code> and <code>footer</code> classes will be 24 grid units wide and the <code>content</code> class will be 18 grid units wide. The <code>sidebar</code> class will be 6 grid units wide and the last block in its row.</p>
<p>With this configuration file written, you simply run the compress.rb script, and the customized version of the Blueprint style sheet files (screen.css, print.css, and ie.css) will be generated in the specified path. The style sheet will contain rules like this one, that apply the grid dimensions to your custom class names:</p>
<pre><code>/* semantic class names */
.content {float:left;margin-right:10px;
  width:710px;}</code></pre>
<p>&#8230; and just like that, you gain all the layout facilities of Blueprint CSS with none of the HTML cruft!</p>
<p>If manually compiling your style sheets with a Ruby script sounds like a bit of a pain (which it can be &#8212; especially if you develop on a Windows computer without Ruby installed), a server-side CSS framework might be a better option for you.</p>
<p>CSS frameworks are popping up for all the major server-side programming languages. Two prominent examples include <a href="http://compass-style.org/">Compass</a> (for Ruby), and <a href="http://wiki.github.com/anthonyshort/csscaffold">Scaffold</a> (for PHP). These frameworks let you write your style sheets with extra language features, and automatically compile them to standard CSS code when sending them to the browser.</p>
<p>Using Scaffold, for example, you could write your style sheet like this:</p>
<pre><code>@grid {
  column-width:30;
  column-count:24;
  right-gutter-width:20;
  baseline:20;
  unit:px;
}
.header, .footer {
  +columns(24);
}
.content {
  +columns(18);
}
.sidebar {
  +columns(6);
  +last;
}</code></pre>
<p>The <code>@grid</code> at-rule sets up the options for Scaffold&#8217;s <a href="http://wiki.github.com/anthonyshort/csscaffold/layout-plugin">layout plugin</a>, and then lines like <code>+columns(24);</code> (called <strong>mixins</strong>) are compiled into standard CSS properties when the browser requests the style sheet.</p>
<p>These are just a couple of the ways that the latest CSS frameworks respond to those critics who complain about having to sacrifice HTML code quality to use them. Now you can have all the benefits of a well-tested layout framework, and apply them to your HTML code on your terms.</p>
<p style="text-align: right;"><cite>(photo: <a href="http://www.sxc.hu/photo/858987">Nbauer</a>)</cite></p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/02/17/whats-so-bad-about-css-frameworks/' rel='bookmark' title='Permanent Link: What&#8217;s So Bad About CSS Frameworks?'>What&#8217;s So Bad About CSS Frameworks?</a> <small>Standards-aware web developers often feel conflicted about using CSS frameworks....</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/10/video-css-frameworks-%e2%80%93-make-the-right-choice/' rel='bookmark' title='Permanent Link: Video: CSS Frameworks – Make the Right Choice'>Video: CSS Frameworks – Make the Right Choice</a> <small>Choose the right framework and you’ll save yourself a lot...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/01/13/add-semantic-richness-to-your-markup-with-rdf-ease/' rel='bookmark' title='Permanent Link: Add Semantic Richness To Your Markup With (RDF) Ease'>Add Semantic Richness To Your Markup With (RDF) Ease</a> <small>Meitar takes another look at bleeding edge Semantic Web technologies...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/10/06/css-frameworks-semantic-class-names/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Interesting CSS Quirks: Border-spacing</title>
		<link>http://www.sitepoint.com/blogs/2009/10/01/interesting-css-quirks-border-spacing/</link>
		<comments>http://www.sitepoint.com/blogs/2009/10/01/interesting-css-quirks-border-spacing/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 01:50:54 +0000</pubDate>
		<dc:creator>AlexW</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>

		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14646</guid>
		<description><![CDATA[I came across a CSS peculiarity recently that had me scratching my head, so I thought it was worth popping in a little post here for future Googling head-scratchers. 


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/04/15/5-rarely-used-css-properties/' rel='bookmark' title='Permanent Link: 5 Rarely-Used CSS Properties'>5 Rarely-Used CSS Properties</a> <small>It is easy to forget CSS that you don't use...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/' rel='bookmark' title='Permanent Link: How to Use Operating System Styles in CSS'>How to Use Operating System Styles in CSS</a> <small>CSS can reference fonts and colors defined for the underlying...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/31/techy-treasures-5-fudging-css-counters-in-internet-explorer/' rel='bookmark' title='Permanent Link: Techy Treasures #5: Fudging CSS Counters in Internet Explorer'>Techy Treasures #5: Fudging CSS Counters in Internet Explorer</a> <small>CSS Counters are a useful but under-used feature of CSS2...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I came across a CSS peculiarity recently that had me scratching my head, so I thought it was worth popping in a little post here for future Googling head-scratchers. </p>
<p>The <a href="http://webstandardsgroup.org/mail/">WSG mailing list</a> gets a lot of CSS layout questions sent to it and last week I noticed <a href="http://www.mail-archive.com/wsg@webstandardsgroup.org/msg39800.html">this query</a>. Tee wanted to visually reproduce the table layout shown below without adding extra wrapping DIVs or other non-semantic markup.</p>
<p><img src="http://www.sitepoint.com/examples/tabletest/example.png" alt="Example table layout" width="363px" height="188px" class="imgright" /></p>
<p>It&#8217;s not quite as simple as it looks. </p>
<div id="adz" class="horizontal"></div><p>Anyway, playing around <a href="http://www.sitepoint.com/examples/tabletest/tabletest.html">my approach</a>, I came across a CSS property I&#8217;ve rarely seen in use: <code>border-spacing</code>. </p>
<p>Now if you&#8217;re not super familiar with <code>border-spacing</code>, it&#8217;s essentially a better version of the old &#8216;cellspacing&#8217; table attribute (i.e. <code>&lt;table cellspacing="3px" ..</code>) , and controls the space *between* your table cells. Of course, if you set the table&#8217;s border to collapse (i.e. <code>border-collapse:collapse;</code>) there *is* no space between your table cells, so setting <code>border-spacing</code> becomes redundant.</p>
<p>The key advantage that CSS&#8217;s border-spacing has over HTML&#8217;s cellspacing (besides cleaner markup) is it allows you to set <em>different</em> horizontal and vertical spacing widths &#8212; seemingly perfect for creating the 5 pixel row separations required in the example. <code><a href="http://reference.sitepoint.com/html/table/cellspacing">Cellspacing</a></code> only accepts a single value.</p>
<p>Guessing the CSS, I didn&#8217;t get the result I expected when I tried (<a href="http://reference.sitepoint.com/css/border-spacing/demo">try for yourself</a>): </p>
<pre>
<code class="css">
table#grid {
	border-collapse:separate;
	border-spacing:  5px 0px ;
}
</code>
</pre>
<p><img src="http://i2.sitepoint.com/images/blogs/border-spacing.png" alt="Border-spacing in action" class="imgleft" />Counter-intuitively to the way <code>margin</code>, <code>padding</code>, <code>border</code> and every other CSS property I can think of operates, <code>border-spacing</code> asks for it&#8217;s horizontal value <em>before</em> it&#8217;s vertical value. Strange.</p>
<p>Other points to note with <code>border-spacing</code>:</p>
<ul>
<li>You aren&#8217;t able to assign different top, bottom, right and left values. This makes sense if you think about it, as we&#8217;re actually talking about an attribute of the TABLE, but I think it&#8217;s easy to trick yourself into thinking it&#8217;s part of the TD &#8212; it wraps around the TD borders after all.</li>
<li>Support is perfect in all modern browsers, but old IE6 &#038; 7 don&#8217;t support this property at all.</li>
</ul>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/04/15/5-rarely-used-css-properties/' rel='bookmark' title='Permanent Link: 5 Rarely-Used CSS Properties'>5 Rarely-Used CSS Properties</a> <small>It is easy to forget CSS that you don't use...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/11/css-system-styles/' rel='bookmark' title='Permanent Link: How to Use Operating System Styles in CSS'>How to Use Operating System Styles in CSS</a> <small>CSS can reference fonts and colors defined for the underlying...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/31/techy-treasures-5-fudging-css-counters-in-internet-explorer/' rel='bookmark' title='Permanent Link: Techy Treasures #5: Fudging CSS Counters in Internet Explorer'>Techy Treasures #5: Fudging CSS Counters in Internet Explorer</a> <small>CSS Counters are a useful but under-used feature of CSS2...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/10/01/interesting-css-quirks-border-spacing/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JSNES: a NES Emulator Written in JavaScript</title>
		<link>http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/</link>
		<comments>http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 17:29:30 +0000</pubDate>
		<dc:creator>Craig Buckler</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[javascript]]></category>
<category>development</category><category>game</category><category>JavaScript</category>
		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14340</guid>
		<description><![CDATA[Just when you thought you'd seen everything in JavaScript, along comes a full NES emulator that is actually playable in a browser. Craig takes a look at JSNES.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/10/16/ben-firshman-jsnes-interview/' rel='bookmark' title='Permanent Link: Exclusive Interview With Ben Firshman, Creator of JSNES'>Exclusive Interview With Ben Firshman, Creator of JSNES</a> <small>Craig interviews Ben Firshman, developer of the JavaScript-based NES emulator...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/02/07/opera-fights-back-announces-next-gen-javascript-engine/' rel='bookmark' title='Permanent Link: Opera Fights Back: Announces Next Gen JavaScript Engine'>Opera Fights Back: Announces Next Gen JavaScript Engine</a> <small>At one time, Opera had the fastest ECMAScript / JavaScript...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/28/google-chrome-frame-technical-details/' rel='bookmark' title='Permanent Link: Google Chrome Frame: the Technical Details'>Google Chrome Frame: the Technical Details</a> <small>Google's Chrome Frame announcement has been surrounded by hype, fabrication,...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/162-javascript-nes.png" width="256" height="256" alt="JSNES" class="imgright" />Today&#8217;s award for the most unlikely, probably pointless, but simply stunning use of JavaScript goes to Ben Firshman and his Nintendo Entertainment System emulator, JSNES.</p>
<p><a href="http://benfirshman.com/projects/jsnes/"><strong>Visit the JSNES page&#8230;</strong></a></p>
<p>The emulator is port of the Java-based <a href="http://www.virtualnes.com/">vNES</a> project. It uses the HTML <code>canvas</code> element for screen rendering (sorry Internet Explorer users) although sound is not supported yet.</p>
<p>There are 17 working games to try. Most will run in Firefox 3.5 or Safari 4, but neither browser offers a playable gaming experience. You&#8217;ll be lucky to achieve 10 frames per second on the highest-specification liquid-nitrogen-cooled ninja PC.</p>
<div id="adz" class="horizontal"></div><p>The real revelation, however, is Google Chrome &#8212; it runs the emulator at full speed (50-60 fps) on a modest PC. Google&#8217;s <code>canvas</code> performance optimization appears to be out-pacing the competition by a considerable margin. Both <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509986">Mozilla</a> and <a href="https://bugs.webkit.org/show_bug.cgi?id=29534">WebKit</a> have raised bugs to investigate why there is such a noticeable speed difference.</p>
<p>Although JSNES is little more than an interesting experiment, it illustrates what can be achieved with modern JavaScript engines, some ingenuity, and lots of caffeine. Ben Firshman &#8212; you are a genius. My only question is &hellip; why?!!</p>
<p>See also: <a href="http://www.sitepoint.com/blogs/2009/10/16/ben-firshman-jsnes-interview/">SitePoint&#8217;s Exclusive Interview With Ben Firshman, Creator of JSNES</a></p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/10/16/ben-firshman-jsnes-interview/' rel='bookmark' title='Permanent Link: Exclusive Interview With Ben Firshman, Creator of JSNES'>Exclusive Interview With Ben Firshman, Creator of JSNES</a> <small>Craig interviews Ben Firshman, developer of the JavaScript-based NES emulator...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/02/07/opera-fights-back-announces-next-gen-javascript-engine/' rel='bookmark' title='Permanent Link: Opera Fights Back: Announces Next Gen JavaScript Engine'>Opera Fights Back: Announces Next Gen JavaScript Engine</a> <small>At one time, Opera had the fastest ECMAScript / JavaScript...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/28/google-chrome-frame-technical-details/' rel='bookmark' title='Permanent Link: Google Chrome Frame: the Technical Details'>Google Chrome Frame: the Technical Details</a> <small>Google's Chrome Frame announcement has been surrounded by hype, fabrication,...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/27/jsnes-javascript-nes-emulator/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Who&#8217;s Using ARIA?</title>
		<link>http://www.sitepoint.com/blogs/2009/09/16/whos-using-aria/</link>
		<comments>http://www.sitepoint.com/blogs/2009/09/16/whos-using-aria/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 06:50:26 +0000</pubDate>
		<dc:creator>brothercake</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>

		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=14171</guid>
		<description><![CDATA[In this post, James discusses the concept of Accessible Rich Internet Applications, and asks "where are the users?"


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/01/15/free-book-giveaway-the-adobe-flash-platform-api-reference/' rel='bookmark' title='Permanent Link: Free Book Giveaway: The Adobe Flash Platform Reference for RIAs'>Free Book Giveaway: The Adobe Flash Platform Reference for RIAs</a> <small>Do you develop Rich Internet Applications (RIAs)? Or want to?...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/22/progressive-enhancement-graceful-degradation-basics/' rel='bookmark' title='Permanent Link: Progressive Enhancement and Graceful Degradation: an Overview'>Progressive Enhancement and Graceful Degradation: an Overview</a> <small>It is possible to create a fantastic-looking Ajax-powered Internet application...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-14172" src="http://www.sitepoint.com/blogs/wp-content/uploads/2009/09/pegs.jpg" alt="A square peg in a round hole" width="200" height="200" /></p>
<p>And I don&#8217;t mean developers, I mean <em>real people</em> — actual users, who are browsing the Web with assistive devices and making use of <a href="http://www.w3.org/WAI/intro/aria"><abbr title="Accessible Rich Internet Application">ARIA</abbr></a> enabled applications?</p>
<p>See, when I first researched the question of accessible Ajax for <a href="http://www.sitepoint.com/books/jsant1/">The JavaScript Anthology</a>, back in 2006, there was no such thing as <abbr title="Accessible Rich Internet Application">ARIA</abbr>; there was only the early draft ideas that would eventually become it, based largely on work done at IBM.</p>
<p>And I was unimpressed. Not because of any specific details, but over the entire concept behind it — the idea that all <abbr title="Rich Internet Applications">RIAs</abbr> needed to make them usable for screenreaders is <strong>more information</strong> seemed naïve.</p>
<div id="adz" class="vertical"></div><p>And now that we have a <a href="http://www.w3.org/TR/wai-aria/">formal specification</a>, with browsers and screenreaders that have working implementations, I ask the same question — are <abbr title="Rich Internet Applications">RIAs</abbr> really appropriate to assistive devices if only they had that role and state information, or are we trying to force a square peg into a round hole? Are we just adding layers of information on top of a paradigm that is fundamentally incompatible with the target devices?</p>
<p>What my question really comes down to is, can any Ajax-based application which requires an <abbr title="Application Programming Interface">API</abbr> to give the consuming device enough information to make sense of it, possibly be better than what we had before — where you submit a form and you get a new page in response — something that generations of devices were well able to comprehend.</p>
<p>I&#8217;m not trying to dredge up my <a href="http://dev.opera.com/articles/view/stop-using-ajax/">stop using Ajax</a> argument again — not at all, I accept that Ajax is here to stay, and welcome it as a valuable addition to the programmer&#8217;s toolkit. But the hype has yet to calm down, and Ajax is still over-used. The question of <strong>to what extent Ajax applications are expected to progressively enhance from static applications</strong> is still very much an issue, as the bulk of the comments in <a title="SitePoint blog post: 5 Reasons Why You Should Not Publish Supported Browser Lists, by Craig Buckler" href="http://www.sitepoint.com/blogs/2009/09/10/5-reasons-to-avoid-supported-browser-lists/">one of Craig&#8217;s recent posts</a> highlighted all too sharply.</p>
<p>So where are the <abbr title="Accessible Rich Internet Application">ARIA</abbr> users? And what do <em>they</em> think?</p>
<p>It&#8217;s an honest question, because I really don&#8217;t know. Is there any information? Have any studies been carried out, that convincingly answer the question of whether <abbr title="Accessible Rich Internet Application">ARIA</abbr> enabled applications are a better user experience for people using assistive technologies, compared with conventional post-and-response style applications, that <abbr title="Rich Internet Applications">RIAs</abbr> should otherwise be  expected to degrade to?</p>
<p>Is <abbr title="Accessible Rich Internet Application">ARIA</abbr> really the way forward, or is it just a solution looking for a problem?</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/01/15/free-book-giveaway-the-adobe-flash-platform-api-reference/' rel='bookmark' title='Permanent Link: Free Book Giveaway: The Adobe Flash Platform Reference for RIAs'>Free Book Giveaway: The Adobe Flash Platform Reference for RIAs</a> <small>Do you develop Rich Internet Applications (RIAs)? Or want to?...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/09/22/progressive-enhancement-graceful-degradation-basics/' rel='bookmark' title='Permanent Link: Progressive Enhancement and Graceful Degradation: an Overview'>Progressive Enhancement and Graceful Degradation: an Overview</a> <small>It is possible to create a fantastic-looking Ajax-powered Internet application...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/16/whos-using-aria/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>How to Write a Cookie-less Session Library for JavaScript</title>
		<link>http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/</link>
		<comments>http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 16:29:26 +0000</pubDate>
		<dc:creator>Craig Buckler</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>
<category>cookies</category><category>javascript</category><category>sessions</category><category>variables</category>
		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13335</guid>
		<description><![CDATA[Craig provides the code for a stand-alone JavaScript session variable handling system that does not require cookies or third-party libraries.


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/' rel='bookmark' title='Permanent Link: Cookie-less Session Variables in JavaScript'>Cookie-less Session Variables in JavaScript</a> <small>Cookies may be delicious, but they can be clumsy if...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/135-javascript-sessions.jpg" width="250" height="250" alt="the (JavaScript) Cookie Monster" class="imgright" />In my previous post, <a href="http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/">Cookie-less Session Variables in JavaScript</a>, we discovered how JavaScript session data could be saved to the window.name property. Today, we create a JavaScript library to exploit this property.</p>
<p><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/index.html"><strong>View the JavaScript session library demonstration page&#8230;</strong></a></p>
<p>The code provides three main methods:</p>
<ul>
<li><strong>Session.set(<em>name</em>, <em>object</em>)</strong> &#8212; store a named session value/object</li>
<li><strong>Session.get(<em>name</em>)</strong> &#8212; retrieve a named session value/object</li>
<li><strong>Session.clear()</strong> &#8212; reset all the session data</li>
</ul>
<div id="adz" class="horizontal"></div><p>Another <strong>Session.dump()</strong> method returns all the JSON-encoded session data. This would normally be used for debugging purposes only.</p>
<p>The JavaScript code is loaded just before the closing <code>body</code> tag. First, we load the JSON library:</p>
<pre><code class="javascript">
&lt;script type=&quot;text/javascript&quot; src=&quot;json-serialization.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>The JSON library provides cross-browser serialization methods that are required by our Session library. For more information, refer to <a href="http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/">Cross-browser JSON Serialization in JavaScript</a>.</p>
<p>The <a href="http://blogs.sitepointstatic.com/examples/tech/js-session/session.js">session.js</a> file is loaded next. This is stand-alone code that can be implemented in any system &#8212; it does not depend on jQuery or any other JavaScript library. Working through the code:</p>
<pre><code class="javascript">
 if (JSON &amp;&amp; JSON.stringify &amp;&amp; JSON.parse) var Session = Session || (function() {

	// window object
	var win = window.top || window;

	// session store
	var store = (win.name ? JSON.parse(win.name) : {});
</code></pre>
<p>The first line defines our Session module. However, it will only be defined if the JSON library has been loaded and there are no other conflicting Session variables or functions.</p>
<p>The second line sets win to &#8216;window.top&#8217;. It is set to &#8216;window&#8217; if that is not available (perhaps if the browser does not support frames).</p>
<p>Next, we define a &#8217;store&#8217; object to hold all our session data. Exisiting JSON-encoded data in the window.name property is parsed but, if that is not available, &#8217;store&#8217; is set to an empty object.</p>
<pre><code class="javascript">
	// save store on page unload
	function Save() {
		win.name = JSON.stringify(store);
	};

	// page unload event
	if (window.addEventListener) window.addEventListener(&quot;unload&quot;, Save, false);
	else if (window.attachEvent) window.attachEvent(&quot;onunload&quot;, Save);
	else window.onunload = Save;
</code></pre>
<p>The private Save() function assigns the serialized the &#8217;store&#8217; object string to the window .name property. The following three lines define a cross-browser event which calls the Save function when the page is unloaded. Your pages can therefore modify the &#8217;store&#8217; as much as necessary, but the heavy work of serializing and saving only occurs at the last possible moment.</p>
<pre><code class="javascript">
	// public methods
	return {

		// set a session variable
		set: function(name, value) {
			store[name] = value;
		},

		// get a session value
		get: function(name) {
			return (store[name] ? store[name] : undefined);
		},

		// clear session
		clear: function() { store = {}; },

		// dump session data
		dump: function() { return JSON.stringify(store); }

	};

 })();
</code></pre>
<p>Finally, we have our four public set, get, clear and dump functions which handle the store object accordingly. The Session.get() method will return a JavaScript &#8216;undefined&#8217; value if a session name can not be found.</p>
<p>I hope you find the code useful. Feel free to use it in your own projects.</p>
<p>Useful resources:</p>
<ul>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/index.html"><strong>JavaScript session variables demonstration page</strong></a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/session.js">Full JavaScript session.js code</a></li>
<li><a href="http://blogs.sitepointstatic.com/examples/tech/js-session/js-session.zip">Download full code in a ZIP file</a></li>
</ul>
<p>See also:</p>
<ul>
<li><a href="http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/">Cookie-less Session Variables in JavaScript</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/">Cross-browser JSON Serialization in JavaScript</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/">How To Develop a jQuery Plugin</a></li>
<li><a href="http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/">How to Build an Auto-Expanding Textarea jQuery Plugin</a></li>
</ul>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=137&amp;did=adz&amp;adtype=horizontal" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/' rel='bookmark' title='Permanent Link: Cookie-less Session Variables in JavaScript'>Cookie-less Session Variables in JavaScript</a> <small>Cookies may be delicious, but they can be clumsy if...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/' rel='bookmark' title='Permanent Link: Google Closure: How not to write JavaScript'>Google Closure: How not to write JavaScript</a> <small>What if Google released a JavaScript library that sucked, and...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cookie-less Session Variables in JavaScript</title>
		<link>http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/</link>
		<comments>http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 17:14:10 +0000</pubDate>
		<dc:creator>Craig Buckler</dc:creator>
				<category><![CDATA[JavaScript & CSS]]></category>

		<guid isPermaLink="false">http://www.sitepoint.com/blogs/?p=13332</guid>
		<description><![CDATA[Cookies may be delicious, but they can be clumsy if you need to store temporary data in a JavaScript application. Craig provides an unlikely alternative...


Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/10/server-side-javascript-will-be-as-common-as-php/' rel='bookmark' title='Permanent Link: Server-side JavaScript Will Be as Common as PHP'>Server-side JavaScript Will Be as Common as PHP</a> <small>Despite the fact that JavaScript has been typecast as the...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://blogs.sitepointstatic.com/images/tech/135-javascript-sessions.jpg" width="250" height="250" alt="the (JavaScript) Cookie Monster" class="imgright" />Cookies may be delicious delicacies, but they can leave a nasty taste if you don&#8217;t cook them correctly! Cookies can be blocked by the user, storage space is limited to four 20Kb cookies per domain, only strings can be used, paths can cause confusion, and the data is normally passed as plain text in the HTTP header. Often, cookies can be overkill for client-side-heavy applications that need to save temporary state data.</p>
<p>Fortunately, there is a solution that allows you to store JavaScript data within the browser. The data is retained between page loads, it&#8217;ll survive page back/next events (even away from the domain), it does not require plugins or off-line storage facilities, it&#8217;ll hold at several megabytes of information, it is never transmitted to the server, and works in every browser. Bizarrely, it works by exploiting the window.name property (or window.top.name if you&#8217;re using multiple frames). </p>
<p>It&#8217;s rare for developers set the window.name property. Generally, it&#8217;s only required when you&#8217;re manipulating frames or pop-up windows. Even though I&#8217;d hope you weren&#8217;t doing that, you do not normally need to define a name for an application&#8217;s starting window. Although the name property is still a string, it can hold several megabytes of data. Some versions of Opera limit it to around 2Mb but most browsers offer 10MB or more.</p>
<p>It&#8217;s easy to try for yourself. Insert the following JavaScript code into a page on your site:</p>
<pre><code class="javascript">
window.name = &quot;This message will survive between page loads.&quot;;
</code></pre>
<p>Now add the following code to any other page:</p>
<div id="adz" class="vertical"></div><pre><code class="javascript">
alert(window.name);
</code></pre>
<p>Navigate from the first page to the second and you&#8217;ll find that the message data is retained.</p>
<p>As normal, there are a number of caveats:</p>
<ol>
<li>The window.name property can be analysed and changed if you navigate to page on another website. That&#8217;s easily thwarted by not providing external links within your application&#8217;s main window. However, to be on the safe side, don&#8217;t use window.name for storing secure data (unlikely to be a major problem for a client-side-only temporary data store).</li>
<li>window.name can only store strings. What if we need to save other data types or even complex objects? Serialization is the answer and, fortunately, we have already developed <a href="http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/">cross-browser code to generate JSON strings from any JavaScript object</a>.</li>
</ol>
<p>See also: <a href="http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/">How to Write a Cookie-less Session Library for JavaScript</a>.</p>
<script src="http://ads.aws.sitepoint.com/adjs.php?region=136&amp;did=adz&amp;adtype=vertical" type="text/javascript"></script>

<p>Related posts:<ol><li><a href='http://www.sitepoint.com/blogs/2009/09/03/javascript-session-variable-library/' rel='bookmark' title='Permanent Link: How to Write a Cookie-less Session Library for JavaScript'>How to Write a Cookie-less Session Library for JavaScript</a> <small>Craig provides the code for a stand-alone JavaScript session variable...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/03/10/server-side-javascript-will-be-as-common-as-php/' rel='bookmark' title='Permanent Link: Server-side JavaScript Will Be as Common as PHP'>Server-side JavaScript Will Be as Common as PHP</a> <small>Despite the fact that JavaScript has been typecast as the...</small></li><li><a href='http://www.sitepoint.com/blogs/2009/08/19/javascript-json-serialization/' rel='bookmark' title='Permanent Link: Cross-browser JSON Serialization in JavaScript'>Cross-browser JSON Serialization in JavaScript</a> <small>JSON serialization can be incredibly useful, but few browsers support...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.sitepoint.com/blogs/2009/09/02/cookieless-javascript-session-variables/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 2.837 seconds -->
<!-- Cached page served by WP-Cache -->
