<?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>The True Tribe &#187; JavaScript</title>
	<atom:link href="http://www.thetruetribe.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thetruetribe.com</link>
	<description>Vroom! That&#039;s us leaving IE in the dust.</description>
	<lastBuildDate>Fri, 22 Jan 2010 23:34:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>iPhone Click Event Delay</title>
		<link>http://www.thetruetribe.com/2010/01/iphone-click-event-delay/</link>
		<comments>http://www.thetruetribe.com/2010/01/iphone-click-event-delay/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 23:34:03 +0000</pubDate>
		<dc:creator>jdempcy</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.thetruetribe.com/?p=300</guid>
		<description><![CDATA[It appears that the iPhone has a built-in delay of about 300ms before firing the click event. This is most likely to give the user time to make a gesture, such as scrolling the page. In some cases, though, this may not be desired. For instance, if you make a mobile web app that doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>It appears that the iPhone has a built-in delay of about 300ms before firing the click event. This is most likely to give the user time to make a gesture, such as scrolling the page. In some cases, though, this may not be desired. For instance, if you make a mobile web app that doesn&#8217;t scroll, there&#8217;s no reason to wait 300ms every time the user clicks.</p>
<p>In these cases, the trick is to <a href="http://cubiq.org/remove-onclick-delay-on-webkit-for-iphone/9">use ontouchstart instead of onclick</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.thetruetribe.com%2F2010%2F01%2Fiphone-click-event-delay%2F&amp;linkname=iPhone%20Click%20Event%20Delay"><img src="http://www.thetruetribe.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.thetruetribe.com/2010/01/iphone-click-event-delay/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Image Rotator Viewer</title>
		<link>http://www.thetruetribe.com/2008/06/javascript-image-rotator-viewer/</link>
		<comments>http://www.thetruetribe.com/2008/06/javascript-image-rotator-viewer/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 06:01:00 +0000</pubDate>
		<dc:creator>grandecomplex</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://wordpress.thetruetribe.com/?p=42</guid>
		<description><![CDATA[Here is an image gallery written in JavaScript without the use of frameworks. It's an image rotator with functions to start and stop rotation, as well as actions when the user clicks a thumbnail.]]></description>
			<content:encoded><![CDATA[<p><a href="See a demo at http://www.alexgrande.com">See a demo at http://www.alexgrande.com</a></p>
<p>It is the images on the top right.</p>
<p>I wrote this in Object Oriented format so you can use it again and again on the same page.</p>
<p>Javascript:</p>
<pre class="js">var ImageGallery = new Function();

ImageGallery.prototype = {
 initialize: function(mainImage, listWrapper){
  // large image that is shown
  this.mainImage = document.getElementById(mainImage);
  // a list of all the anchors for the thumbnails. Must be a tags for graceful degradation
  this.thumbnails = document.getElementById(listWrapper).getElementsByTagName("a");
  // 0 image is shown already so the first one we want to switch to is the next image or 1
  this.i = 1;
  // this is a work around to allow calling this within nested functions
  var Scope = this;
  // Here starts the rotating of the image by first focusing the thumbnail, then switch the primary image
  this.start = setInterval(function(){
   Scope.focusCall();
  // Here we choose 5 seconds in between each image change. You may want to change this.
  }, 5000);
  // This lets the browser know to do something if one of the thumbnails is clicked
  this.clickEvent();
 },

 // This stops the rotation of the thumbnails. We do that if the user clicks one of them
 stop: function(){
  if (this.start)
   clearInterval(this.start);
 },

 // When an thumbnail loses focus we must use this css class now
 resetBorderColor: function(reset){
  reset.getElementsByTagName("img")[0].className="thumbnailDefault";
 },

 // When the thumbnail gains focus we most give it the corresponding styles
 focusBorderColor: function(focused){
  focused.getElementsByTagName("img")[0].className="thumbnailFocus";
 },

 // Here we grab the href of the a tags and make their path be the path of the current image
 imageRotator: function(){
  this.mainImage.src = this.thumbnails[this.i].href;
  this.previousImage = this.thumbnails[this.i];
  this.i++;
  // This closes the loop for the rotation
  if (this.i == this.thumbnails.length)
   this.i = 0;
 },

 // We focus the thumbnail
 focusCall: function(){
  // reset the last image that was shown
  if (typeof this.previousImage != 'undefined')
   this.resetBorderColor(this.previousImage);
  // Remember the newer one
  this.currentImage = this.thumbnails[this.i];
  // Give the newer image some focus
  this.focusBorderColor(this.currentImage);
  var Scope = this;
  // Les that have image rotate to the new one 300 miliseconds after the thumbnails get the css focus
  window.setTimeout(function(){
   Scope.imageRotator()
  // You may want to change this number
  }, 300);

 },

 // This is what happens when you click the thumbnails
 clickEvent: function(){
  var Scope = this;
  for (k = 0; k &lt; this.thumbnails.length; k++) {
   this.thumbnails[k].onclick = function(){
    if (typeof Scope.previousImage != 'undefined')
     Scope.resetBorderColor(Scope.previousImage);
    Scope.focusBorderColor(this);
    // Stop the rotation
    Scope.stop();
    // This is where the switching happens for the click
    Scope.mainImage.src = this.href;
    Scope.previousImage = this;
    // Make sure to not allow default behavior of the a tag
    return false;
   }
  }
 }

}</pre>
<p>This is to load it on the window object and create an instance of the viewer</p>
<pre class="js">var imageGallery1 = new ImageGallery();

// Not sure where I got this.. I didn't write this but it allows you to load multiple functions on the window.onload.
function addLoadEvent(func) {
 var oldonload = window.onload;
 if (typeof window.onload != "function") {
  window.onload = func;
 } else {
  window.onload = function() {
   oldonload();
   func();
  }
 }
}

var onLoad = function() {
 imageGallery1.initialize("index_largepic_display", "index_thumbnail_display");
}

addLoadEvent(onLoad);</pre>
<p>For the version on my homepage alexgrande.com here is the CSS and HTML. The CSS is up to you but I suggest following a similar mode with the HTML</p>
<p>HTML:</p>
<pre class="html">&lt;div id="gallery"&gt;
     &lt;ul id="index_thumbnail_display"&gt;
        &lt;li&gt;
   &lt;a href="images/index/fernlarge.jpg" &gt;
  &lt;img class="thumbnailDefault" src="images/index/fernthumb.jpg" alt="A picture of a fern just as it is unraveling in front of a log." /&gt;
   &lt;/a&gt;
 &lt;/li&gt;

        &lt;li&gt;
   &lt;a id="partythumb" href="images/index/partylarge.jpg" &gt;
      &lt;img class="thumbnailDefault" src="images/index/partythumb.jpg" alt="Downtown Seattle at night." /&gt;
   &lt;/a&gt;
 &lt;/li&gt;

        &lt;li&gt;
   &lt;a id="alexthumb" href="images/index/alexlarge.jpg" &gt;
      &lt;img class="thumbnailDefault" src="images/index/alexthumb.jpg" alt="I'm on a laptop at night in a field on using the internet via hacking a telephone box...legally." /&gt;
   &lt;/a&gt;
 &lt;/li&gt;
        &lt;li&gt;
   &lt;a href="images/index/trucks.jpg" &gt;
     &lt;img class="thumbnailDefault" alt="Trucks lined up in Sodo in Seattle at night." src="images/index/trucksthumb.jpg" /&gt;
   &lt;/a&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
      &lt;img id="index_largepic_display" src="images/index/fernlarge.jpg" alt="A picture of a fern just as it is unraveling in front of a log." /&gt;
&lt;/div&gt;</pre>
<p>CSS:</p>
<pre class="css">div#gallery {
 position:relative;
 float: left;
 overflow: hidden;
 width: 65%;
}

img#index_image_display {
 border:1px black solid;
 margin-bottom:20px;
}

ul#index_thumbnail_display {
 list-style-type:none;
 position:absolute;
 top: 0;
 left: 0;
 margin-top: 15px;
}

ul#index_thumbnail_display li a {
 padding:10px;
}

.thumbnailDefault {border: 1px solid gray !important;}

.thumbnailFocus {border: 1px solid red !important;}</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.thetruetribe.com%2F2008%2F06%2Fjavascript-image-rotator-viewer%2F&amp;linkname=JavaScript%20Image%20Rotator%20Viewer"><img src="http://www.thetruetribe.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.thetruetribe.com/2008/06/javascript-image-rotator-viewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Saving State: What To Do When Users Leave</title>
		<link>http://www.thetruetribe.com/2008/06/saving-state-what-to-do-when-users-leave/</link>
		<comments>http://www.thetruetribe.com/2008/06/saving-state-what-to-do-when-users-leave/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 06:10:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://wordpress.thetruetribe.com/?p=41</guid>
		<description><![CDATA[In this era of rich JavaScript applications, so much
focus is given to the features of the application that one
crucial element is often overlooked: What happens when the
user leaves the page? We take it for granted that pages
will look the same when we leave and return, but a new
question merges for sites using rich JavaScript
interaction: If [...]]]></description>
			<content:encoded><![CDATA[<p>In this era of rich JavaScript applications, so much<br />
focus is given to the features of the application that one<br />
crucial element is often overlooked: What happens when the<br />
user leaves the page? We take it for granted that pages<br />
will look the same when we leave and return, but a new<br />
question merges for sites using rich JavaScript<br />
interaction: If the user leaves and returns to the page,<br />
will the application state be preserved?<span id="more-41"></span></p>
<p>The effects of losing application state can range from<br />
minor annoyances like losing what page you&#8217;re on, to<br />
all-out frustration after losing a carefully-typed message<br />
because you accidentally triggered the browser&#8217;s back<br />
button. (It&#8217;s easier than you think&#8211; hitting backspace<br />
when the document is in focus triggers the back button in<br />
most browsers). Couple this with the fact that some users<br />
may expect pages to save form data, because of their prior<br />
experience to that effect, and it becomes apparent that a<br />
robust strategy for preserving application state must be<br />
devised.</p>
<p>Browsers automatically save data entered into form<br />
fields, but all JavaScript variables are lost when the user<br />
leaves the page. Furthermore, any form fields that were<br />
created by JavaScript will also be lost. So, for all but<br />
the most simple applications, JavaScript must have a<br />
strategy for saving state that deals with these<br />
limitations.</p>
<p>Some sites like <a href="&lt;br"></a> &#8220;http://www.thesixtyone.com&#8221;&gt;<em>thesixtyone.com</em><br />
reside entirely on a single page and capture users&#8217; back<br />
button clicks with named anchors. But, try writing a wall<br />
post on Facebook and you&#8217;ll find that it does not save the<br />
post if you leave the page. Accidentally pressing backspace<br />
is all too easy in cases like this where typing is<br />
involved, which is why sites like Gmail and Blogger warn<br />
users that they will lose data before leaving the page.</p>
<h3>How To Warn Users Before Leaving the Page</h3>
<p>One way you can do this is by assigning a confirmation<br />
message to the return value of the<br />
<em>window.onbeforeunload</em> event handler. The user will<br />
be presented with two choices, <em>OK</em> and<br />
<em>Cancel</em>, along with a custom message of your<br />
choosing.</p>
<p>In the following example, we regsiter an anonymous<br />
function as the event handler for<br />
<em>window.onbeforeunload</em>, and add our own custom<br />
message:</p>
<h5>Using <em>window.onbeforeunload</em> to confirm if a<br />
user wants to leave the page (<a href="&lt;br"></a> &#8220;/examples/saving-state/example-1.html&#8221;&gt;example 1)</h5>
<pre class="js:nocontrols">window.onbeforeunload = function() {
  return "You will lose any unsaved information.";
};</pre>
<p>The browser displays your custom message, given in the<br />
return statement of the <em>onbeforeunload</em> event<br />
handler, along with the browser default message. In<br />
Firefox, the result is:</p>
<blockquote><p>Are you sure you want to navigate away from this<br />
page?<br />
You will lose any unsaved information.<br />
Press OK to continue, or Cancel to stay on the current<br />
page.</p></blockquote>
<h3>Retaining Data When Users Do Leave the Page</h3>
<p>You may opt to silently save the user&#8217;s data when they<br />
leave the page. This may give a better user experience<br />
since they are not confronted with a choice, and their data<br />
is saved automatically.</p>
<p>This is one of the times where Ajax comes in handy.<br />
However, there are also other ways to do this without using<br />
Ajax, such as cleverly storing information in named anchors<br />
or hidden form fields. We&#8217;ll examine each of these<br />
practices in more depth, but suffice it to say that the<br />
hidden form fields approach works better for conventional<br />
websites that are spread across many pages, whereas storing<br />
data in named anchors is better for single-page, pure<br />
JavaScript applications.</p>
<p>It turns out that while you could (and should) save<br />
state to the server using Ajax, for some cases you will<br />
want to avoid Ajax altogether and use a simpler,<br />
clientside-only model.</p>
<h3>Using Hidden Form Fields to Save State</h3>
<p>As mentioned, all JavaScript objects are lost when the<br />
user leaves or refreshes the page. But, browsers will<br />
retain data in form fields, provided that the form elements<br />
were not generated using JavaScript. Given this limitation,<br />
it is necessary to save JavaScript variables (or the<br />
serialized JSON strings of such objects) to hidden form<br />
fields if they need to be retained.</p>
<p>Here is a basic example showing how variables can be<br />
stored to hidden form fields and restored on page load:</p>
<pre class="html:nocontrols">
<input id="saved-data" type="hidden" /></pre>
<h5>Saving data in hidden form fields (<a href="&lt;br"></a> &#8220;/examples/saving-state/example-2.html&#8221;&gt;example 2)</h5>
<pre class="js:nocontrols">// The variable userData is some necessary information we need from the user.
// The first time the user visits the page, they must enter this data manually.
// But, when leaving and returning to the page (or refreshing the page), we'll check
// if they already entered the data, and if so, restore it from a hidden form field.

var userData;

// Register event handlers
window.onload = function() {
 restoreState();
 if (!userData) {
    userData = prompt('Please enter the data to save', 'test');
 }
 document.write("userData: " + userData);
}

window.onbeforeunload = saveState;

// This function is called onbeforeunload and writes the userData to the hidden form field
function saveState() {
   document.getElementById('saved-data').value = userData;
}

// This function is called onload and checks if any data is present in the hidden form field
// If so, it defines userData to be the saved data
function restoreState() {
   var savedData = document.getElementById('saved-data').value;
   if (savedData != "") {
        userData = savedData;
   }
}</pre>
<p>In the above example, all we&#8217;re saving is one string<br />
from the user. But what about cases where we need to save<br />
many different values? For instance, what if we&#8217;re using<br />
object-oriented code and have numerous nested objects<br />
within objects we need to store? At times like this,<br />
<strong>serializing objects with JSON</strong> is the<br />
easiest way to store the data. Without using JSON, you&#8217;d<br />
have to create a hidden form field for each value you want<br />
to save, whereas JSON can create string representations of<br />
complex data structures that you can easily <em>eval</em><br />
back into JavaScript objects once they&#8217;re fetched from the<br />
DOM.</p>
<h3>So What is JSON, Anyway?</h3>
<p>JSON (pronounced &#8220;Jason&#8221;), short for <em>JavaScript<br />
Object Notation</em> is a lightweight, human- and<br />
machine-readable way to represent the string serializations<br />
of objects. These strings can be evaluated back into<br />
JavaScript objects as needed. For instance, say I create a<br />
JavaScript object to represent a person (in this case,<br />
me):</p>
<pre class="js:nocontrols">var person = new Object();
person.name = "Jonah";
person.age = 24;
person.gender = "male";
person.location = "Seattle, WA";</pre>
<p>The JSON representation of this object is as<br />
follows:</p>
<pre class="js:nocontrols">{
    'person': {
        'name': 'Jonah',
        'age': 24,
        'gender': 'male',
        'location': 'Seattle, WA'
    }
}</pre>
<p>Then, if you need to reconstruct the object at a later<br />
point, you can simply eval the JSON string:</p>
<pre class="js:nocontrols">var jsonString = "{'person': {'name': 'Jonah', 'age': 24, 'gender': 'male', 'location': 'Seattle, WA'}}";
var person = eval( '(' + jsonString + ')' );    

console.assert(person.name == 'Jonah');
console.assert(person.age == 24);
console.assert(person.gender == 'male');
console.assert(person.location == 'Seattle, WA');</pre>
<p>If you&#8217;ve written JavaScript using object literal syntax<br />
before, this should be familiar to you. The only minor<br />
difference between JSON and the standard JavaScript object<br />
literal syntax is that JSON requires quotes around key in a<br />
key/value pair. So, <em>name</em> is a valid JavaScript key<br />
but in JSON it would have to be <em>&#8216;name&#8217;</em>. (Note: It<br />
doesn&#8217;t matter if you use single- or double-quotes, as long<br />
as they are matched).</p>
<h3>Stringifying Objects in JSON</h3>
<p>To use JSON, it&#8217;s necessary to include a library of JSON<br />
methods. Don&#8217;t worry, the library is quite small. The<br />
entire thing shouldn&#8217;t be more than 2k and can be obtained<br />
from <a href="http://www.json.org/js.html">json.org</a>.<br />
Eventually, the JSON methods will be included as part of<br />
the core JavaScript language, but for the time being, we&#8217;re<br />
left to use the methods provided by json.org or those found<br />
in libraries such as MooTools, Prototype and jQuery.</p>
<p>Depending on the library used, the method names for<br />
serializing an object into a JSON string are different.<br />
But, they are all used in rather similar fashion. For now,<br />
we&#8217;ll assume you&#8217;re using the library from <a href="&lt;br"></a> &#8220;http://www.json.org/js.html&#8221;&gt;json.org and use the<br />
method names provided in its API.</p>
<h5>Saving complex JavaScript data structures as JSON<br />
strings (<a href="/examples/saving-state/example-3.html">example 3</a>)</h5>
<pre class="js">// The variable userData is some necessary information we need from the user.
// The first time the user visits the page, they must enter this data manually.
// But, when leaving and returning to the page (or refreshing the page), we'll check
// if they already entered the data, and if so, restore it from a hidden form field.

var userData;

// Register event handlers
window.onload = function() {
 restoreState();
 if (!userData) {
    userData = new Object();
    userData.name = prompt('Please enter a name', 'Jonah');
    userData.age = parseInt(prompt('Please enter an age', '24'));
    userData.gender = prompt('Please enter a gender', 'male');
    userData.location = prompt('Please enter a location', 'Seattle, WA');
 }
 displayData(userData);
}

window.onbeforeunload = saveState;

// This function is called onbeforeunload and writes the userData to the hidden form field
function saveState() {
   document.getElementById('saved-data').value = JSON.stringify(userData);
}

// This function is called onload and checks if any data is present in the hidden form field
// If so, it defines userData to be the saved data
function restoreState() {
   var savedData = document.getElementById('saved-data').value;
   if (savedData != "") {
        userData = eval( '(' + savedData + ')' );
   }
}

// This is a helper function that iterates through each property in an object and renders it in HTML.
function displayData(obj) {
 var list = document.createElement('ul');
 for (var property in obj) {
    var text = document.createTextNode(property + ': ' + obj[property])
     var line = document.createElement('li');
     line.appendChild(text);
     list.appendChild(line);
 }
 document.getElementsByTagName('body')[0].appendChild(list);
}</pre>
<p>This example is pretty similar to the previous one where<br />
we saved a string. The only difference is that in this<br />
case, the string is a representation of a complex<br />
JavaScript object. In fact, you can save the entire state<br />
of your application in one JSON string, as long as the<br />
application state is completely stored as properties of a<br />
single object. There are a few minor gotchas, such as<br />
having to add parentheses around the JSON string when<br />
evaluating it. But, overall this is a clean and<br />
straightforward approach that is very useful when complex<br />
data structures must be retained.</p>
<h3>Using Named Anchors to Save State</h3>
<p>An alternate option for retaining state is to not<br />
actually let the user leave the page at all. Rather, when<br />
following links on the site, update the named anchor<br />
(everything after the number sign in a URL), instead of<br />
changing the actual document being displayed.</p>
<p>The problem that this is trying to solve is the fact<br />
that Ajax applications will normally break the back button.<br />
A user loads the application on the homepage and clicks to<br />
visit a different page, but since the new page is loaded in<br />
via Ajax, the browser URL doesn&#8217;t change. Then the user<br />
clicks the back button and leaves the application<br />
altogether&#8211; not the intention of the user, who just wanted<br />
to get back to the homepage.</p>
<p>Storing data in named anchors offers a solution to this<br />
problem. Each time the application state changes,<br />
JavaScript updates the named anchor with a token<br />
representing the application state. When the page is<br />
loaded, data is read from the named anchors and the state<br />
can be restored.</p>
<p>Say you&#8217;re on the homepage of an ecommerce Ajax<br />
application and click on a product you&#8217;d like to view.<br />
Instead of changing URLs to the detail page, the<br />
application loads in new data with Ajax. So, when a user<br />
clicks on the new Brad Mehldau CD for instance, instead of<br />
going to a different URL (yoursite.com/brad-mehldau/) the<br />
document URL remains the same, but JavaScript updates the<br />
named anchor: yoursite.com/#brad-mehldau.</p>
<p>One site which does this unbelievably well is <a href="&lt;br"></a> &#8220;http://www.thesixtyone.com&#8221;&gt;<em>thesixtyone.com</em><br />
(Thanks, Derek!). The entire site resides in one document,<br />
truly a rich JavaScript application if I&#8217;ve ever seen one.<br />
But, despite the fact that the entire application is<br />
contained in a single document URL, due to clever use of<br />
named anchors, the site has full back button support and<br />
you can even email working links to friends.</p>
<p>Implementing code to save state in named anchors is out<br />
of scope for this article, but you can see how it is<br />
somewhat similar to saving data in hidden form fields. In<br />
this case, there are a few more issues to mitigate and it&#8217;s<br />
somewhat tricky, but the reward is an Ajax site with fully<br />
functional back button support and the ability to share<br />
links &#8212; worth all the effort, in my book.</p>
<h3>So What Use is Ajax, Then?</h3>
<p>Since we&#8217;ve made it this far, you might think that there<br />
is no use for Ajax in all this. Actually, Ajax is great for<br />
saving state to the server, especially for saving data<br />
beyond the lifespan of the browser session. Ajax can be<br />
used to save messages periodically (like how Gmail and<br />
Google Docs automatically save on a timer every few<br />
minutes). It can also be used to send data when the user<br />
leaves the page by capturing the <em>onbeforeunload</em><br />
event, but this is unreliable and I would not depend on<br />
this Ajax request to complete. Instead, try to save the<br />
data before the user attempts to leave the page, by either<br />
firing the Ajax request on a timer or another event on the<br />
page (leaving focus on a form element, for example).</p>
<p>Some frameworks like Prototype have serialize() methods<br />
that return URL query string representations of objects.<br />
This is perfect for saving data through GET requests. Yes,<br />
GET requests have a 2000-character limit and other<br />
limitations, but in most cases this won&#8217;t be an issue. Even<br />
without helper methods to serialize objects, it&#8217;s a fairly<br />
simple matter to construct an Ajax request that will save<br />
the necessary data to the server.</p>
<h3>Wrapping Up</h3>
<p>To re-cap, it is a good practice to check if users are<br />
sure they want to leave a page when they are entering<br />
information, but it&#8217;s even better to silently save that<br />
information for them. (Arguably you would want to do both,<br />
like how Gmail and Blogger save state <em>and</em> ask<br />
users if they are sure they want to leave the page). There<br />
are many different ways to save state, some purely<br />
client-side and others relying on saving data to the server<br />
with Ajax. The solutions which save data to the server are<br />
suitable for times when the data needs to be saved beyond<br />
the browsing session.</p>
<p>Of the two client-side solutions explored, hidden form<br />
fields and named anchors, the former is more suitable for<br />
conventional websites spanning many pages while the latter<br />
better suits single-page Ajax applications. Using named<br />
anchors also has the added benefit of allowing users to<br />
bookmark and send links to the JavaScript application in<br />
various states, and the state is preserved beyond the<br />
browsing session.</p>
<p>Whatever strategy you follow, your users will thank you<br />
for the time saved and frustration avoided of having to<br />
re-enter lost information.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.thetruetribe.com%2F2008%2F06%2Fsaving-state-what-to-do-when-users-leave%2F&amp;linkname=Saving%20State%3A%20What%20To%20Do%20When%20Users%20Leave"><img src="http://www.thetruetribe.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.thetruetribe.com/2008/06/saving-state-what-to-do-when-users-leave/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Recursive Functions in JavaScript</title>
		<link>http://www.thetruetribe.com/2008/05/recursive-functions-in-javascript/</link>
		<comments>http://www.thetruetribe.com/2008/05/recursive-functions-in-javascript/#comments</comments>
		<pubDate>Wed, 14 May 2008 11:06:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[recursive]]></category>

		<guid isPermaLink="false">http://wordpress.thetruetribe.com/?p=28</guid>
		<description><![CDATA[Recursive functions are functions which conditionally call themselves. A common use for recursive functions is anywhere you need to iterate on data, where you would normally use a for() or while() loop.
I can&#8217;t say that I&#8217;ve used much recursion in production code, but it&#8217;s a fun topic to write about, as there are plenty of [...]]]></description>
			<content:encoded><![CDATA[<p>Recursive functions are functions which conditionally call themselves. A common use for recursive functions is anywhere you need to iterate on data, where you would normally use a <span style="font-style:italic;">for()</span> or <span style="font-style:italic;">while()</span> loop.<span id="more-28"></span></p>
<p>I can&#8217;t say that I&#8217;ve used much recursion in production code, but it&#8217;s a fun topic to write about, as there are plenty of fun uses of recursion to explore.</p>
<p>Let&#8217;s start with a basic use of recursion, and replace a <span style="font-style:italic;">for()</span> loop with a recursive function. In this case, we&#8217;ll implement a simple function to reverse a string, first using iteration and then recursion.</p>
<pre class="js:nocontrols">// Iterative
function reverseString(str) {
    var rev = new String();
    for (var i = str.length - 1; i &gt;= 0; i--) {
        rev += str[i];
    }
    return rev;
}

console.log(reverseString('test')); // Logs 'tset'</pre>
<pre class="js:nocontrols">// Recursive
function reverseString(str) {
    var firstLetter = str.charAt(0);

    function iterate(str) {
        if (str.charAt(str.length-1) != firstLetter) {
            var charToReverse = str.charAt(str.length-1);
            str.charAt(str.length-1) = '';
            return iterate(charToReverse + str);
        }
    }
    return iterate(str);
}

console.log(reverseString('test')); // Logs 'tset'</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.thetruetribe.com%2F2008%2F05%2Frecursive-functions-in-javascript%2F&amp;linkname=Recursive%20Functions%20in%20JavaScript"><img src="http://www.thetruetribe.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.thetruetribe.com/2008/05/recursive-functions-in-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IE Plugin to Detect JavaScript Memory Leaks</title>
		<link>http://www.thetruetribe.com/2008/04/ie-plugin-to-detect-javascript-memory-leaks/</link>
		<comments>http://www.thetruetribe.com/2008/04/ie-plugin-to-detect-javascript-memory-leaks/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 02:44:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://wordpress.thetruetribe.com/?p=16</guid>
		<description><![CDATA[
Microsoft has released a free beta version of a plugin for Internet Explorer that looks for memory leaks. The plugin, plainly titled JavaScript Memory Leak Detector (download), is available immediately and tests for both IE6 and IE7 leaks. Apparently, IE6 has far more leaks &#8212; any time when you have a circular reference between DOM [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>Microsoft has released a free beta version of a plugin for Internet Explorer that looks for memory leaks. The plugin, plainly titled <em>JavaScript Memory Leak Detector</em> <em><em>(</em><a title="download installer" href="http://www.mseurojobs.members.winisp.net/JSLeaksDetector.msi.zip"><em>download</em></a></em><em>)</em>, is available immediately and tests for both IE6 and IE7 leaks.<span id="more-16"></span> Apparently, IE6 has far more leaks &#8212; any time when you have a circular reference between DOM objects and JavaScript objects a leak would occur.</p>
<p>Why are leaks a problem? Because the RAM leaked by a page will remain in use until the browser is closed. For developers of websites with heavy JavaScript usage, memory leaks can be a nightmare. I once worked on a site that would climb to hundreds of megabytes after a few pages of data loaded in through Ajax. Then, the RAM would continue to stay in use until I closed and restarted the browser.</p>
<p><a href="http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector.aspx">Excerpt from the article &#8220;JavaScript Memory Leak Detector&#8221;</a></p>
<blockquote><p><img src="http://blogs.msdn.com/photos/gpdepix/images/7108452/original.aspx" alt="" /></p>
<p>The IE team has been working hard to solve the problem. With the initial versions of Internet Explorer 6 practically all circular references between Javascript and DOM objects caused a memory leak.</p></blockquote>
<p>It seems than an update to IE6 alleviated this problem somewhat, but there are probably still many users who haven&#8217;t upgraded, and even the later versions of IE6 and current versions of IE7 still have problems. Most of the problems are caused by closures, which really shouldn&#8217;t be an issue, as Firefox, Opera and Safari generally handle them fine. I use closures all the time in my code so I shudder to think of what leaks lie beneath. But, I&#8217;m about to download this leak detector and give it a try. From the screenshots, it doesn&#8217;t look too appealing, but I&#8217;m curious to find what it will detect on the past few sites I&#8217;ve made.</p></div>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.thetruetribe.com%2F2008%2F04%2Fie-plugin-to-detect-javascript-memory-leaks%2F&amp;linkname=IE%20Plugin%20to%20Detect%20JavaScript%20Memory%20Leaks"><img src="http://www.thetruetribe.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.thetruetribe.com/2008/04/ie-plugin-to-detect-javascript-memory-leaks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firebug Tutorial: Getting Started</title>
		<link>http://www.thetruetribe.com/2008/03/firebug-tutorial-getting-started/</link>
		<comments>http://www.thetruetribe.com/2008/03/firebug-tutorial-getting-started/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 12:58:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://wordpress.thetruetribe.com/?p=3</guid>
		<description><![CDATA[Firebug is a plugin for Firefox that greatly aids CSS and JavaScript debugging. This guide will walk you through installing Firebug and using some of its functionality, including debugging JavaScript, inspecting the DOM and editing CSS on the fly.

Getting Started
First, make sure you&#8217;re running Firefox. If you aren&#8217;t, get Firefox now. You won&#8217;t be disappointed. [...]]]></description>
			<content:encoded><![CDATA[<p>Firebug is a plugin for Firefox that greatly aids CSS and JavaScript debugging. This guide will walk you through installing Firebug and using some of its functionality, including<span style="font-weight: bold;"> debugging JavaScript</span>, inspecting the DOM and<span style="font-weight: bold;"> editing CSS on the fly.<span id="more-3"></span><br />
</span></p>
<h4>Getting Started</h4>
<p>First, make sure you&#8217;re running Firefox. If you aren&#8217;t, <a title="Firefox really is the best browser." href="http://www.getfirefox.com/">get Firefox</a> now. You won&#8217;t be disappointed. Next, <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">install Firebug</a> by following the link and clicking &#8220;Install Now.&#8221; After installing, restart Firefox and continue.</p>
<p>Now you can click the small icon in the bottom right corner of the Firefox window to open Firebug. Go ahead and open it&#8211; the first time running, you may have to choose to enable it for sites on the world wide web.</p>
<p><a href="http://www.thetruetribe.com/uploaded_images/html1-770907.gif" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor: pointer;" src="http://www.thetruetribe.com/uploaded_images/html1-770892.gif" border="0" alt="" /></a></p>
<h4>Using the Console</h4>
<p>The first tab that&#8217;s open in Firebug is the console. The console tab shows JavaScript error messages, as well as having a command line interface (CLI) where you can enter JavaScript and execute it in real time.</p>
<p><a style="margin: 10px 0pt 10px 10px; float: right;" href="http://www.getfirebug.com/cl.html"><img class="miniscreen" src="http://www.getfirebug.com/screenHome-cl.gif" alt="" /></a>Using the CLI, you can call functions, define variables, or even write new functions.</p>
<p>The JavaScript error messages are are also helpful for debugging since they show you which line the error occurred on, as well as a <a href="http://en.wikipedia.org/wiki/Stack_trace">stack trace</a>.</p>
<p>Another interesting feature is the ability to <span style="font-weight: bold;">log messages to the console </span>by using the method <span style="font-style: italic;">console.log()</span>. Note that this will throw an error in browsers which don&#8217;t have Firebug installed, so it&#8217;s just for development purposes.</p>
<p>Logging messages can be very useful when debugging complex JavaScript applications that have a lot of moving parts. It can also be used for page profiling. Here&#8217;s an example of how you might use logging to the console to add some <span style="font-weight: bold;">rudimentary speed profiling</span> of a JavaScript function:</p>
<pre class="js:nocontrols">function doStuff() {
var startTime = new Date().getTime(); // The current time in epoch milliseconds

// Add code here to be profiled

var endTime = new Date().getTime() - startTime;
console.log("The function doStuff() took " + endTime + " milliseconds to complete.");
}</pre>
<p>This would result in a message being logged to the console with the amount of milliseconds it took for that code to execute. Nothing fancy, but it gets the job done!</p>
<h4>DOM Inspection</h4>
<p>Clicking the next tab over in Firebug, to <span style="font-style: italic;">HTML</span>, you&#8217;ll find a two-paned window that allows you to browse the DOM on the left and edit CSS on the right.</p>
<p>Start opening HTML tags and mousing over them. You&#8217;ll notice that the HTML element on the screen lights up when you hover over the tag. It&#8217;s a nice feature that lets you quickly orient yourself in the code.</p>
<p>The highlighted area also shows how much space an element is taking up on the screen. The color blue denotes the element&#8217;s <span style="font-style: italic;">height</span> and <span style="font-style: italic;">width</span>, while yellow is <span style="font-style: italic;">margin</span> and purple is <span style="font-style: italic;">padding</span>.</p>
<p>Clicking the <span style="font-style: italic;">Inspect</span> button (next to the bug icon in the top left corner of Firebug) will toggle a mode where you can click on HTML elements on the screen and it will go to that tag in the code.</p>
<p>There&#8217;s another tab for DOM inspection, the aptly-named <span style="font-style: italic;">DOM</span> tab. Here you will find all of the DOM objects created by JavaScript, such as <span style="font-weight: bold;">variables and functions</span>, as well as the <span style="font-weight: bold;">core DOM API</span> (for example, the <span style="font-style: italic;">window</span> and <span style="font-style: italic;">document</span> objects can be inspected here).</p>
<p>I check this page when I want to view the current state of the page and watch it change as JavaScript executes. For example, say I have a variable that keeps track of how many items are in a shopping cart. I could watch this variable in the <span style="font-style: italic;">DOM</span> tab to make sure that it&#8217;s incremented when I add an item to the cart.</p>
<h4>Editing CSS on the Fly</h4>
<p>Going back to the <span style="font-style: italic;">HTML</span> tab, notice that the pane on the right shows CSS styles for whichever element is currently selected. You can choose an element in the left pane (or by clicking <span style="font-style: italic;">Inspect</span> and then clicking the element), and the CSS styles for that element will be displayed. Furthermore, you can edit the properties and even add new ones.</p>
<p>Firebug has a different take on CSS editing than some other debugging programs, namely the <span style="font-weight: bold;">Microsoft Web Developer Toolbar</span>, so I&#8217;ll clarify how it works: In Firebug, when you change a CSS style, it updates it for every element on the page. Conversely, in Microsoft Web Developer Toolbar, changing CSS styles only affects the currently selected element.</p>
<p>By way of example, say you have the CSS rule <span style="font-style: italic;">p {padding: 10px;}</span>. You then select a P tag and change it to <span style="font-style: italic;">padding: 20px</span>;<span style="font-style: italic;"> </span>using Firebug<span style="font-style: italic;">. </span>The result is that every P tag will now have 20px padding, unlike other programs where it would only affect the styles of the selected tag.</p>
<p>To add a new style, simply click twice in the whitespace inside of a style block, next to the existing declarations. Firebug even has a convenient auto-complete feature for writing CSS.</p>
<p>In the right page, there are three tabs: <span style="font-style: italic;">Style, Layout </span>and <span style="font-style: italic;">DOM</span>. So far, we&#8217;ve been editing CSS in the <span style="font-style: italic;">Style</span> tab, but make sure to check out the other two as well. The <span style="font-style: italic;">Layout</span> tab offers an alternate view of the box model for the selected element, along with pixel-precise measurements of its dimensions. The <span style="font-style: italic;">DOM</span> tab shows all properties and methods for that element.</p>
<h4>Page Profiling and Network Metrics</h4>
<p><a style="margin: 10px 10px 10px 0pt; float: left;" href="http://www.getfirebug.com/net.html"><img class="miniscreen" src="http://www.getfirebug.com/screenHome-net.gif" alt="" /></a>Nothing&#8217;s worse than making a great site only to have it suffer from poor front end performance. (OK, well, a lot of things are worse &#8212; but it&#8217;s still frustrating!). The Firebug <span style="font-style: italic;">Net</span> profiler can help get to the source of that slowness.</p>
<p>Although it is far from robust, the <span style="font-style: italic;">Net </span>tab offers semi-reliable metrics on the download speed of all assets including the HTML document, CSS, JavaScript, images and any other linked files.</p>
<p>You can see which files are being downloaded concurrently and which are blocking (hint: it&#8217;s the JavaScript), and how many connections are being opened with a given domain.</p>
<p>For more extensive page profiling, be sure to check out <a href="http://developer.yahoo.com/yslow/"><span style="font-style: italic;">YSlow</span>!</a>, a plugin for Firebug  (I guess that makes it an extension-of-an-extension) developed by Yahoo.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.thetruetribe.com%2F2008%2F03%2Ffirebug-tutorial-getting-started%2F&amp;linkname=Firebug%20Tutorial%3A%20Getting%20Started"><img src="http://www.thetruetribe.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.thetruetribe.com/2008/03/firebug-tutorial-getting-started/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
