<?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>All Geekness Great and Small &#187; Javascript</title>
	<atom:link href="http://www.danrumney.co.uk/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.danrumney.co.uk</link>
	<description>Technology from work and home</description>
	<lastBuildDate>Mon, 12 Dec 2011 01:52:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Making your tweets ReTweetable</title>
		<link>http://www.danrumney.co.uk/2010/03/02/making-your-tweets-retweetable/</link>
		<comments>http://www.danrumney.co.uk/2010/03/02/making-your-tweets-retweetable/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 22:57:32 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=310</guid>
		<description><![CDATA[We all know, by now, that Twitter limits its tweets to 140 characters. We&#8217;ve all got pretty good at limiting ourselves to 140 characters, but many overlook a hidden limit. This post outlines what that is and how we can avoid it. Many users of Twitters are hoping that their followers will retweet (RT) their [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Twitter and Greasemonkey" src="http://danrumney.co.uk/images/tweetMonkey.jpg" alt="" width="510" height="156" /></p>
<p>We all know, by now, that Twitter limits its tweets to 140 characters. We&#8217;ve all got pretty good at limiting ourselves to 140 characters, but many overlook a hidden limit. This post outlines what that is and how we can avoid it.</p>
<p>Many users of Twitters are hoping that their followers will retweet (RT) their tweets. Twitter recently made a change to how these work, but in general, the following pattern is followed:</p>
<pre>   UserXYZ tweets: Hey... here's something that's fascinating
   UserABC tweets: RT @UserXYZ: Hey... here's something that's fascinating</pre>
<p>User XYZ&#8217;s tweet was 42 characters. UserABC&#8217;s RT was 52 characters, i.e. 10 characters were added in order to RT.</p>
<p>Put another way, if UserXYZ creates a tweet that was longer than 130 characters, nobody would be able to RT it with modifying the original tweet. If you&#8217;re trying to get a specific message out to the world, you might not be happy with lots of people fiddling with it.</p>
<p>I&#8217;ve created a new Greasemonkey script which will help you with this. I&#8217;ve written about Greasemonkey plugins <a href="http://www.danrumney.co.uk/2009/02/15/augmenting-twitter-whoami/">before</a> and this is another Twitter helper. If you install the script, you will see the following change:</p>
<p style="text-align: center;"><a href="http://www.danrumney.co.uk/blog/wp-content/uploads/2010/03/retweetable_screenshot.png"><img class="aligncenter size-full wp-image-311" title="retweetable_screenshot" src="http://www.danrumney.co.uk/blog/wp-content/uploads/2010/03/retweetable_screenshot.png" alt="" width="600" height="160" /></a></p>
<p style="text-align: left;">You can now see, next to the normal character countdown, a bracketed countdown. This is the number of characters that you have left, before a tweet can no longer be RTed without modification. In this example, you would be able to send the tweet (as you have 6 characters left), but Twitter users would have to remove 8 characters before they could RT your Tweet.</p>
<p style="text-align: left;">To use this, it&#8217;s simple:</p>
<ol>
<li>If you haven&#8217;t already, install <a href="https://addons.mozilla.org/en-US/firefox/addon/748">Greasemonkey</a></li>
<li>Install the <a href="http://danrumney.co.uk/gmScripts/reTweetable.user.js">ReTweetable Alert</a> script</li>
</ol>
<p>That&#8217;s it! As ever, your questions and comments are most welcome</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2010/03/02/making-your-tweets-retweetable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SEO concerns regarding Rotating Banners</title>
		<link>http://www.danrumney.co.uk/2009/11/12/seo-concerns-regarding-rotating-banners/</link>
		<comments>http://www.danrumney.co.uk/2009/11/12/seo-concerns-regarding-rotating-banners/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 19:37:57 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=279</guid>
		<description><![CDATA[I recently wrote about a script designed to generate Rotating Banners. The script works fine, but using JavaScript to present a user with links creates a few problems of its own: Google Analytics will not be able to track these external links (if, for instance, you&#8217;re using my Google Analytics for external links) Non-visual User [...]]]></description>
			<content:encoded><![CDATA[<p>I recently wrote about <a href="http://www.danrumney.co.uk/2009/11/09/rotating-banners-in-random-order/">a script designed to generate Rotating Banners</a>. The script works fine, but using JavaScript to present a user with links creates a few problems of its own:</p>
<ul>
<li>Google Analytics will not be able to track these external links (if, for instance, you&#8217;re using my <a href="http://www.danrumney.co.uk/2009/06/21/enabling-external-links-for-google-analytics/">Google Analytics for external links</a>)</li>
<li>Non-visual User Agents will not be able to access these links</li>
<li>As a subset, Google will not be able to crawl these links and so associate your site with the sites those banners point to.</li>
</ul>
<p><span id="more-279"></span><br />
The way to resolve this is to use the method of graceful degradation or, perhaps more appropriately, progressive enhancement. By this, I mean, the HTML should be written such that the above issues are avoided, and then the JavaScript should be written to provide the Rotating Banners functionality.</p>
<p>Using the Rotating Banners script as a starting point, the obvious approach is to dispense with the JSON representation of our banners and replace it with an HTML representation of our banners. This will be hidden using CSS. Much of the functionality will otherwise remain the same. By representing the links in the HTML document, webcrawlers (such as Google&#8217;s indexing service) will be able to parse these links and use them accordingly. In addition, Google Analytics (if installed on your site) can track exits from your site, via these banners.</p>
<p>I have created a <strong>new</strong> object which extends the original Rotating Banners object, such that it doesn&#8217;t cause SEO problems. In order to use this object, you need to include the original object in your HTML, as well as this one.</p>
<p>The new object is shown below:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
* SEO Safe Rotating Banner
*
* Specialized version of Rotating Banner
* @author dancrumb
*/</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/*global rotatingBanner,$ */</span> 
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> seoSafeRotatingBanner <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>spec<span style="color: #339933;">,</span> secrets<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> prvItems <span style="color: #339933;">=</span> secrets <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> that <span style="color: #339933;">=</span> rotatingBanner<span style="color: #009900;">&#40;</span>spec<span style="color: #339933;">,</span> prvItems<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	spec.<span style="color: #660066;">banners</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	prvItems.<span style="color: #660066;">rotate</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006600; font-style: italic;">// This should only be executed if initialization is complete</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>prvItems.<span style="color: #660066;">intialized</span><span style="color: #009900;">&#41;</span>	<span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #003366; font-weight: bold;">var</span> newBanner <span style="color: #339933;">=</span> prvItems.<span style="color: #660066;">nextBanner</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span> <span style="color: #339933;">+</span> spec.<span style="color: #660066;">divId</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'display'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'none'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span> <span style="color: #339933;">+</span> newBanner.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> imgBanner <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'img'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.
			<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'src'</span><span style="color: #339933;">,</span> newBanner.<span style="color: #660066;">src</span><span style="color: #009900;">&#41;</span>.
			<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'height'</span><span style="color: #339933;">,</span> spec.<span style="color: #660066;">height</span><span style="color: #009900;">&#41;</span>.
			<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'width'</span><span style="color: #339933;">,</span> spec.<span style="color: #660066;">width</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span> <span style="color: #339933;">+</span> newBanner.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>imgBanner<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span> <span style="color: #339933;">+</span> newBanner.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'display'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'inline'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		prvItems.<span style="color: #660066;">cacheNextImage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">return</span> newBanner<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	prvItems.<span style="color: #660066;">initialize</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> bannerDiv<span style="color: #339933;">;</span>
		bannerDiv <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span> <span style="color: #339933;">+</span> spec.<span style="color: #660066;">divId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>bannerDiv.<span style="color: #660066;">length</span> <span style="color: #339933;">===</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>	<span style="color: #009900;">&#123;</span>
			<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Please provide the ID of an element on the page&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div#'</span> <span style="color: #339933;">+</span> spec.<span style="color: #660066;">divId</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> aElem <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #006600; font-style: italic;">// Ensure that there is an ID defined, for future manipulation</span>
&nbsp;
			<span style="color: #003366; font-weight: bold;">var</span> a_id <span style="color: #339933;">=</span> aElem.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>a_id <span style="color: #339933;">===</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				a_id <span style="color: #339933;">=</span> <span style="color: #3366CC;">'rb_auto_id_'</span> <span style="color: #339933;">+</span> i<span style="color: #339933;">;</span>
				aElem.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span> a_id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// Ensure that there is a target defined, and set it to the defaultTarget</span>
			<span style="color: #006600; font-style: italic;">// if not</span>
			<span style="color: #003366; font-weight: bold;">var</span> tgt <span style="color: #339933;">=</span> aElem.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'target'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>tgt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				tgt <span style="color: #339933;">=</span> spec.<span style="color: #660066;">defaultTarget</span><span style="color: #339933;">;</span>
				aElem.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'target'</span><span style="color: #339933;">,</span> tgt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// Ensure that the banner is hidden</span>
			aElem.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'display'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'none'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// Add the banner to the rotater</span>
			that.<span style="color: #660066;">addBanner</span><span style="color: #009900;">&#40;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #3366CC;">&quot;src&quot;</span><span style="color: #339933;">:</span> aElem.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
					<span style="color: #3366CC;">&quot;id&quot;</span><span style="color: #339933;">:</span> a_id
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		that.<span style="color: #660066;">randomizeBanners</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		prvItems.<span style="color: #660066;">intialized</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		prvItems.<span style="color: #660066;">rotate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div#'</span> <span style="color: #339933;">+</span> spec.<span style="color: #660066;">divId</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'display'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">return</span> that<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This file can be downloaded <a href="http://www.danrumney.co.uk/js/seoSafeRotatingBanner.js">here</a>.<br />
All that is necessary is to override the &#8216;initialize&#8217; and &#8216;rotate&#8217; methods.</p>
<p>Using this object on your page is just as straightforward as before. As before, you need to include the jQuery library. You also need to include the original rotatingBanners script, as well as this one. The initialization code is slightly different:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> rB <span style="color: #339933;">=</span> seoSafeRotatingBanner<span style="color: #009900;">&#40;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;width&quot;</span><span style="color: #339933;">:</span>  <span style="color: #CC0000;">600</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;height&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">400</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;interval&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">5000</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;divId&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;bannerHere&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;defaultTarget&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;blank&quot;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
rB.<span style="color: #660066;">startRotation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The final ingredient is the list of links itself. This is provided in HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;bannerHere&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display:none;&quot;</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;banner1&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;link1&quot;</span>&gt;</span>/image_location/img_src_1.jpg<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;banner2&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;link1&quot;</span> <span style="color: #000066;">target</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blank&quot;</span>&gt;</span>../img_src_2.png<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;banner3&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;link1&quot;</span> <span style="color: #000066;">target</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;some_target&quot;</span>&gt;</span>img_src3.gif<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></pre></div></div>

<p>Note that the URLs to the images are just plain text. They are <strong>not</strong> <code>IMG</code> tags.</p>
<p>You must ensure that the style of the enclosing DIV contains &#8216;<code>display:none</code>&#8216; (per line 1) or your list of links will be visible to the user.</p>
<p>At this point, you will have your rotating banners, without sacrificing your SEO performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/11/12/seo-concerns-regarding-rotating-banners/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rotating Banners in random order</title>
		<link>http://www.danrumney.co.uk/2009/11/09/rotating-banners-in-random-order/</link>
		<comments>http://www.danrumney.co.uk/2009/11/09/rotating-banners-in-random-order/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 00:38:59 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=273</guid>
		<description><![CDATA[I was recently sent a script designed to take a series of advertising banners and rotate them on a page. By &#8216;rotate&#8217;, I mean display on banner in a designated position and then, after a certain period of time, replace it with another, and then another, and so on. To be fair to those who [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently sent a script designed to take a series of advertising banners and rotate them on a page. By &#8216;rotate&#8217;, I mean display on banner in a designated position and then, after a certain period of time, replace it with another, and then another, and so on. To be fair to those who paid for the banners, each banner was chosen at random so that each new visitor to the site would see a different banner first, second, third, etc. After taking a look at it, I spotted some problems and decided to fix them.<br />
<span id="more-273"></span></p>
<p>The main problem with the script is that it was <strong>too</strong> random. It took an array, or list, of banners and, on each rotation, it would select a random position in this list. The problem with this becomes obvious when you look at some examples of random number selections. The output from the following (Perl) script:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$idx</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">20</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$idx</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066;">print</span> <span style="color: #000066;">int</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$idx</span><span style="color: #339933;">--;</span>
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;,&quot;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$idx</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>is</p>
<p>0,1,2,0,3,0,3,3,3,3,0,3,0,1,1,1,0,4,4,2,4</p>
<p>If each number represents a specific banner, you can see that there is a significant bias toward 3 in this set of 20 rotations. This is not indicating an inherent bias towards 3. Quite the opposite; this is truly random, but human perception detects a bias because our sample is relatively low.</p>
<p>Leaving the statistics behind, it is quite easy to ensure that the order of banner rotation is random, but every banner gets equal time. All you have to do is to randomize the order of your list of banners when the page loads, and then cycle through them. On each page load, the order is random, but once a page is loaded, the order remains static.</p>
<p>With that in mind, I wrote a JavaScript object to provide the necessary function. I&#8217;ve been writing JavaScript for some time, but I recently bought <a title="JavaScript: The Good Parts" href="http://oreilly.com/catalog/9780596517748" target="_blank">&#8216;JavaScript: The Good Parts&#8217; by <em>Douglas Crockford</em></a>. Crockford has been writing JavaScript for a long time now and has some strong opinions on the language. I for one applaud this book, although I&#8217;m not wholly sold on some of his beliefs. That said, I decided to take a crack at creating an object based on his writings. I&#8217;m not overly convinced that the code I&#8217;ve written is superior to anything else I would have written, but I&#8217;m willing to take the blame for any failings in my code here:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
 * @author dancrumb
 */</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/*global $ */</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> rotatingBanner <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>spec<span style="color: #339933;">,</span> secrets<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
 <span style="color: #006600; font-style: italic;">// Private</span>
 <span style="color: #003366; font-weight: bold;">var</span> that <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 prvItems <span style="color: #339933;">=</span> secrets <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 prvItems.<span style="color: #660066;">workingList</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">cached</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">timeoutId</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">intialized</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
 prvItems.<span style="color: #660066;">nextBanner</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #003366; font-weight: bold;">var</span> banner <span style="color: #339933;">=</span> prvItems.<span style="color: #660066;">workingList</span>.<span style="color: #660066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">workingList</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>banner<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">return</span> banner<span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 prvItems.<span style="color: #660066;">rotate</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #006600; font-style: italic;">// This should only be executed if initialization is complete</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>prvItems.<span style="color: #660066;">intialized</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #003366; font-weight: bold;">var</span> newBanner <span style="color: #339933;">=</span> prvItems.<span style="color: #660066;">nextBanner</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>spec.<span style="color: #660066;">divId</span><span style="color: #339933;">+</span><span style="color: #3366CC;">' a img'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'src'</span><span style="color: #339933;">,</span>newBanner.<span style="color: #660066;">src</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>spec.<span style="color: #660066;">divId</span><span style="color: #339933;">+</span><span style="color: #3366CC;">' a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #339933;">,</span>newBanner.<span style="color: #660066;">href</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>spec.<span style="color: #660066;">divId</span><span style="color: #339933;">+</span><span style="color: #3366CC;">' a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'target'</span><span style="color: #339933;">,</span>newBanner.<span style="color: #660066;">target</span> <span style="color: #339933;">||</span> spec.<span style="color: #660066;">defaultTarget</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 prvItems.<span style="color: #660066;">cacheNextImage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #000066; font-weight: bold;">return</span> newBanner<span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 prvItems.<span style="color: #660066;">initialize</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #003366; font-weight: bold;">var</span> bannerDiv<span style="color: #339933;">,</span>
 eImg<span style="color: #339933;">,</span>
 eA<span style="color: #339933;">;</span>
 bannerDiv <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>spec.<span style="color: #660066;">divId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>bannerDiv.<span style="color: #660066;">length</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Please provide the ID of an element on the page&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
&nbsp;
 bannerDiv.<span style="color: #660066;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 eImg <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;img&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.
 <span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'height'</span><span style="color: #339933;">,</span>spec.<span style="color: #660066;">height</span><span style="color: #009900;">&#41;</span>.
 <span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'width'</span><span style="color: #339933;">,</span>spec.<span style="color: #660066;">width</span><span style="color: #009900;">&#41;</span>.
 <span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'bannerImage'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 eA <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.
 <span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 eA.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>eImg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 bannerDiv.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>eA<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                
&nbsp;
 that.<span style="color: #660066;">randomizeBanners</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">intialized</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">rotate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #006600; font-style: italic;">/*
 * Place the next Banner Image into the browser cache
 */</span>
 prvItems.<span style="color: #660066;">cacheNextImage</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #003366; font-weight: bold;">var</span> upcomingBanner <span style="color: #339933;">=</span> prvItems.<span style="color: #660066;">workingList</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
 cacheImage<span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>prvItems.<span style="color: #660066;">cached</span><span style="color: #009900;">&#91;</span>upcomingBanner.<span style="color: #660066;">src</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 cacheImage <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Image<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 cacheImage.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> upcomingBanner.<span style="color: #660066;">src</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">cached</span><span style="color: #009900;">&#91;</span>upcomingBanner.<span style="color: #660066;">src</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #006600; font-style: italic;">/*
 * Ensure we, at least, have an array of banners
 */</span>
 <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>
 spec.<span style="color: #660066;">banners</span> <span style="color: #339933;">&amp;&amp;</span>
 <span style="color: #000066; font-weight: bold;">typeof</span> spec.<span style="color: #660066;">banners</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'object'</span> <span style="color: #339933;">&amp;&amp;</span>
 <span style="color: #000066; font-weight: bold;">typeof</span> spec.<span style="color: #660066;">banners</span>.<span style="color: #660066;">length</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'number'</span> <span style="color: #339933;">&amp;&amp;</span>
 <span style="color: #000066; font-weight: bold;">typeof</span> spec.<span style="color: #660066;">banners</span>.<span style="color: #660066;">splice</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span> <span style="color: #339933;">&amp;&amp;</span>
 <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>spec.<span style="color: #660066;">banners</span>.<span style="color: #660066;">propertyIsEnumerable</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'length'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 spec.<span style="color: #660066;">banners</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
&nbsp;
 <span style="color: #006600; font-style: italic;">/*
 * Confirm that the interval is sensibly set
 */</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> spec.<span style="color: #660066;">interval</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'number'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span>
 <span style="color: #009900;">&#40;</span>isFinite<span style="color: #009900;">&#40;</span>spec.<span style="color: #660066;">interval</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span>
 <span style="color: #009900;">&#40;</span>spec.<span style="color: #660066;">interval</span> <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 spec.<span style="color: #660066;">interval</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1000</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
&nbsp;
 <span style="color: #006600; font-style: italic;">// Public</span>
 that.<span style="color: #660066;">randomizeBanners</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #006600; font-style: italic;">// We shouldn't fiddle with knownBanners directly as this</span>
 <span style="color: #006600; font-style: italic;">// is our master list of banners</span>
 <span style="color: #003366; font-weight: bold;">var</span> holdingCopy <span style="color: #339933;">=</span> spec.<span style="color: #660066;">banners</span>.<span style="color: #660066;">slice</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
 index<span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prvItems.<span style="color: #660066;">timeoutId</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 clearTimeout<span style="color: #009900;">&#40;</span>prvItems.<span style="color: #660066;">timeoutId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 prvItems.<span style="color: #660066;">workingList</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #006600; font-style: italic;">// Randomize the order of the holding copy of known banners and put it</span>
 <span style="color: #006600; font-style: italic;">// into the working list</span>
 <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>holdingCopy.<span style="color: #660066;">length</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 index <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>holdingCopy.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 prvItems.<span style="color: #660066;">workingList</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>holdingCopy<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 holdingCopy.<span style="color: #660066;">splice</span><span style="color: #009900;">&#40;</span>index<span style="color: #339933;">,</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>        
&nbsp;
 <span style="color: #006600; font-style: italic;">// If we cancelled the rotation, we restart it here</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prvItems.<span style="color: #660066;">timeoutId</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 that.<span style="color: #660066;">startRotation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 that.<span style="color: #660066;">startRotation</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 prvItems.<span style="color: #660066;">timeoutId</span> <span style="color: #339933;">=</span> setInterval<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
 prvItems.<span style="color: #660066;">rotate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>spec.<span style="color: #660066;">interval</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 that.<span style="color: #660066;">addBanner</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>banner<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 spec.<span style="color: #660066;">banners</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>banner<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">randomizeBanners</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
 that.<span style="color: #660066;">setInterval</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>interval<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prvItems.<span style="color: #660066;">timeoutId</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 clearTimeout<span style="color: #009900;">&#40;</span>prvItems.<span style="color: #660066;">timeoutId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
 spec.<span style="color: #660066;">interval</span> <span style="color: #339933;">=</span> interval<span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prvItems.<span style="color: #660066;">timeoutId</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#123;</span>
 that.<span style="color: #660066;">startRotation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#125;</span>
&nbsp;
 $<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> prvItems.<span style="color: #660066;">initialize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #000066; font-weight: bold;">return</span> that<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can download this script <a href="http://www.danrumney.co.uk/js/rotatingBanner.js" alt="Rotating Banners script">here</a></p>
<p>The code above relies on jQuery, so naturally, you would need to include that library first in any HTML page that uses this object.</p>
<p>Invoking this code is straightforward. Your webpage will need a DIV with a defined ID attribute; in this case we use <em>bannerHere</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> rB <span style="color: #339933;">=</span> rotatingBanner<span style="color: #009900;">&#40;</span>
 <span style="color: #009900;">&#123;</span>
 <span style="color: #3366CC;">&quot;width&quot;</span><span style="color: #339933;">:</span>  <span style="color: #CC0000;">600</span><span style="color: #339933;">,</span>
 <span style="color: #3366CC;">&quot;height&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">400</span><span style="color: #339933;">,</span>
 <span style="color: #3366CC;">&quot;banners&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
 <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;src&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'fake1'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'fake1'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;src&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'fake2'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'fake2'</span><span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
 <span style="color: #3366CC;">&quot;interval&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">2000</span><span style="color: #339933;">,</span>
 <span style="color: #3366CC;">&quot;divId&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;bannerHere&quot;</span><span style="color: #339933;">,</span>
 <span style="color: #3366CC;">&quot;defaultTarget&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;blank&quot;</span>
 <span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 rB.<span style="color: #660066;">startRotation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>width</em> and <em>height</em> are the desired dimensions for the banners<br />
<em>interval</em> is the time (in ms) between each rotation<br />
<em>defaultTarget</em> is the desired value for the TARGET attribute of the banner link<br />
<em>banners</em> is a JavaScript array of JavaScript objects with the following fields:</p>
<p><em>src</em> is the SRC of the banner image<br />
<em>href</em> is the HREF of the banner link<br />
<em>target</em> is the <strong>optional</strong> target for the banner link</p>
<p>The code is based on Crockford&#8217;s belief that we should not pretend the JavaScript is a class-based language. It isn&#8217;t, it&#8217;s a prototype-based language. This means that new objects are created from a &#8216;template&#8217; object or from a factory method, which generates new object. Again, I&#8217;ll repeat that my implementation is quite probably not the best example of this and I&#8217;m not sure that I prefer this code to a class-based approach, but it works and it&#8217;ll do for now.</p>
<p>There are some SEO concerns with this implementation, but I&#8217;m going to save them for an upcoming post. For now, the code about should be enough for you to implement rotating banners on your website</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/11/09/rotating-banners-in-random-order/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Enabling external links for Google Analytics</title>
		<link>http://www.danrumney.co.uk/2009/06/21/enabling-external-links-for-google-analytics/</link>
		<comments>http://www.danrumney.co.uk/2009/06/21/enabling-external-links-for-google-analytics/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 00:36:35 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[google analytics]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=240</guid>
		<description><![CDATA[Tracking external links with Google Analytics is a great way to work out and why how people are leaving your site. This post describes a method for automatically tracking external links in a way that degrades gracefully in the absence of Javascript. Google Analytics works by having you install a small Javascript on each page. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.danrumney.co.uk/blog/wp-content/uploads/2009/06/googleAnalyticsLogo1.jpg"><img class="aligncenter size-full wp-image-243" title="googleAnalyticsLogo" src="http://www.danrumney.co.uk/blog/wp-content/uploads/2009/06/googleAnalyticsLogo1.jpg" alt="googleAnalyticsLogo" width="350" height="59" /></a></p>
<p>Tracking external links with Google Analytics is a great way to work out and why how people are leaving your site. This post describes a method for automatically tracking external links in a way that degrades gracefully in the absence of Javascript.<br />
<span id="more-240"></span><br />
Google Analytics works by having you install a small Javascript on each page. This script tracks a number of things, including the <strong>referrer</strong>. The referrer is the page that the user as <em>just</em> on. If this was an <em>external </em>page, then Google Analytics registers this as a traffic source. If this was an <em>internal</em> page, then Google analytics registers this as well. When you&#8217;re analyzing your site statistics, Google Analytics will be able to show which internal links were clicked on any given page.</p>
<p>However, because Google Analytics relies on the page that you&#8217;re clicking <em>to</em>, in order to track information, you need to do something extra in order to track clicks on external links. Remember, when you leave your site, Google Analytics isn&#8217;t going to be able to track that normally.</p>
<p>The Google Analytics <a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=72712">documentation</a> for this explains what you need to do. You need to add an onClick event handler to your external links. The problem is, the method that they recommend doesn&#8217;t degrade very nicely if your visitor doesn&#8217;t have Javascript running. In addition, it requires yo to add this code to <strong>every</strong> external link.</p>
<p>I&#8217;ve written a script which will set up all of your external links to be tracked with Google Analytics and include it here for your use. I&#8217;ve stripped out a lot of the comments from the code below, but the actual file has plenty of comments in it. It can be found <a href="http://www.danrumney.co.uk/js/EnableGA.js">here</a>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> EnableGA<span style="color: #009900;">&#40;</span>tracker<span style="color: #339933;">,</span>mappings<span style="color: #339933;">,</span>trackUnknownLinks<span style="color: #339933;">,</span>testing<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tracker</span> <span style="color: #339933;">=</span> tracker<span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">mappings</span> <span style="color: #339933;">=</span> mappings<span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">trackUnknown</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>trackUnknownLinks<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;undefined&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>trackUnknownLinks<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">testing</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>testing<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;undefined&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>testing<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">parseOptions</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
		key<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;source&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;protocol&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;authority&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;userInfo&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;user&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;password&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;host&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;port&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;relative&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;path&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;directory&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;file&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;query&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;anchor&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
		q<span style="color: #339933;">:</span>   <span style="color: #009900;">&#123;</span>
			<span style="color: #000066;">name</span><span style="color: #339933;">:</span>   <span style="color: #3366CC;">&quot;queryKey&quot;</span><span style="color: #339933;">,</span>
			parser<span style="color: #339933;">:</span> <span style="color: #009966; font-style: italic;">/(?:^|&amp;amp;)([^&amp;amp;=]*)=?([^&amp;amp;]*)/g</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
		parser<span style="color: #339933;">:</span> <span style="color: #009966; font-style: italic;">/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> oThis <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    $<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>oThis.<span style="color: #660066;">enable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/*
 * enable
 *
 * Enables GA tracking of external links
 */</span>
EnableGA.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">enable</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">tracker</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">testing</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> oThis <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
		$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;a&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> target <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>target <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span>target <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> URL <span style="color: #339933;">=</span> oThis.<span style="color: #660066;">parseUri</span><span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>URL.<span style="color: #660066;">host</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>URL.<span style="color: #660066;">host</span>.<span style="color: #660066;">search</span><span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">location</span>.<span style="color: #660066;">hostname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;=</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #006600; font-style: italic;">// Do nothing. Google Analytics already tracks local files</span>
				<span style="color: #009900;">&#125;</span>
				<span style="color: #000066; font-weight: bold;">else</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #003366; font-weight: bold;">var</span> pseudoLoc <span style="color: #339933;">=</span> oThis.<span style="color: #660066;">getPseudoLoc</span><span style="color: #009900;">&#40;</span>URL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>pseudoLoc<span style="color: #009900;">&#41;</span>
					<span style="color: #009900;">&#123;</span>
						$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span>
						<span style="color: #009900;">&#123;</span>
							<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>oThis.<span style="color: #660066;">testing</span><span style="color: #009900;">&#41;</span>
							<span style="color: #009900;">&#123;</span>
								<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>console<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>console.<span style="color: #660066;">log</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
								<span style="color: #009900;">&#123;</span>
									console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>pseudoLoc<span style="color: #009900;">&#41;</span>
								<span style="color: #009900;">&#125;</span>
								<span style="color: #000066; font-weight: bold;">else</span>
								<span style="color: #009900;">&#123;</span>
									<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>pseudoLoc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
								<span style="color: #009900;">&#125;</span>
								evt.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
							<span style="color: #009900;">&#125;</span>
							<span style="color: #000066; font-weight: bold;">else</span>
							<span style="color: #009900;">&#123;</span>
								pageTracker._trackPageview<span style="color: #009900;">&#40;</span>pseudoLoc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
							<span style="color: #009900;">&#125;</span>
						<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/*
 * getPseudoLoc
 *
 * Gets a pseudo-location for the purposes of GA tracking for the provided
 * URL of an external link
 */</span>
EnableGA.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">getPseudoLoc</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> response <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">trackUnknown</span><span style="color: #339933;">?</span><span style="color: #3366CC;">&quot;/UNK/&quot;</span><span style="color: #339933;">+</span><span style="color: #009900;">&#91;</span>url.<span style="color: #660066;">host</span><span style="color: #339933;">,</span>url.<span style="color: #660066;">directory</span><span style="color: #339933;">,</span>url.<span style="color: #660066;">file</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
	jQuery.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">mappings</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>plDir<span style="color: #339933;">,</span>regExp<span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>regExp.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>url.<span style="color: #660066;">host</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>url.<span style="color: #660066;">path</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>url.<span style="color: #660066;">path</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span>url.<span style="color: #660066;">file</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
					<span style="color: #009900;">&#123;</span>
						response <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;/&quot;</span><span style="color: #339933;">+</span>plDir<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;/root&quot;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
					<span style="color: #000066; font-weight: bold;">else</span>
					<span style="color: #009900;">&#123;</span>
						response <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;/&quot;</span><span style="color: #339933;">+</span>plDir<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;/&quot;</span><span style="color: #339933;">+</span><span style="color: #009900;">&#91;</span>url.<span style="color: #660066;">directory</span><span style="color: #339933;">,</span>url.<span style="color: #660066;">file</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">return</span> response<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/*
 * parseURI
 *
 * Takes a URI and splits it into its constituent parts
 */</span>
EnableGA.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">parseUri</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span>	o   <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">parseOptions</span><span style="color: #339933;">,</span>
		m   <span style="color: #339933;">=</span> o.<span style="color: #660066;">parser</span>.<span style="color: #660066;">exec</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		uri <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
		i   <span style="color: #339933;">=</span> <span style="color: #CC0000;">14</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span> uri<span style="color: #009900;">&#91;</span>o.<span style="color: #660066;">key</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> m<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	uri<span style="color: #009900;">&#91;</span>o.<span style="color: #660066;">q</span>.<span style="color: #000066;">name</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
	uri<span style="color: #009900;">&#91;</span>o.<span style="color: #660066;">key</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">12</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">q</span>.<span style="color: #660066;">parser</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>$0<span style="color: #339933;">,</span> $1<span style="color: #339933;">,</span> $2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$1<span style="color: #009900;">&#41;</span> uri<span style="color: #009900;">&#91;</span>o.<span style="color: #660066;">q</span>.<span style="color: #000066;">name</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>$1<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $2<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">return</span> uri<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>In order to demonstrate how this works, I&#8217;ve created a very <a href="http://www.danrumney.co.uk/examples/EnableGADemo.html">bare bones demonstration</a>. This will show you how the script is used and how it bahaves in &#8216;testing&#8217; mode.</p>
<p>If you have any questions or comments, feel free to leave a comment below and I&#8217;ll address them as soon as I can</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/06/21/enabling-external-links-for-google-analytics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Global Tweeting about the Pre</title>
		<link>http://www.danrumney.co.uk/2009/03/03/global-tweeting-about-the-pre/</link>
		<comments>http://www.danrumney.co.uk/2009/03/03/global-tweeting-about-the-pre/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 23:55:44 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[preDevCamp]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=157</guid>
		<description><![CDATA[The other day, the preDevCamp team published our &#8216;PreView&#8217; map at http://predevcamp.org/preView.html. In this post, I&#8217;ll talk about how it was put together. PreView is a combination of the Google Maps API and the Twitter API. Without wanting to shatter the mystique, I&#8217;m going to outline how I set about creating PreView. First, take a [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Twitter around the globe" src="http://dancrumb.com/images/twitterGlobe.jpg" alt="" width="357" height="357" /></p>
<p>The other day, the preDevCamp team published our &#8216;PreView&#8217; map at <a href="http://predevcamp.org/preView.html">http://predevcamp.org/preView.html</a>. In this post, I&#8217;ll talk about how it was put together.</p>
<p>PreView is a combination of the Google Maps API and the Twitter API. Without wanting to shatter the mystique, I&#8217;m going to outline how I set about creating PreView.<br />
<span id="more-157"></span></p>
<p>First, take a look at the HTML in <a href="http://predevcamp.org/preView.html">preView.html</a>. When you strip out the preDevCamp menu and Twitter Bird, you&#8217;re left with:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>preView - Global Twitter interest in preDevCamp, Palm Pre and webOS<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/css/preView.css&quot;</span> &gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://maps.google.com/maps?file=api&amp;amp;v=2.x&amp;amp;key=xxxxxxxx&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://gmaps-utility-library.googlecode.com/svn/trunk/markermanager/release/src/markermanager_packed.js&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/jQuery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/tweetList.js&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/preView.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tweetAPI&quot;</span>&gt;</span>Checking Twitter API<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;preViewMap&quot;</span>&gt;</span>Loading Google Map<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>As you can see, the BODY of the page is exceptionally simple; just two DIVs with ids set and some basic content. All the hard work is done by the Javascript in the HEAD of the page. So how does it all work? The &#8216;preView.js&#8217; script creates an object called PreView which pulls together jQuery, Google Maps and Twitter.</p>
<h2>jQuery</h2>
<p><a href="http://jquery.com/">jQuery</a> is a library that extends the Javascript language and makes it easier to perform Web 2.0 functionality in a way that works independent of your users&#8217; browsers. You can find good tutorials on jQuery all over the Internet and the docs are pretty good too, with lots of examples. One thing that I discovered the hard way is that your CSS links <strong>must</strong> appear before loading jQuery or else you can find you have problems when you try to access CSS properties in later code. For the life of me, I can&#8217;t figure out why this is so, but that&#8217;s how it works.</p>
<p>Other people might say Prototype or YUI. I haven&#8217;t used either of those, so I can&#8217;t comment, but I will be learning Prototype soon, since it underpins a lot of the <a href="http://www.danrumney.co.uk/2009/02/18/what-have-we-learned-about-webos/">webOS</a> language.</p>
<h2>Google Maps</h2>
<p>The next step is to create your map. I used the <a href="http://code.google.com/apis/maps/">Google Maps API</a> for this. To access the API, you need to get a key from Google. This allows them to track how people are using their API and who is making requests. Your API key is associated with a specific domain, so for preDevCamp, we need 3 keys; one for &#8216;.com&#8217;, one for &#8216;.org&#8217; and one for &#8216;.net&#8217;.</p>
<p>In addition to pulling in the Google Maps API, we used the Marker Manager for handling all of those little Palm Pres dotted over the map. The Marker Manager improves performance of map panning by only drawing the Pres that are currently visible. As preDevCamp grows, we&#8217;re going to have more and more Pres on the map, so this will get more an more important.</p>
<p>Once the API is loaded, you have access to all of the Google Maps commands. The API documentation is the best place to go to understand what each object does, but here&#8217;s a breakdown of what PreView does:</p>
<ol>
<li>Locate the destination DIV for the Google Map</li>
<li>Create the GMap2 object and associate it with this DIV</li>
<li>Add a small Zoom control</li>
<li>Centre the map on 50n,0E. This is in the English channel, directly south of London. There&#8217;s no great geographical significance of this point, but it makes for a map that feels reasonably centered, with regard to land masses.</li>
<li>Set the map to a Physical map instead of a Satellite Image map</li>
<li>Create a new Marker Manager and associate it with the map</li>
<li>Make a JSONP call to the preDevCamp website requesting the location of all the preDevCamps. This returns an array of JS objects, each containing the Name, Longitude and Latitude of each preDevCamp city (see geocoding below)</li>
</ol>
<p>That&#8217;s it for creating the map!</p>
<h3>Geocoding</h3>
<p>Geocoding is the transformation of an address of some sort into a latitude and longitude. Google Maps provides a geocoding interface and you can translate addresses on the fly if you need to. However, the geocoding service is rate limited and if you request too many, too quickly, your requests will get rejected. In addition to this, it takes a certain amount of time to send the request and get a response. As a result, the geocoding results have been cached on the preDevCamp server and are taken from there. This also allows us to handle ambiguous locations, such as &#8220;Washington&#8221; or &#8220;Charleston&#8221;, which could refer to a number of locations. Since we know which city each preDevCamp is in, we can add special handling for cities such as these.</p>
<p>That said, the geocoding service is used to find the Latitude and Longitude of Twitter users, based on their reported location.</p>
<h2>Twitter API</h2>
<p>Once the map is created, all that remains is to query Twitter for relevant Tweets. Like the Google Maps API, the <a href="http://apiwiki.twitter.com/">Twitter API</a> is really well documented. They actually have 2 APIs. One is for searching the Twitter public time line, the other is for interacting more explicitly with Twitter. One thing to note is that the Twitter API is also rate limited. You&#8217;re restricted to 100 API requests per hour, unless you get a special dispensation from Twitter.</p>
<p>So, the first step PreView takes is to find out how many API requests are available. It also checks to see when this limit will be reset and will use that later on, if the limit is exceeded</p>
<p>PreView continues by sending out searches for &#8216;predevcamp&#8217;, &#8216;webos&#8217; and &#8216;palm pre&#8217;. Each of these requests generates a list of Tweet objects which are put onto a central list which sorts by each Tweet&#8217;s ID. The ID is globally unique. At this point, PreView does not filter duplicated Tweets, but a future version will.</p>
<p>The next step is to go through the list one at a time and display the Tweet on the map. In order to do this, we take the location property of the Tweet and send it to the Google Geocoding Service. Although this Service is rate limited, we only show Tweets once every 8 seconds or so, so we&#8217;re not going to hit the rate limit that Google sets. <em>However</em>, asking Twitter where a user is located, <strong>does</strong> count against our Twitter API usage, so we make sure to cache users&#8217; locations to prevent the limit from being gobbled up.</p>
<p>If the user&#8217;s location does not translate, we put the Tweet somewhere in the middle of the Pacific Ocean. There may be a better way to indicate that Tweet cannot be located but, again, that is deferred to version 2.0.</p>
<p>Once all of the Tweets in the list have been shown, we send a second request to the Twitter Search API. Twitter has a neat trick to help us here. When we send a search request , Twitter gives us a list of Tweets as well as a URL that we can use later which essentially says: &#8220;Show us the Search Results starting from where we left off in the last search&#8221;. This means we don&#8217;t need to filter for Tweets that we&#8217;ve already seen.</p>
<h2>Summary</h2>
<p>Hopefully, that&#8217;s given you an overview of what I sought to achieve with the preView map. By looking through the <a href="http://predevcamp.org/js/preView.js">source code</a> and reading this post, you should be able to see what it takes to make something like this. The astute of you will also see areas where preView could be improved and, when I have time, I&#8217;ll be taking a second run at it. However, for now, I hope that it proves to be an instructive read!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/03/03/global-tweeting-about-the-pre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why web developers should look hard at webOS</title>
		<link>http://www.danrumney.co.uk/2009/02/22/why-web-developers-should-look-hard-at-webos/</link>
		<comments>http://www.danrumney.co.uk/2009/02/22/why-web-developers-should-look-hard-at-webos/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 19:05:21 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[preDevCamp]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[mojo]]></category>
		<category><![CDATA[palm pre]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=136</guid>
		<description><![CDATA[There is a lot of excitement in the mobile development world about the coming of the Palm Pre. Palm&#8217;s been doing pretty poorly of late, so the alternate prospects of abject failure (and bye, bye Palm) and glorious success (bye, bye iPhone) has get everyone all of a quiver. The thing is, I&#8217;m a big [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="Guy At Computer" src="/images/guyAtComputer.jpg" alt="" width="226" height="339" />There is a lot of excitement in the mobile development world about the coming of the Palm Pre. Palm&#8217;s been doing pretty poorly of late, so the alternate prospects of abject failure (and bye, bye Palm) and glorious success (bye, bye iPhone) has get everyone all of a quiver. The thing is, I&#8217;m a big geek&#8230; I&#8217;m just excited about webOS.<br />
<span id="more-136"></span></p>
<p>If you don&#8217;t know, webOS is the new operating system that Palm have created. Instead of having to write apps in Objective C or Java, Palm have opted for having HTML, Javascript and CSS as the language of choice. I think this might be a smart move on their part; the number of applications that developers write is directly proportional to the number of developers who actually <strong>have</strong> the expertise to code for this platform. However, I think Palm have only made <em>half</em> of this smart move.</p>
<p>If you want to change the game, you sometimes need to bring in new players. Right now, the smartphone application development arena is populated by Objectve C developers and Java developers. Many of these developers have been mobile application developers for a long time. They bring great experience with them, but they also bring history. They look at applications in a &#8216;mobile&#8217; way; this is not necessarily the best way. Palm seem to have opened the door, but they&#8217;re not doing anything to point the door out to people or to encourage them to walk through it.</p>
<p>I want to see web developers sit up and take notice of webOS and the Palm Pre. For one thing, it&#8217;s an opportunity for them to branch out and extend their repetoire. They don&#8217;t need to learn a new language; just an alteration in architecture and a new framework. With very little effort, a seasoned web developer can become a webOS developer.<br />
Also, web developers are used to the stateless nature of web pages and have learned to work around this with cookies and HTML 5 Storage functions. In addition, they&#8217;re used to JSON and working with DOM manipulation. That means that they can concentrate on the important aspect of generating innovative ideas for apps, instead of getting to grips with a new language.</p>
<p>Bringing in developers without a traditional mobile mindset will, no doubt, result in some applications that really don&#8217;t perform well on a mobile platform. However, it also brings the potential for some really great ideas, unfettered by the idea of &#8216;what is possible&#8217;. Again, Palm do not appear to be highlighting this; instead they are highlighting the number of PalmOS developers that they have.</p>
<p>The thing is, the number of web developers in the world is staggering. Palm claim 30,000 developers in the Palm development community; contrast this with the over 4.5m downloads of the development version of  jQuery last year alone&#8230; that gives you some kind of indication of how many web developers are out there.</p>
<p>If you&#8217;re a web developer out there, looking for a new challenge, take a long hard look at the Palm Pre. If you&#8217;re interested, go over to the <a href="http://predevcamp.org">preDevCamp website</a> and sign up or organizer a local event; join an evergrowing group of developers excited by this new platform. As a founder of preDevCamp, I have to admit a bias, but I&#8217;m not waiting for Palm to realise what they&#8217;ve got here</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/02/22/why-web-developers-should-look-hard-at-webos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What have we learned about webOS?</title>
		<link>http://www.danrumney.co.uk/2009/02/18/what-have-we-learned-about-webos/</link>
		<comments>http://www.danrumney.co.uk/2009/02/18/what-have-we-learned-about-webos/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 07:17:33 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[preDevCamp]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[mojo]]></category>
		<category><![CDATA[pre]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=124</guid>
		<description><![CDATA[O&#8217;reilly release the first chapter of their new webOS book in the past few days and it has been a welcome island in a sea of tedious rumours. While others may wildly speculate on when the Pre will appear, at least we now have some idea of what it will be running. So what does [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="webOS Rough Cuts" src="/images/webOSRoughCutsTitle.png" alt="" width="410" height="224" /></p>
<p>O&#8217;reilly release <a href="http://oreilly.com/catalog/9780596801816/">the first chapter of their new webOS book</a> in the past few days and it has been a welcome island in a sea of tedious rumours. While others may wildly speculate on <strong>when</strong> the Pre will appear, at least we now have some idea of what it will be running.<br />
<span id="more-124"></span></p>
<p>So what does this chapter tell us about webOS? Well, a lot of the chapter is spent with the usual overview. I tend to skip these chapters in technical books, but webOS is brand new to me, so I gave it the time. Here&#8217;s what I learned:</p>
<ul>
<li>webOS is expressly intended to support multiple hardware environments with all sorts over screen sizes, resolutions and orientations &#8211; This tells me that a good webOS App will not restrict itself to functioning on a Pre form factor</li>
<li>webOS will use HTML 5 tags to provide storage functions and some graphic functions (using the canvas) &#8211; This tells me that I need to get up to speed on HTML 5 and start playing with it in Firefox</li>
<li>webOS will give you access to Calendar and Contact data, Location Services, Accelerometer data and XMPP messaging  &#8211; This tells me that the apps we can make are going to be awwwwesome!</li>
<li>Mojo will come bundled with the <a href="http://www.prototypejs.org/">Prototype</a> framework &#8211; Since I&#8217;m a jQuery fan, this means that I have to learn <strong>another </strong>JS framework, if I&#8217;m going to be able to fully exploit the Pre</li>
<li>The Core OS will support fat32 for media file partitions (with a mention of mounting via USB) &#8211; This suggests that it may be possible to plug a USB drive into the Pre for extra storage and ease of file transfer!</li>
</ul>
<p>There are some  nice pieces about design philosophy and UI considerations in the first chapter and some high level introduction to concepts such as <em>stages</em> and <em>scenes</em>.</p>
<p>All in all, and interesting read; certainly enough to whet my appetite for the Pre. Here&#8217;s what I&#8217;m going to be doing in preparation:</p>
<ol>
<li>Learn HTML 5</li>
<li>Learn Prototype</li>
</ol>
<p>I think focusing on those two, for now, will put me in good stead. I recommend the same to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/02/18/what-have-we-learned-about-webos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A History of Languages</title>
		<link>http://www.danrumney.co.uk/2009/02/15/a-history-of-languages/</link>
		<comments>http://www.danrumney.co.uk/2009/02/15/a-history-of-languages/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 01:30:22 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[preDevCamp]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[assembler]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[korn shell]]></category>
		<category><![CDATA[languages]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=104</guid>
		<description><![CDATA[I saw @mhat&#8216;s tweet today about &#8216;What language should I learn&#8216;  and it got me thinking about the times I&#8217;ve asked that question and how I might answer it. So, @mhat, I&#8217;m taking your tweet to be a challenge to write an unbiased and &#8216;unwrong&#8217; post. To do this, I&#8217;m going to give you a [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Laptop and Books" src="/images/laptopAndBooks.jpg" alt="" width="425" height="282" /></p>
<p>I saw <a href="http://twitter.com/mhat">@mhat</a>&#8216;s tweet today about &#8216;<a href="http://twitter.com/mhat/status/1212746649">What language should I learn</a>&#8216;  and it got me thinking about the times I&#8217;ve asked that question and how I might answer it. So, @mhat, I&#8217;m taking your tweet to be a challenge to write an unbiased and &#8216;unwrong&#8217; post. To do this, I&#8217;m going to give you a history of the languages I have learned.<br />
<span id="more-104"></span></p>
<h2>The early years</h2>
<p>As I wrote in <a href="http://www.danrumney.co.uk/2009/01/25/all-geekness-great-and-small/">my first post</a>, I started at a tender age, on a ZX Spectrum. The Spectrum came with a dialect of BASIC, called &#8216;Sinclair Basic&#8217;. Like all <a href="http://en.wikipedia.org/wiki/BASIC_programming_language">BASIC</a> derivatives, it&#8217;s a high level language, however unlike modern flavours of BASIC, it was untyped and unstructured. Lines of code were entered with the line number provided explicitly. There was no variable scoping and subroutines were implemented as a special &#8216;GOTO&#8217; called &#8216;GOSUB&#8217; which allowed you to &#8216;RETURN&#8217; to the next line. However, since there was no variable scoping, recursion was impossible.</p>
<p>That said, I was 5 at the time, I wasn&#8217;t too worried about recursion at the time. My programming was limited to copying code out of books containing page after page of ZX Spectrum programs. My brother and I would diligently type these out, then play the game for a while and then start playing with the code to see what changes we could make. This process was about as successful as genetic mutation. More often than not, our change would kill the program, but sometimes it would lead to great stuff.</p>
<p>As we got older, our 48K Spectrum was replaced with a 128K Spectrum. Along with the extra memory, came an update to BASIC to include keywords that allowed direct access to the MIDI chip. I continued to mess around with BASIC, making programs that would play both hands of a piano score, as well as simple games.</p>
<h2>The IBM PC arrives</h2>
<p>My first experience with an IBM PC was the 286. I migrated from Sinclair BASIC to <a href="http://en.wikipedia.org/wiki/Microsoft_GW-BASIC_interpreter">GW-BASIC</a>. At this point, I was writing programs from scratch, including a text adventure called &#8216;Loup-Garou Chateau&#8217;. Tragically, this game has been lost from prosperity, but it was my first foray into actually <em>designing</em> a program before coding it. I chose GW-BASIC, simply because I was very familiar with BASIC and it made for the simplest transition.</p>
<p>As the years passed, I would inherit my dad&#8217;s old computers, moving up through the 386 to the 486. At this point, I got my hands on <a href="http://en.wikipedia.org/wiki/Visual_Basic">Visual Basic</a>. Again, this transition was driven by the ease of transition from what I knew to something new. This was my first experience with a proper development IDE, as well as my first experience with creating GUIs. Beyond that, it wasn&#8217;t a great step forward to me&#8230; that would come during university.</p>
<h2>Coding gets hardcore</h2>
<p>I never studied computing at university; I was a physics student. However, the course I took, included some small computing components. For one lab rotation, we learned how to use computers for physical analysis. This was back in 2000 and they had us coding with <a href="http://en.wikipedia.org/wiki/Pascal_(programming_language)">Pascal</a>. At the same time, I was playing with <a href="http://en.wikipedia.org/wiki/C_(programming_language)">C</a> at the suggestion of my dad. For the first time, I was learning about functions and variable typing. In addition, I was programming with the intention to solve problems that were being presented to me, instead of just &#8216;playing&#8217; with a language and seeing what it could do. When you have an externally provided problem to solve, you&#8217;re forced to learn how to use new facets of the language. If you&#8217;re just playing around, you can be limited to seeing what you can do with the parts of the language you understand.</p>
<p>While at university, I also participated in an Electronics lab which involved learning about the 8086 processor. We had an experimental board which allowed us to commit opcodes to a region of memory and then execute them. As part of the practical, we actually had to wire up the SUB instruction, by running the clock signal through the appropriate logic gates and to the appropriate ALU pins. This was my first experience with the lowest level of programming.</p>
<p>In the summer between my second and third years, I spent four weeks working for <a href="http://www.milinst.com/">Milford Instruments</a>. While there, I developed a <a href="http://www.ppmilinst.redcetera.com/shop/DMX/pdf/1_463.pdf">DMX-512 Transceiver Controller</a>. I was working with the SX-Chip from Parallax and learned how to write assembler, how to work with interrupt handlers and how to get microcontrollers to talk to other microchips. For 4 weeks, I worked on the firmware and the hardware and really learned what programming was all about&#8230;</p>
<p><img class="alignnone" title="Computer Code" src="/images/computerCode.jpg" alt="" width="400" height="300" /></p>
<h2>Coding starts to bring in money</h2>
<p>My month at Milford Instruments made me realise what I wanted to do with my time; I wanted to get into development professionally. It was an obvious choice to apply to IBM and I started working at their Hursley Development Lab, one weeks after school ended. They had me working on a protocol converter, (this time, a SCSI-SSA converter) and, as before, it was coded in assembler.</p>
<p>After a couple of years working on this, I moved to work on one of their Storage RAID controllers. This time I was coding in C, the first time I had done so, professionally. However, alongside all this production code, I was steadily learning how to write <a href="http://en.wikipedia.org/wiki/Perl">Perl</a> and <a href="http://en.wikipedia.org/wiki/Korn_shell">Korn Shell</a> scripts for developing test rigs. I was also teaching myself how to code for the web. I&#8217;d done some basic page development while at university, but I was beginning to learn about dynamic pages and DOM manipulation.</p>
<p>My next move got me into support and I started writing a web-based support tool. It uses Perl and <a href="http://en.wikipedia.org/wiki/MySQL">MySQL</a> in the back-end and HTML and Javascript in the front-end.</p>
<p>The main thing I got from the IBM Development Lab was the chance to be surrounded by people writing a wide variety of code to solve a wide variety of problems and be exposed to what other people were doing with languages that I both knew and that I had never heard of. I learned that there is really no such thing as the one perfect language, rather the best language for the job in hand.</p>
<h2>What&#8217;s the point of all this?</h2>
<p>So, what&#8217;s the point of this post? Is it possible to write a post about &#8220;Which language should I use&#8221; that is not biased and has some value? I hope so. Here&#8217;s what I feel I&#8217;ve learned over the years.</p>
<p>People write code for a wide variety of reasons. The language that they code in is also determined by a multitude of factors. More often than not, we don&#8217;t have a truly free hand when it comes to choosing the language we&#8217;re coding in. However, looking back, I believe I see some benefits in the track I took.</p>
<ul>
<li>Learning C allows you to truly understand what higher level languages such as Perl or Java are doing with objects and references. Although people get scared off by pointers, if you don&#8217;t understand the concept, then you&#8217;re going to struggle with the idea of references. Since all languages have variables, if you can get those nailed and totally understood, you&#8217;re going to be in good stead when you move to a language which brings new data types</li>
<li>Learning Assembler allows you to truly understand what C is doing with pointers. Assembler has a tiny command set and you have to tell it to do every last thing. It&#8217;s a struggle, but once you&#8217;ve got assembler in your tool belt you&#8217;re in good shape. You may never go back to it, but the lessons you learn from it can be applied all the way up the language stack</li>
<li>Learning a wide variety of languages allows you to truly understand the patterns of development that are language-independent and stops you falling into the trap of becoming a language bigot. There&#8217;s nothing wrong with having a favourite language, but saying that one language is categorically better than another because of the presence of a specific feature is like praising Inuit for its wide variety of words for snow. That&#8217;s fine if you&#8217;re describing snow, but not much use if you want to discuss the surfing conditions in Hawaii.</li>
<li>Learning a language is a lot easier if you&#8217;re trying to solve a specific problem that has come from an external source. This is why it&#8217;s such a good idea to do the exercises if you&#8217;re learning from a textbook. There&#8217;s nothing wrong with playing with a feature for its own sake, but unless you have some factor that is external to the language driving you, it&#8217;s going to be tough to learn all that the language can do.</li>
</ul>
<h2>Did I just cop out?</h2>
<p>So, did I just cop out of the question? If someone asked me what language they should learn, how would I answer? That depends on the person. If they were just starting out, I would say Perl or Python. These languages have a huge development community and millions of pages dedicated to coding in them. They are in common usage and show no signs of disappearing in the near future. They are neither arcane nor limited in their range and they allow for procedural and object oriented style programming, meaning that the developer can transition to OO without having to change languages.</p>
<p>If I was being asked by someone with a reasonable amount of development, I would strongly suggest Javascript. As the powerhouse behind Web 2.0 and the basis for coding on the Palm Pre, it&#8217;s critical to know this language. However, testing and debugging Javascript is not a trivial task and requires a developer who is comfortable writing code that has &#8216;a good chance&#8217; of working so that troubleshooting is limited to ironing out wrinkle. Also, the problems of cross-browser support are bewildering enough for experienced coders; exposing a brand new coder to Javascript would probably be the end of their efforts in the field.</p>
<p>If someone wanted to spread their wings a little, I&#8217;d strongly suggest taking a look at Assembler or some other microprocessor based language. It&#8217;s still coding, but you&#8217;re forced to truly understand your code&#8217;s interaction with external factors that don&#8217;t care about your nice neat program. Spending time debugging microprocessor code; especially code that interacts with an external piece of hardware, gives you a true understanding of the many ways that code can fail to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/02/15/a-history-of-languages/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Augmenting Twitter &#8211; WhoAmI?</title>
		<link>http://www.danrumney.co.uk/2009/02/15/augmenting-twitter-whoami/</link>
		<comments>http://www.danrumney.co.uk/2009/02/15/augmenting-twitter-whoami/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 21:05:29 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=100</guid>
		<description><![CDATA[Like a fair number of people, I have a number of Twitter identities. I have my personal identity (@dancrumb) as well as a number of shared identities that represent events or organizations in which I&#8217;m involved. I use a number of clients to send out tweets, but all of these clients limit you to a [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Twitter meets GreaseMonkey" src="/images/tweetMonkey.jpg" alt="" width="408" height="125" /></p>
<p>Like a fair number of people, I have a number of Twitter identities. I have my personal identity (<a href="http://twitter.com/dancrumb">@dancrumb</a>) as well as a number of shared identities that represent events or organizations in which I&#8217;m involved.</p>
<p>I use a number of clients to send out tweets, but all of these clients limit you to a single identity. If you want to user twitter.com to send out messages, you need to log in with the appropriate identity before you perform any Twitter functions.</p>
<p>Herein lies the problem. When you&#8217;re logged in to Twitter and you navigate to somebody&#8217;s Twitter page, there is no indication as to who you&#8217;re logged in as. The risk is that you could elect to follow or message someone, thinking you&#8217;re logged in as one identity, only to find that you&#8217;re logged in as another identity. I did precisely this, yesterday. As luck would have it, the person was my sister and I quickly spotted my mistake, but if  you&#8217;re using Twitter as a major communication channel, you need to be <strong>very</strong> aware of which identity you&#8217;re tweeting with.</p>
<p>In order to address this, I&#8217;ve written a small Greasemonkey script. You can access it <a href="http://www.danrumney.co.uk/gmScripts/twitterWhoAmi.user.js">here</a>. You&#8217;ll need to have the <a href="https://addons.mozilla.org/en-US/firefox/addon/748">Greasemonkey plugin</a> installed, of course.</p>
<p>Once the script is installed, you will be able to see who you&#8217;re logged on as, in the Twitter navigation bar at the top right-hand corner of the screen, at all times.</p>
<p>I hope you find it useful; I know from experience that I will&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/02/15/augmenting-twitter-whoami/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Build your own TwitterFeed</title>
		<link>http://www.danrumney.co.uk/2009/02/03/build-your-own-twitterfeed/</link>
		<comments>http://www.danrumney.co.uk/2009/02/03/build-your-own-twitterfeed/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 08:04:14 +0000</pubDate>
		<dc:creator>dancrumb</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[preDevCamp]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.danrumney.co.uk/?p=58</guid>
		<description><![CDATA[As part of the preDevCamp 2009 site, I created a JavaScript TwitterFeed today. A sample can be seen here. If you leave this page open, it will constantly update with all Twitter tweets that contain the word &#8216;twitter&#8217;. It will update once every 5 seconds and will contain no more than the 25 most recent [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Twitter Whale" src="http://static.twitter.com/images/whale.png" alt="" width="424" height="318" /></p>
<p>As part of the <a href="http://predevcamp.org">preDevCamp 2009</a> site, I created a JavaScript TwitterFeed today.</p>
<p>A sample <a href="http://www.danrumney.co.uk/twitterTest.html">can be seen here</a>. If you leave this page open, it will constantly update with all Twitter tweets that contain the word &#8216;twitter&#8217;. It will update once every 5 seconds and will contain no more than the 25 most recent tweets.</p>
<p>Installing this code into a page of your own is very simple. You will need the following:</p>
<ul>
<li>jQuery must be installed and you must include it in your webpage</li>
<li>tweetFeed.js must be included in your webpage</li>
<li>tweetFeed.css should be included, although the function <strong>will</strong> work without this file</li>
<li>A &lt;div&gt; with an id of &#8216;tweets&#8217; somewhere on the page</li>
</ul>
<p>With all of those in place, it&#8217;s a simple case of instantiating the feed:</p>
<p><code>var tf = new TweetFeed(searchString,feedPeriod,feedLength);</code></p>
<dl>
<dt>searchString</dt>
<dd>This is the string that is used to generate the feed. The feed will contain all tweets containing this word</dd>
<dt>feedPeriod</dt>
<dd>Number of seconds between each refresh of the feed</dd>
<dt>feedLength</dt>
<dd>Maximum number of tweets to show. At the moment, this must be &gt; 15 or else the feed doesn&#8217;t work properly.</dd>
</dl>
<p>All of the relevant code can be found by looking at the example, linked to above. Feel free to use this in any way you like. Comments are welcome</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danrumney.co.uk/2009/02/03/build-your-own-twitterfeed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

