<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:series="http://organizeseries.com/"
> <channel><title>SitePoint &#187; Intermediate</title> <atom:link href="http://www.sitepoint.com/category/javascript/intermediate/feed/" rel="self" type="application/rss+xml" /><link>http://www.sitepoint.com</link> <description>Learn CSS &#124; HTML5 &#124; JavaScript &#124; Wordpress &#124; Tutorials-Web Development &#124; Reference &#124; Books and More</description> <lastBuildDate>Mon, 13 May 2013 13:12:07 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5.1</generator> <item><title>Accessible Audio Descriptions for HTML5 Video</title><link>http://www.sitepoint.com/accessible-audio-descriptions-for-html5-video/</link> <comments>http://www.sitepoint.com/accessible-audio-descriptions-for-html5-video/#comments</comments> <pubDate>Mon, 29 Apr 2013 21:32:51 +0000</pubDate> <dc:creator>James Edwards</dc:creator> <category><![CDATA[Accessibility]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[video]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65695</guid> <description><![CDATA[James describes a simple but surprisingly effective technique for synchronising multiple media sources in order to add accessible audio descriptions to an existing video.]]></description> <content:encoded><![CDATA[<p></p><p>A client recently asked me to produce an accessible video player, and one of the features she was very keen to have is <strong>audio descriptions</strong>. Audio descriptions are intended for people who are blind or have impaired vision, providing additional spoken information to describe important visual details.</p><p>Traditionally, audio-described videos have to be made specially, with the audio encoded in a separate track of the single video file. It takes pretty specialised video-editing equipment to encode these audio tracks, and that raises the bar for most content producers beyond a practical level.</p><p>All the audio-described content I&#8217;ve seen on the web is like this. For example, <a
href="http://www.bbc.co.uk/iplayer/">BBC iPlayer</a> has a <a
title="Audio Described programs on BBC iPlayer (bbc.co.uk)" href="http://www.bbc.co.uk/iplayer/tv/categories/audiodescribed">selection of such content</a>, but the video player doesn&#8217;t give you control over the relative volumes, and you can&#8217;t turn the audio-descriptions off — you can only watch separate described or non-described versions of the program.</p><h2>Enter HTML5</h2><p>The <a
title="The video element (whatwg.org)" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html">HTML5 video specification</a> does provide an <code><a
title="Media resources with multiple media tracks (whatwg.org)" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#media-resources-with-multiple-media-tracks">audioTracks</a></code> object, which would make it possible to implement an on/off button, and to control the audio and video volumes separately. But its browser support is virtually non-existent — at the time of writing, only <abbr
title="Internet Explorer 10">IE10</abbr> supports this feature.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>In any case, what my client wanted was <strong>audio descriptions in a separate file</strong>, which could be added to a video without needing to create a separate version, and which would be easy to make without specialised software. And of course, it had to work in a decent range of browsers.</p><p>So my next thought was to use a <a
title="Synchronising multiple media elements (whatwg.org)" href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#synchronising-multiple-media-elements">MediaController</a>, which is a feature of <abbr
title="HyperText Markup Language Version 5">HTML5</abbr> audio and video that allows you to synchronise multiple sources. However browser support for this is equally scant — at the time of writing, only Chrome supports this feature.</p><p>But you know — even without that support, it&#8217;s clearly not a problem to <strong>start</strong> two media files at the same time, it&#8217;s just a case of <strong>keeping them in sync</strong>. So can we use existing, widely-implemented features to make that work?</p><h2>Video Events</h2><p>The video <abbr
title="Application Programming Interface">API</abbr> provides a number of events we can hook into, that should make it possible to synchronise audio playback with events from the video:</p><ul><li>The <code>"play"</code> event (which fires when the video is played).</li><li>The <code>"pause"</code> event (which fires when the video is paused).</li><li>The <code>"ended"</code> event (which fires when the video ends).</li><li>The <code>"timeupdate"</code> event (which fires continually while the video is playing).</li></ul><p>It&#8217;s the <code>"timeupdate"</code> event that&#8217;s really crucial. The <em>frequency</em> at which it fires is not specified, and practise it varies considerably — but as a rough, overall average, it amounts to 3–5 times per second, which is enough for our purposes.</p><p>I&#8217;ve seen a similar approach being tried to <a
title="Two videos in sync (html5demos.com)" href="http://html5demos.com/two-videos">synchronise two video files</a>, but it isn&#8217;t particularly successful, because even tiny discrepancies are very obvious. But audio descriptions generally don&#8217;t need to be so precisely in sync — a delay of <code>100ms</code> either way would be acceptable — and playing audio files is far less work for the browser anyway.</p><p>So all we need to do is use the video events we have, to lock the audio and video playback together:</p><ul><li>When the video is played, play the audio.</li><li>When the video is paused, pause the audio.</li><li>When the video ends, pause the video and audio together.</li><li>When the time updates, set the audio time to match the video time, if they&#8217;re different.</li></ul><p>After some experimentation, I discovered that the best results are achieved by comparing the time in whole seconds, like this:</p><pre class="brush: jscript; title: ; notranslate">
if(Math.ceil(audio.currentTime) != Math.ceil(video.currentTime))
{
  audio.currentTime = video.currentTime;
}
</pre><p>This seems counter-intuitive, and initially I had assumed we&#8217;d need as much precision as the data provides, but that doesn&#8217;t seem to be the case. By testing it using a literal audio copy of the video&#8217;s soundtrack (i.e. so the audio and video both produce identical sound), it&#8217;s easy to hear when the synchronisation is good or bad. Experimenting on that basis, I got much better synchronisation when rounding the figures, than not.</p><p>So here&#8217;s the final script. If the browser supports <code>MediaController</code> then we just use that, otherwise we implement manual synchronisation, as described:</p><pre class="brush: jscript; title: ; notranslate">
var video = document.getElementById('video');
var audio = document.getElementById('audio');
if(typeof(window.MediaController) === 'function')
{
  var controller = new MediaController();
  video.controller = controller;
  audio.controller = controller;
}
else
{
  controller = null;
}
video.volume = 0.8;
audio.volume = 1;
video.addEventListener('play', function()
{
  if(!controller &amp;&amp; audio.paused)
  {
    audio.play();
  }
}, false);
video.addEventListener('pause', function()
{
  if(!controller &amp;&amp; !audio.paused)
  {
    audio.pause();
  }
}, false);
video.addEventListener('ended', function()
{
  if(controller)
  {
    controller.pause();
  }
  else
  {
    video.pause();
    audio.pause();
  }
}, false);
video.addEventListener('timeupdate', function()
{
  if(!controller &amp;&amp; audio.readyState &gt;= 4)
  {
    if(Math.ceil(audio.currentTime) != Math.ceil(video.currentTime))
    {
      audio.currentTime = video.currentTime;
    }
  }
}, false);
</pre><p>Note that the <code>MediaController</code> itself is defined only through scripting, whereas it is possible to define a controller using the static <code>"mediagroup"</code> attribute:</p><pre class="brush: xml; title: ; notranslate">
&lt;video mediagroup=&quot;foo&quot;&gt; ... &lt;/video&gt;
&lt;audio mediagroup=&quot;foo&quot;&gt; ... &lt;/audio&gt;
</pre><p>If we did that, then it would work without JavaScript in Chrome. It would sync the media sources, but the user would have <strong>no control over the audio</strong> (including not being able to turn it off), because the browser <em>wouldn&#8217;t know what the audio represents</em>. This is the case in which it would be better to have the audio encoded into the video, because then it could appear in the <code>audioTracks</code> object, and the browser could recognise that and be able to provide native controls.</p><p>But since we have no <code>audioTracks</code> data, that&#8217;s rather a moot point! So if scripting is not available, the audio simply won&#8217;t play.</p><p><strong>Here&#8217;s the final demo</strong>, which will work in any recent version of Opera, Firefox, Chrome, Safari, or <abbr
title="Internet Explorer 9">IE9</abbr> or later:</p><ul><li><strong><a
href="http://jspro.brothercake.com/audio-descriptions/">Audio Descriptions Demo</a></strong></li></ul><p>This is just a simple proof-of-concept demo, of course — there&#8217;s no initial feature detection, and it only has the basic controls provided by the native <code>"controls"</code> attribute. For a proper implementation it would need custom controls, to provide (among other things) a button to switch the audio on and off, and separate volume sliders. The interface should also be accessible to the keyboard, which is not the case in some browsers&#8217; native controls. And it would need to handle buffering properly — as it is, if you seek past the point where the video has preloaded, the audio will continue to play freely until the video has loaded enough to bring it back into sync.</p><p>I might also mention that the descriptions themselves are hardly up to professional standards! That&#8217;s my voice you can hear, recorded and converted using <a
title="Audacity is a free audio editor and recorded" href="http://audacity.sourceforge.net/">Audacity</a>. But such as it is, I think it makes an effective demonstration, of how low the technical barrier-to-entry is with this approach. I didn&#8217;t have to edit the video, and I made the audio in an hour with free software.</p><p>As a proof of concept, I&#8217;d say it was pretty successful — and I&#8217;m sure my client will be very pleased!</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/accessible-audio-descriptions-for-html5-video/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>3 Neat Tricks with Regular Expressions</title><link>http://www.sitepoint.com/3-neat-tricks-with-regular-expressions/</link> <comments>http://www.sitepoint.com/3-neat-tricks-with-regular-expressions/#comments</comments> <pubDate>Thu, 18 Apr 2013 01:20:15 +0000</pubDate> <dc:creator>James Edwards</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Raw Javascript]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=65485</guid> <description><![CDATA[James looks at three cunning things you can do with regular expressions, that provide neat solutions to some very sticky problems.]]></description> <content:encoded><![CDATA[<p></p><p>I&#8217;d like to show you three cunning things you can do with regular expressions, that provide neat solutions to some very sticky problems:</p><ol><li><a
href="#removing-comments">Removing Comments</a></li><li><a
href="#using-replacement-callbacks">Using Replacement Callbacks</a></li><li><a
href="#working-with-invisible-delimiters">Working With Invisible Delimiters</a></li></ol><h2 id="removing-comments">1. Removing Comments</h2><p>Regular expressions make light work of <strong>single-character delimiters</strong>, which is why it&#8217;s so easy to remove markup from a string:</p><pre class="brush: jscript; title: ; notranslate">
str = str.replace(/(&lt;[\/]?[^&gt;]+&gt;)/g, '');
</pre><p>It&#8217;s the negation in the character class that does the real work:</p><pre class="brush: jscript; title: ; notranslate">
[^&gt;]
</pre><p>Which means <em>&#x201c;anything except <code>&lt;&#x201d;</code></em>. So the expression looks for the starting tag-delimiter and possible slash, then anything except the closing tag-delimiter, and then the delimiter itself. Easy.</p><p>However comments are not so simple, because comment delimiters are comprised of <strong>more than one character</strong>. Multi-line comments in <abbr
title="Cascading Style Sheets">CSS</abbr> and JavaScript, for example, start with <code>/*</code> and end with <code>*/</code>, but between those two delimiters there could be <strong>any number of unrelated stars</strong>.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>I often use multiple stars in comments, to indicate the severity of a bug I&#8217;ve just noticed, for example:</p><pre class="brush: jscript; title: ; notranslate">
/*** this is a bug with 3-star severity ***/
</pre><p>But if we tried to parse that with a single negation character, it would fail:</p><pre class="brush: jscript; title: ; notranslate">
str = str.replace(/(\/\*[^\*]+\*\/)/g, '');
</pre><p>Yet it&#8217;s not possible with regular expressions to say: <em>&#x201c;anything except [this sequence of characters]&#x201d;</em>, we can only say: <em>&#x201c;anything except [one of these single characters]&#x201d;</em>.</p><p>So here&#8217;s the regular expression we need instead:</p><pre class="brush: jscript; title: ; notranslate">
str = str.replace(/(\/\*([^*]|(\*+[^*\/]))*\*+\/)/gm, '');
</pre><p>The expression handles unrelated characters by <strong>looking at what comes after them</strong> &#x2014; stars are allowed as long as they&#8217;re not followed by a slash, until we find one that is, and that&#8217;s the end of the comment.</p><p>So it says: <em>&#x201c;<code>/</code> then <code>*</code> (then anything except <code>*</code> OR one or more <code>*</code> followed by anything except <code>*</code> or <code>/</code>)(and any number of instances of that) then one or more <code>*</code> then <code>/</code>&#x201d;</em>.</p><p>(The syntax looks particular convoluted, because <code>"*"</code> and <code>"/"</code> are both special characters in regular expressions, so the ambiguous literal ones have to be escaped. Also note the <code>"m"</code> flag at the end of the expression, which means <strong>multi-line</strong>, and specifies that the regular expression should search across more than one line of text.)</p><p>Using the same principle then, we can adapt the expression to search for any kind of complex delimiters. Here&#8217;s another one that matches <abbr
title="HyperText Markup Language">HTML</abbr> comments:</p><pre class="brush: jscript; title: ; notranslate">
str = str.replace(/(&lt;!\-\-([^\-]|(\-+[^&gt;]))*\-+&gt;)/gm, '');
</pre><p>And here&#8217;s one for <code>CDATA</code> sections:</p><pre class="brush: jscript; title: ; notranslate">
str = str.replace(/(&lt;\!\[CDATA\[([^\]]|(\]+[^&gt;]))*\]+&gt;)/gm, '');
</pre><h2 id="using-replacement-callbacks">2. Using Replacement Callbacks</h2><p>The <code>replace</code> function can also be <strong>passed a callback</strong> as its second parameter, and this is invaluable in cases where the replacement you want can&#8217;t be described in a simple expression. For example:</p><pre class="brush: jscript; title: ; notranslate">
isocode = isocode.replace(/^([a-z]+)(\-[a-z]+)?$/i,
  function(match, lang, country)
  {
    return lang.toLowerCase()
      + (country ? country.toUpperCase() : '');
  });
</pre><p>That example normalizes the capitalisation in language codes &#x2014; so <code>"EN"</code> would become <code>"en"</code>, while <code>"en-us"</code> would become <code>"en-US"</code>.</p><p>The first argument that&#8217;s passed to the callback is always the complete match, then each subsequent argument corresponds with the backreferences (i.e. <code>arguments[1]</code> is what a string replacement would refer to as <code>"$1"</code>, and so on).</p><p>So taking <code>"en-us"</code> as the input, we&#8217;d get the three arguments:</p><ol
start="0"><li><code>"en-us"</code></li><li><code>"en"</code></li><li><code>"-us"</code></li></ol><p>Then all the function has to do is enforce the appropriate cases, re-combine the parts and return them. Whatever the callback returns is what the replacement itself returns.</p><p>But we don&#8217;t actually have to assign the return value (or return at all), and if we don&#8217;t, then the original string will be unaffected. This means we can use <code>replace</code> as a <strong>general-purpose string processor</strong> &#x2014; to extract data from a string without changing it.</p><p>Here&#8217;s another example, that combines the multi-line comment expression from the previous section, with a callback that extracts and saves the text of each comment:</p><pre class="brush: jscript; title: ; notranslate">
var comments = [];
str.replace(/(\/\*([^*]|(\*+[^*\/]))*\*+\/)/gm,
  function(match)
  {
    comments.push(match);
  });
</pre><p>Since nothing is returned, the original string remains unchanged. Although if we wanted to extract <em>and</em> remove the comments, we could simply return and assign an empty-string:</p><pre class="brush: jscript; title: ; notranslate">
var comments = [];
str = str.replace(/(\/\*([^*]|(\*+[^*\/]))*\*+\/)/gm,
  function(match)
  {
    comments.push(match);
    return '';
  });
</pre><h2 id="working-with-invisible-delimiters">3. Working With Invisible Delimiters</h2><p>Extracting content is all very well when it uses standard delimiters, but what if you&#8217;re using <strong>custom delimiters</strong> that only your program knows about? The problem there is that <strong>the string might already contain your delimiter</strong>, literally character for character, and then what do you?</p><p>Well, recently I came up with a very cute trick, that not only avoids this problem, it&#8217;s also as simple to use as the single-character class we saw at the start! The trick is to use <strong>unicode characters that the document can&#8217;t contain</strong>.</p><p>Originally I tried this with <em>undefined</em> characters, and that certainly worked, but it&#8217;s not safe to assume that any such character will always be undefined (or that the document won&#8217;t already contain it anyway). Then I discovered that Unicode actually reserves a set of code-points specifically for this kind of thing &#x2014; so-called <a
href="http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Noncharacters" title="Mapping of Unicode Characters (wikipedia.org)">noncharacters</a>, which will never be used to define actual characters. A valid Unicode document is not allowed to contain noncharacters, but a program can use them internally for its own purposes.</p><p>I was working on <abbr
title="Cascading Style Sheets">CSS</abbr> processor, and I needed to remove all the comments before parsing the selectors, so they wouldn&#8217;t confuse the selector-matching expressions. But they had to be replaced in the source with something that took up the same number of lines, so that the line-numbers would remain accurate. Then later they would have to be added back to the source, for final output.</p><p>So first we use a regex callback to extract and save the comments. The callback returns a copy of the match in which all non-whitespace is converted to space, and which is delimited with a noncharacter either side:</p><pre class="brush: jscript; title: ; notranslate">
var comments = [];
csstext = csstext.replace(/(\/\*([^*]|(\*+([^*\/])))*\*+\/)/gm,
  function(match)
  {
    comments.push(match);
    return '\ufddf' + match.replace(/[\S]/gim, ' ') + '\ufddf';
  });
</pre><p>That creates an array of comments in the same source-order as the spaces they leave behind, while the spaces themselves take-up as many lines as the original comment.</p><p>Then the originals can be restored simply by replacing each delimited space with its corresponding saved comment &#x2014; and since the delimiters are single characters, we only need a <strong>simple character class</strong> to match each pair:</p><pre class="brush: jscript; title: ; notranslate">
csstext = csstext.replace(/(\ufddf[^\ufddf]+\ufddf)/gim,
  function()
  {
    return comments.shift();
  });
</pre><p>How easy is that!</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/3-neat-tricks-with-regular-expressions/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Automatic Type Conversion In The Real World</title><link>http://www.sitepoint.com/automatic-type-conversion/</link> <comments>http://www.sitepoint.com/automatic-type-conversion/#comments</comments> <pubDate>Wed, 13 Mar 2013 21:29:54 +0000</pubDate> <dc:creator>James Edwards</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Raw Javascript]]></category> <category><![CDATA[data types]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[shorthand syntax]]></category> <guid
isPermaLink="false">http://www.sitepoint.com/?p=64413</guid> <description><![CDATA[James Edwards looks at two JavaScript shorthand expressions that rely on automatic type conversion, and discusses when they are - and are not - a good idea.]]></description> <content:encoded><![CDATA[<p></p><p>There are a few expressions that are commonly seen in JavaScript, but which some programming purists will tell you are never a good idea. What these expressions share is their reliance on <strong>automatic type conversion</strong> &#x2014; a core feature of JavaScript which is both a strength and a weakness, depending on the circumstances and your point of view.</p><p>So in this article I&#8217;d like to look at two of these expressions in particular, and consider the circumstances in which they are &#x2014; and are not &#x2014; a good idea.</p><p>The first of these expressions is a simple <code>if()</code> condition:</p><pre class="brush: jscript; title: ; notranslate">
if(foo)
{
}
</pre><p>The second is a variable assignment with a choice of possible values:</p><pre class="brush: jscript; title: ; notranslate">
var x = foo || bar;
</pre><p>If the <code>foo</code> and <code>bar</code> in those examples are both boolean values, then the expressions are simple: the first condition passes if <code>foo</code> is <code>true</code>; the second expression assigns <code>foo</code> to <var>x</var> if <code>foo</code> is <code>true</code>, or assigns <code>bar</code> to <var>x</var> if not.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>But what if they&#8217;re not simple booleans &#x2014; what if <code>foo</code> is an object, a string, or undefined? What if <code>foo</code> and <code>bar</code> are different data-types? To understand how these expressions will be evaluated, we need to understand how JavaScript automatically converts between data-types.</p><h2>Automatic Type Conversion</h2><p>JavaScript is a <strong>&quot;loosely typed&quot; language</strong>, which means that whenever an operator or statement is expecting a particular data-type, JavaScript will automatically convert the data to that type. The <code>if()</code> statement in the first example expects a boolean value, therefore whatever you define in the brackets will be converted to a boolean. The same is true for <code>while()</code> and <code>do...while()</code> statements.</p><p>JavaScript values are often referred to as being &quot;truthy&quot; or &quot;falsey&quot;, according to what the result of such a conversion would be (i.e. <code>true</code> or <code>false</code>). The simplest way to think of it  is like this: <strong>a value is truthy unless it&#8217;s known to be falsey</strong>; and in fact there are only <em>six</em> falsey values:</p><ul><li><code>false</code> (of course!)</li><li><code>undefined</code></li><li><code>null</code></li><li><code>0</code> (numeric zero)</li><li><code>""</code> (empty string)</li><li><code>NaN</code> (Not A Number)</li></ul><p>Notable exceptions are <code>"0"</code> (string zero) and all types of object &#x2014; which are truthy &#x2014; and this includes <em>all</em> primitive constructors, which means that <code>new Boolean(false)</code> evaluates to <code>true</code>! (Kinda confusing, but in practice you never need to create primitive values that way.)</p><p><i>Note: comparing two falsey values won&#8217;t always produce the result you might expect, for example <code>(null != false)</code> even though both are falsey values. There are some rather complex algorithms that determine how equality evaluations work, and it&#8217;s beyond the scope of this article to discuss them. But if you&#8217;re interested in the details, have a look at the <a
href="http://es5.github.com/#x11.9.3">The Abstract Equality Comparison Algorithm</a> which is part of <a
href="http://ecma-international.org/ecma-262/5.1/">ECMAScript 5.1</a>.</i></p><h2>The Condition Shortcut</h2><p>The <code>if()</code> example I showed you at the start converts its expression to a boolean, and since objects always evaluate to <code>true</code> while <code>null</code> evaluates to <code>false</code>, we can use a condition like that to test for the existence of <abbr
title="Document Object Model">DOM</abbr> elements:</p><pre class="brush: jscript; title: ; notranslate">
var element = document.getElementById(&quot;whatever&quot;);
if(element)
{
  //the element exists
}
else
{
  //the element doesn't exist
}
</pre><p>That will always work reliably when dealing with <abbr
title="Document Object Model">DOM</abbr> elements, because <strong>the DOM specification requires that a non-existent element returns <code>null</code></strong>.</p><p>However, other cases are not so clear-cut, like this example:</p><pre class="brush: jscript; title: ; notranslate">
function doStuff(foo)
{
  if(foo)
  {
    ...
  }
}
</pre><p>Conditions like that are frequently used to mean <em>&quot;if the <code>foo</code> argument is defined&quot;</em>, but there are several cases where that would fail &#x2014; namely, any cases where <code>foo</code> is a falsey value. So if, for example, it&#8217;s boolean <code>false</code> or an empty string, then the conditional code would not be executed, even though <code>foo</code> <em>is</em> defined.</p><p>This is what we want instead:</p><pre class="brush: jscript; title: ; notranslate">
function doStuff(foo)
{
  if(typeof foo != &quot;undefined&quot;)
  {
    ...
  }
}
</pre><p>Arguments (and other variables) which have not been defined, have a data-type of <code>"undefined"</code>. So we can use the <code>typeof</code> comparator to test the argument&#8217;s data-type, and then the condition will always pass if <code>foo</code> is defined at all. The <code>if()</code> expression is still evaluating a boolean, of course, but the boolean it&#8217;s evaluating is <em>the result</em> of that <code>typeof</code> expression.</p><h2>The Assignment Shortcut</h2><p>The second example I showed you at the start uses a logical operator, to determine which of two values should be assigned to a variable:</p><pre class="brush: jscript; title: ; notranslate">
var x = foo || bar;
</pre><p>Logical operators do not <em>return</em> a boolean, but they do still <em>expect</em> a boolean, so the conversion and evaluation happens internally. If <code>foo</code> evaluates to <code>true</code> then the <em>value of</em> <code>foo</code> is returned, otherwise the value of <code>bar</code> is returned. This is immensely useful.</p><p>This expression is commonly seen in event-handling functions, where it&#8217;s used to define an event argument according to the supported model:</p><pre class="brush: jscript; title: ; notranslate">
element.onclick = function(e)
{
  e = e || window.event;
};
</pre><p>So <code>e</code> is evaluated as a boolean, and that will be truthy (an event object) if the event-argument model is supported, or it will be falsey (undefined) if not; if it&#8217;s truthy then <code>e</code> is returned, or if not then <code>window.event</code> is returned.</p><p>The same kind of expression is also commonly used to assign event properties, finding the supported property by evaluating each possibility:</p><pre class="brush: jscript; title: ; notranslate">
var target = e.target || e.srcElement || window;
</pre><p>So each of those references is evaluated in turn (from left to right), and the first to evaluate to <code>true</code> will be returned. The first case handles the standard model, the second is for Internet Explorer, while the third is for Internet Explorer when the event might fire on the <code>window</code> object (which has no <code>srcElement</code> property).</p><p>But expressions like this are equally prone to failure, in cases where the truthy-ness of the data isn&#8217;t known. For example, another common use-case is to define defaults for optional arguments, but this is not good:</p><pre class="brush: jscript; title: ; notranslate">
function doStuff(foo)
{
  foo = foo || &quot;default value&quot;;
}
</pre><p>Now if you know for sure that <code>foo</code> will <em>always</em> be either a string or undefined, and assuming that an empty string should be treated as undefined, then that expression is safe. But if not, it will need to be re-defined to something more precise, like this for example:</p><pre class="brush: jscript; title: ; notranslate">
function doStuff(foo)
{
  if(typeof foo != &quot;string&quot;)
  {
    foo = &quot;default value&quot;;
  }
}
</pre><p>By testing the type against <code>"string"</code> we can handle multiple cases &#x2014; where <code>foo</code> is undefined, and also where it&#8217;s mis-defined as a non-string value. In that case we also allow an empty string to be valid input, but if we wanted to exclude empty strings, we&#8217;d have to add a second condition:</p><pre class="brush: jscript; title: ; notranslate">
function doStuff(foo)
{
  if(typeof foo != &quot;string&quot; || foo == &quot;&quot;)
  {
    foo = &quot;default value&quot;;
  }
}
</pre><p>There are other, surprisingly subtle cases where this can be a gotcha. For example, we might have a date function that creates a unix timestamp, unless an input timestamp is optionally defined:</p><pre class="brush: jscript; title: ; notranslate">
function doDateStuff(timestamp)
{
  timestamp = timestamp || new Date().getTime();
}
</pre><p>That would fail if the input is <code>0</code> &#x2014; because zero is a falsey value, but it&#8217;s also a valid timestamp.</p><h2>General Principles</h2><p>The general lesson to take from all this is simple &#x2014; <strong>think about how type conversion will affect evaluations</strong>, and take care not to fall into the gotchas we&#8217;ve encountered. With due care and attention, you <em>can</em> still take advantage of automatic type conversion, to shorten conditions and logical expressions wherever it&#8217;s appropriate.</p><p>It does rather beg the question though &#x2014; if we know that explicit testing using <code>typeof</code> is always safe, while relying on automatic type conversion sometimes isn&#8217;t &#x2014; then why not just be <em>explicit all the time</em>? Certainly, if the only reason for preferring the shorter syntax, is that it&#8217;s quicker to type, then that&#8217;s a lazy and sloppy reason.</p><p>But the fact is, JavaScript usually runs across a public network, in situations where <strong>file size makes a difference</strong>. Smaller files are faster loading, and use less bandwidth, and little syntax shortcuts can really add-up.</p><p>Taking advantage of shorter expressions is not an optimization as such, it&#8217;s just a coding style that makes the best of language features.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/automatic-type-conversion/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>A jQuery Plugin for Touch Swiping &#8211; Part 2 of 2</title><link>http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-2-of-2/</link> <comments>http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-2-of-2/#comments</comments> <pubDate>Thu, 07 Mar 2013 05:14:22 +0000</pubDate> <dc:creator>Chee How Chua</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[plugins]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2198</guid> <description><![CDATA[The second part of Chee How Chua's walkthrough of the steps to create a jQuery plugin that detects the horizontal swiping motion on touch devices such as the iPhone and Android-based devices.
]]></description> <content:encoded><![CDATA[<p></p><p>This is part two of two in the series describing how to create a jQuery plugin to detect and respond to swipe gestures.</p><p>In <a
href="http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-1-of-2/">the first part</a>, we saw how to create a plugin that changes a carousel&#8217;s pictures to correspond to the position of the finger on screen. In this part, we will extend that to detect a swipe gesture. This improves the carousel by creating fixed intervals so that a swipe changes the carousel to show the next/previous picture in its entirety.</p><pre class="brush: jscript; title: ; notranslate">var Swiper = function (el, callbacks, options) {
  ...
  this.opts = options;
  this.swipeDone = false;
  //perform binding
  this.el.addEventListener('touchend', function (evt) {
    tis.stop(evt);
  });
  ....
};
Swiper.LEFT = - 1;
Swiper.RIGHT = 1;
...
$.fn.swiper = function (callbacks, options) {
  var opts = $.extend({}, $.fn.swiper.defaults, options);
  if (typeof callbacks.swiping !== 'function') {
    throw '&amp;amp;amp;amp;quot;swiping&amp;amp;amp;amp;quot; callback must be defined.';
  }
  if (typeof callbacks.swiped !== 'function') {
    throw '&amp;amp;amp;amp;quot;swiped&amp;amp;amp;amp;quot; callback must be defined.';
  }
  if (typeof callbacks.swipeCancel !== 'function') {
    throw '&amp;amp;amp;amp;quot;swipeCancel&amp;amp;amp;amp;quot; callback must be defined.';
  }
  this.each(function () {
    ...
    if (!swiper) {
      tis.data('swiper', (swiper = new Swiper(this, callbacks, opts)));
    }
  });
};
$.fn.swiper.defaults = {
    tolerance: 100
};</pre><p>In the above listing, we see that the class constructor for <code>Swiper</code> is modified to accept a third parameter <code>options</code> that holds a single property <code>tolerance</code>. The parameter is assigned to an internal property <code>opts</code>. The <code>touchend</code> event is proxied to the <code>stop()</code> instance method of the <code>Swiper</code> class.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Additionally, two callback functions have been added (<code>swiped</code> and <code>swipeCancel</code>) to handle the swiping. The default value for <code>tolerance</code> is set as 100 (pixels). Notice there are also two class properties <code>Swiper.LEFT </code> and <code>Swiper.RIGHT</code>. They represent a left swipe and a right swipe respectively and will be used in subsequent listings.</p><p>The plugin definition is also modified to accept a second, optional, parameter that provides the choice to override the default threshold of 100 pixels.</p><p>We need to extend the plugin to recognise when a swipe has occurred and modify the carousel correspondingly. There are several scenarios we need to consider. The first, and most straightforward, is when the user drags a finger across the screen and releases it. If the finger covers a distance that is more than or equal to the <code>tolerance</code> value, we consider that a swipe, and the carousel should advance to the next image when the finger is lifted off the screen. The figure below illustrates this scenario.</p><p><img
src="http://jspro.com/files/2013/02/swipe1.png" caption="Beyond threshold - swipe detected." /></p><p>On the other hand, if the finger covers a distance that is less than the <code>tolerance</code> value, the movement is <em>not</em> considered a swipe and the carousel should revert to its original position.</p><p><img
src="http://jspro.com/files/2013/02/swipe2.png" caption="Within threshold - No swipe detected." /></p><p>Remember that the plugin moves the carousel to mirror the movement of the finger for the duration of contact with the screen. The decision as to whether to advance or revert the carousel position is taken when the finger is lifted off the screen (binding for the <code>touchend</code> event).</p><pre class="brush: jscript; title: ; notranslate">Swiper.prototype.stop = function (evt) {
  if (!this.swipeDone) {
    this.cbs.swipeCancel();
  } else {
    this.cbs.swiped(this.getDirection());
  }
};</pre><p>If a swipe is detected, invoke the callback for advancing the carousel (<code>swiped()</code>), otherwise revert the carousel (<code>swipeCancel()</code>).</p><p>One thing to note is that we are returning the direction of the movement to the &#8220;advancing&#8221; callback as determined by the <code>getDirection</code> method. This is required as the callback needs to know which direction to advance the carousel to.</p><pre class="brush: jscript; title: ; notranslate">Swiper.prototype.getDirection = function () {
  var direction = this.diff();
  if (direction &amp;amp;amp;amp;lt; 0) {
    return Swiper.LEFT;
  }
  if (direction &amp;amp;amp;amp;gt; 0) {
    return Swiper.RIGHT;
  }
};</pre><p>This method uses the <code>diff()</code> method defined in Part 1 of this series to get the displacement of the finger. If the difference is negative, it is a left swipe, otherwise it is a right swipe.</p><p>We now need to know how to determine whether a swipe is generated i.e. setting of the <code>swipeDone</code> flag. Before we delve into that though, let&#8217;s consider the next scenario.</p><p>If the user brings a finger to the screen, drags it beyond the threshold value, and then brings it back to within the threshold value before removing the finger, we don&#8217;t want to advance the carousel as the user&#8217;s intention, by bringing the finger back, is that he/she does not want to advance the carousel.</p><p><img
src="http://jspro.com/files/2013/02/swipe3.png" caption="Pulls back to within tolerance - No swipe"/></p><p>Similarly if the user brings the finger back beyond the tolerance value before removing the finger, his/her intention is to advance the carousel.</p><p><img
src="http://jspro.com/files/2013/02/swipe4.png" caption="Pulls back to beyond tolerance - Swipe detected" /></p><p>As you can imagine, the determination of when the gesture is detected is done while the finger is dragging on the screen, and not when the finger is lifted. We therefore have to make some changes to the <code>move()</code> instance method of the <code>Swiper</code> class.</p><pre class="brush: jscript; title: ; notranslate">Swiper.prototype.move = function (evt) {
  if (Math.abs(this.diff()) &amp;amp;amp;amp;gt;= this.opts.tolerance) {
    this.swipeDone = true;
  } else {
    this.swipeDone = false;
  }
  if (evt.targetTouches &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; evt.targetTouches.length === 1) {
    if (evt.targetTouches[0].offsetX) {
      this.points[1] = evt.targetTouches[0].offsetX;
    } else if (evt.targetTouches[0].layerX) {
      this.points[1] = evt.targetTouches[0].layerX;
    } else {
      this.points[1] = evt.targetTouches[0].pageX;
    }
    this.cbs.swiping(this.diff());
  }
};</pre><p>At the beginning of the <code>move()</code> method, we check if the distance moved by the finger has exceeded the tolerance value. The difference is encompassed in a <code>Math.abs()</code> function because a left movement will always generate a negative value which is less than any positive value. By taking its absolute value, we can check the distance for both left and right movements. If it is determined that the distance is larger than or equals to the tolerance value, we consider it a swipe.</p><p>A key point about making this work is the removal of the line <code>this.points[0] = this.points[1];</code> from the <code>move()</code> method. This is absolutely critical because we want to take reference from the point where the finger came into contact with the screen (<code>touchstart</code>). If we retain this line of code, the reference point will keep changing with each movement of the finger and we will not be able to perform the calculation that we want. With the removal of this line of code though, the value that <code>diff()</code> returns will also be different from before. We then have to change the definition of the <code>swiping()</code> callback function.</p><p>One last change to make to the <code>Swiper</code> class is to its <code>start()</code> instance method. This change basically says that every time a finger is first placed on screen, the <code>swipeDone</code> flag to false, which is natural since a swipe cannot have been generated when the finger first touches the screen.</p><pre class="brush: jscript; title: ; notranslate">Swiper.prototype.start = function (evt) {
  if (evt.targetTouches &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; evt.targetTouches.length === 1) {
    this.swipeDone = false;
    ...
  }
};</pre><p>We are pretty much done with the plugin itself. Changing the application code to utilise the plugin requires a paradigm shift in how we manipulate the carousel&#8217;s position while the finger is still dragging on screen. Remember that the carousel is supposed to &#8220;snap&#8221; to positions that show any of the images in its entirety. As a result, the value of the position is always a multiple of the width of each image. Thus it is easiest to represent the position as a percentage. Note that since we are treating the <code>currPos</code> value as a percentage, the values of <code>MAX_LEFT</code> and <code>MAX_RIGHT</code> need to be converted into percentages too.</p><p>We still want to retain the mirroring effect of the carousel on the finger. To do that, a new variable <code>adhocPos</code> is introduced in the <code>swiping()</code> callback. This value holds the position of the carousel as the finger drags on the screen. It uses the <code>baseWidth</code> variable which is set to 330 pixels (the width of each image in the carousel). This value <strong>must</strong> be changed if the width of an image in the carousel changes.</p><pre class="brush: jscript; title: ; notranslate">...
MAX_LEFT = -300,
MAX_RIGHT = 0,
baseWidth = 330;
cb = {
  swiping: function (displacement) {
    var adhocPos = currPos / 100 * baseWidth;
    adhocPos += displacement;
    pictures.css('left', adhocPos + 'px');
  },
  ...
}</pre><p>The <code>currPos</code> value is treated as a percentage which is set in the <code>swiped</code> callback below:</p><pre class="brush: jscript; title: ; notranslate">swiped: function (direction) {
  currPos += (direction * 100);
  if (currPos &amp;amp;amp;amp;lt; MAX_LEFT || currPos &amp;amp;amp;amp;gt; MAX_RIGHT) {
    //i.e. exceeded limit
    currPos -= (direction * 100);
  }
  pictures.css('left', currPos + '%');
}</pre><p>The callback is passed a <code>direction</code> parameter which, as we saw earlier, is either <code>1</code> or <code>-1</code>. This is then multiplied with 100 to convert into a percentage value before summing up with <code>currPos</code>. The <code>if</code> statement checks to make sure that the value remains within the boundaries so that the carousel does not scroll into empty space. This was previously done in the <code>swiping()</code> callback. By placing this check in the <code>swiped()</code> callback, we get the effect that when the user drags the carousel beyond the last image, we see white space but as soon as the finger is lifted, the carousel jumps back, thereby creating a sort of &#8220;bouncing&#8221; effect.</p><p>Lastly, there is the <code>swipeCancel()</code> callback which sets the carousel back to its original position before the dragging started.</p><pre class="brush: jscript; title: ; notranslate">swipeCancel: function () {
  pictures.css('left', currPos + '%');
}</pre><p>With the modifications we made to the plugin in this article we have a decent swiping carousel that works almost like a native app in your browser. Similarly, the plugin has been tested in the same browsers as stated in the first article. You can see the <a
title="See working demo" href="http://jspro.rojakcoder.com/touchswipe2">demo</a> or download the <a
title="Download ZIP file" href="http://jspro.rojakcoder.com/touchswipe2/touchswipe2.zip">source code</a> and have fun with them!</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-2-of-2/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>A jQuery Plugin for Touch Swiping &#8211; Part 1 of 2</title><link>http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-1-of-2/</link> <comments>http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-1-of-2/#comments</comments> <pubDate>Fri, 01 Mar 2013 09:00:06 +0000</pubDate> <dc:creator>Chee How Chua</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[plugins]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2084</guid> <description><![CDATA[This article will explain the steps to create a jQuery plugin that detects the horizontal swiping motion on touch devices such as the iPhone and Android-based devices.]]></description> <content:encoded><![CDATA[<p></p><p>This article will explain the steps to create a jQuery plugin that detects the horizontal swiping motion on touch devices such as the iPhone and Android-based devices. This article is the first in a two-part series. In this article, we will be creating an image carousel that can respond to the user&#8217;s input and change the position of the carousel accordingly. <a
href="http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-2-of-2/">The second article</a> will extend the plugin by adding swipe detection.<br
/> <span
id="more-2084"></span></p><h3>HTML &amp; CSS</h3><p>Before we go on to the JavaScript, let&#8217;s take a look at the HTML and CSS for the image carousel which will be used to demonstrate the Swiper plugin. The HTML is shown below.</p><pre class="brush: xml; title: ; notranslate">
&lt;div style=&quot;width: 330px; height: 200px;&quot;&gt;
  &lt;div id=&quot;target&quot;&gt;
    &lt;div&gt;
      &lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;rexy.jpg&quot; /&gt;&lt;/div&gt;
      &lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;xena.jpg&quot; /&gt;&lt;/div&gt;
      &lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;xenaagain.jpg&quot; /&gt;&lt;/div&gt;
      &lt;div&gt;&lt;img alt=&quot;&quot; src=&quot;rexyagain.jpg&quot; /&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre><p>Similarly, the carousel&#8217;s CSS is shown below.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre class="brush: css; title: ; notranslate">
img { /*100% width to scale the height proportionately*/
  width: 100%;
  margin: 0;
}
.frame {
  width: 100%;
  height: 100%;
  border: 1px solid #ccc;
  overflow: hidden;
  position: relative;
}
.pictures {
  position: absolute;
  width: 400%; /*change accordingly*/
  left: 0%;
}
.pictures:after {
  content: &quot;&#92;&#48;020&quot;;
  display: none;
  height: 0;
}
.pictures .pic {
  width: 25%; /*change with respect to .pictures*/
  float: left;
}
</pre><p>The inner container (<code>.pictures</code>) is set to 400% to contain four images. Each image&#8217;s container (<code>.pic</code>) is set to 25% so that the images end up at a width of 330 pixels. If you change the number of images or use absolute values instead of percentages, you&#8217;d want to change the width value of the <code>.pictures</code> and <code>.pic</code> elements accordingly.</p><p>The images are made to line up horizontally by floating to the left. The frame (<code>.frame</code>) is made to show only one image at a time. With this setup, we can then &#8220;slide&#8221; the carousel by changing the <code>left</code> property of the <code>.pictures</code> <code>&lt;div&gt;</code> element.</p><h3>JavaScript</h3><p>Here is the skeleton of the plugin:</p><pre class="brush: jscript; title: ; notranslate">
(function ($) {
  'use strict';
  var Swiper = function (el, callbacks) {
  }
  $.fn.swiper = function (callbacks) {
    if (typeof callbacks.swiping !== 'function') {
      throw '&quot;swiping&quot; callback must be defined.';
    }
    this.each(function () {
      var tis = $(this),
        swiper = tis.data('swiper');
      if (!swiper) { //i.e. plugin not invoked on the element yet
        tis.data('swiper', (swiper = new Swiper(this, callbacks)));
      }
    });
  };
}(jQuery));
</pre><p>This listing is boilerplate code for creating a jQuery plugin. The bulk of the complexity is handled by the internal class <code>Swiper</code>, whose methods are not yet defined. <code>Swiper</code> is responsible for reading the events produced by the browser and invoking the callback. The plugin is defined in a closure so that the <code>Swiper</code> class will not be mistakenly overridden by external code. The plugin is also prevented from binding to an element more than one time by associating the instantiated <code>Swiper</code> class with the <code>swiper</code> data attribute.</p><pre class="brush: jscript; title: ; notranslate">
var Swiper = function (el, callbacks) {
  var tis = this;
  this.el = el;
  this.cbs = callbacks;
  this.points = [0, 0];
  //perform binding
  this.el.addEventListener('touchstart', function (evt) {
    tis.start(evt);
  });
  this.el.addEventListener('touchmove', function (evt) {
    evt.preventDefault();
    tis.move(evt);
  });
};
</pre><p>In the above listing, the <code>Swiper</code> constructor instantiates the object&#8217;s properties and event handlers. The <code>points</code> property is a two-celled array that stores the starting position of the finger in the first cell, and the ending position in the second cell. We will see the usage of this array in subsequent listings. Its values are both initially zero.</p><p>The constructor binds the <code>touchstart</code> and <code>touchmove</code> events, and proxies the events to the corresponding methods in the <code>Swiper</code> class. The <code>touchstart</code> binding initializes the <code>points</code> array with the initial position of the finger. The <code>touchmove</code> binding gives us the movement of the finger, which we will pass to the callback function to offset the carousel accordingly.</p><pre class="brush: jscript; title: ; notranslate">
Swiper.prototype.start = function (evt) {
  if (evt.targetTouches &amp;&amp; evt.targetTouches.length === 1) {
    if (evt.targetTouches[0].offsetX) {
      this.points[0] = evt.targetTouches[0].offsetX;
    } else if (evt.targetTouches[0].layerX) {
      this.points[0] = evt.targetTouches[0].layerX;
    } else {
      this.points[0] = evt.targetTouches[0].pageX;
    }
    //make initial contact with 0 difference
    this.points[1] = this.points[0];
  }
};
</pre><p>The listing above shows the <code>start()</code> method, which takes the event and reads the set of touches generated on screen. In devices with multi-touch capability, which means nearly all modern smartphones and tablets, this property is an array storing the locations of all contact points with the screen. In this implementation, we are keeping track of one contact point as we are tracking a single swipe gesture which is done using one finger.</p><p>We are checking for the different properties of the touch event to accommodate the different implementations of the touch behaviour on different devices. This used to be required to make it <a
href="http://www.nogginbox.co.uk/blog/canvas-and-multi-touch">work for different devices</a>. Today, however, the devices that I have tested all generate the <code>pageX</code> property.</p><p>Since we are checking only for a horizontal swipe gesture, we ignore the <code>pageY</code> property. We also set the cells of the <code>points</code> property to the same value so that the initial difference between the starting and ending points is zero.</p><p>The function binding for the <code>touchmove</code> event and other helper methods are listed below.</p><pre class="brush: jscript; title: ; notranslate">
Swiper.prototype.diff = function () {
  return this.points[1] - this.points[0];
};
Swiper.prototype.move = function (evt) {
  if (evt.targetTouches &amp;&amp; evt.targetTouches.length === 1) {
    if (evt.targetTouches[0].offsetX) {
      this.points[1] = evt.targetTouches[0].offsetX;
    } else if (evt.targetTouches[0].layerX) {
      this.points[1] = evt.targetTouches[0].layerX;
    } else {
      this.points[1] = evt.targetTouches[0].pageX;
    }
    this.cbs.swiping(this.diff());
    this.points[0] = this.points[1];
  }
};
</pre><p>The <code>diff()</code> method simply calculates the difference between the last point (which changes as the user moves the finger) and the previous point. This is illustrated by the following figure.</p> <a
href="http://jspro.com/files/2013/02/image1.png"><img
class="size-full wp-image-2101 " alt="image1" src="http://jspro.com/files/2013/02/image1.png" width="239" height="166" /></a> Illustration of the Distance &#8220;Dragged&#8221; by a Finger.<p>The <code>move()</code> method also checks through the different properties to get the right one for storing into the second cell of the <code>points</code> property. After storing the value, the callback function is invoked with the difference between the previous position and the new position of the finger. The callback function is responsible for changing the position of the carousel. This is explained below.</p><p>After invoking the callback, the previous position&#8217;s value is replaced with the current position&#8217;s value. The next time the callback is invoked, the difference will be the displacement between the current position and the previous position instead of the starting position. This is required if we want the movement of the carousel to mirror that of the finger. Without this line, the carousel&#8217;s movement accumulates the difference and the result is a large displacement of images in response to a small movement of the finger, which is clearly undesirable for a smooth user experience.</p><p>The listing below invokes the plugin.</p><pre class="brush: jscript; title: ; notranslate">
var target = $('#target'),
  pictures = $('.pictures', target),
  MAX_LEFT = -990,
  MAX_RIGHT = 0,
  currPos = 0,
  cb = {
    swiping: function (displacement) {
      currPos += displacement;
      if (currPos &gt; MAX_RIGHT) {
        currPos = MAX_RIGHT;
      } else if (currPos &lt; MAX_LEFT) {
        currPos = MAX_LEFT;
      }
      pictures.css('left', currPos + 'px');
    }
  };
target.swiper(cb);
</pre><p>We get the element using its <code>id</code>. We also need a handle to the <code>.pictures</code> element within the target because the carousel&#8217;s positioning is changed by changing the <code>left</code> CSS property of this element.</p><p>We set the left and right limit of the carousel&#8217;s position with the <code>MAX_LEFT</code> and <code>MAX_RIGHT</code> variables. These values have to change in relation to the carousel&#8217;s size. They are used so that the user does not scroll the carousel to empty spaces. The <code>MAX_RIGHT</code> variable determines how far right the finger can drag the carousel to hit the left-most image. Naturally, this value is <code>0</code>. The <code>MAX_LEFT</code> variable limits how far left the finger can move the carousel. Since there are four images, to display the right-most one, the three images on the left have to be displaced. The values are derived like this:</p><p><code>330 (width of one image) * 3 = 990</code></p><p>We also have a variable, <code>currPos</code>, that stores the current position of the carousel. Alternatively, we can get the position of the carousel like so:</p><pre class="brush: jscript; title: ; notranslate">currPos = parseInt(pictures.css('left'));</pre><p>The preferred approach is to use the variable. The only reason is that of performance &#8211; retrieving the <code>left</code> property of the element and converting it into an integer definitely consumes more processing power than accessing a variable&#8217;s value. This is cognizant of the fact that we are adding behavior on top of a browser&#8217;s interface, so it is important that we keep the plugin lean.</p><p>The callback is specified as a property within a JSON literal. Why not simply pass it as a function? Well, this is to set the stage for part two of this series, where we will explain how to add swipe gesture detection to the plugin.</p><p>A final note: on iOS devices (iPhones and iPads), there is a bouncing effect on the browser window when you scroll the carousel. This is apparent if the carousel is near the bottom or the top (as is the case here) of the page. To prevent that from happening, we call the <code>preventDefault()</code> method on the <code>touchmove</code> event. Incidentally, by calling the <code>preventDefault()</code> method, it prevents the event from bubbling up the <abbr
title="Document Object Model">DOM</abbr> hierarchy, which in turn leads to better performance, especially apparent on slower devices such as the Nexus One. I&#8217;ve tested the plugin on the iPad 2 (iOS 6.0.1), Nexus One (Android 2.3.6), and Galaxy Note II (Android 4.1.2). If you have used any other devices/OS, feel free to let us know in the comments!</p><ul><li><a
href="http://jspro.rojakcoder.com/touchswipe1">Online Demo</a></li><li><a
href="https://github.com/jsprodotcom/source/blob/master/TouchSwipe.zip">Download Source Code</a></li></ul><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-1-of-2/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Building a Low Memory Web Application</title><link>http://www.sitepoint.com/building-a-low-memory-web-application/</link> <comments>http://www.sitepoint.com/building-a-low-memory-web-application/#comments</comments> <pubDate>Wed, 20 Feb 2013 09:00:01 +0000</pubDate> <dc:creator>Dmitri Lau</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Raw Javascript]]></category> <category><![CDATA[Low Memory]]></category> <category><![CDATA[Raw JavaScript]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2123</guid> <description><![CDATA[With the rise in mobile devices and tablets, web applications are frequently being loaded in slow and low memory environments. When building a web application, one may consider making design choices which reduce the amount of memory consumed by your application, so that the user experience remains fast and responsive. The general idea of reducing [...]]]></description> <content:encoded><![CDATA[<p></p><p>With the rise in mobile devices and tablets, web applications are frequently being loaded in slow and low memory environments. When building a web application, one may consider making design choices which reduce the amount of memory consumed by your application, so that the user experience remains fast and responsive.<br
/> <span
id="more-63980"></span></p><p>The general idea of reducing your application&#8217;s footprint is to reduce the amount of code in your application, thereby reducing the amount of physical memory it occupies. This includes functions, variables, event handlers, housekeeping code, etc.</p><h2>Tip 1: Use One Event Listener Over Multiple Event Listeners</h2><p>It is common to do the following to add event listeners to multiple nodes of the same group.</p><pre class="brush: jscript; title: ; notranslate">
$(&quot;#list .countries&quot;).on(&quot;click&quot;, function() {
  $(&quot;box&quot;).value = this.innerHTML;
});
</pre><p>If your website has 100 nodes, then you are adding an event listener 100 times. That means each of those 100 nodes is modified to respond to an <code>onclick</code> event, and every modification consumes extra memory in the form of reference pointers and state flags.</p><p>Next time consider doing it like this:</p><pre class="brush: jscript; title: ; notranslate">
$(&quot;#list&quot;).on(&quot;click&quot;, function() {
  if($(this).hasClass(&quot;countries&quot;)) $(&quot;box&quot;).value = this.innerHTML;
});
</pre><p>With this, you only need to listen to one parent node for the <code>onclick</code> event and saved 99 other nodes from getting fat, at the cost of a negligible amount of execution time.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>Tip 2: Use Inline Event Handlers Over External Event Handlers</h2><pre class="brush: xml; title: ; notranslate">
&lt;div onclick=&quot;menus.activate(event);&quot;&gt;activate&lt;/div&gt;
</pre><p>This tip will certainly get some people worked up. It is taken for granted that one should migrate away from inline event handlers, because it mixes behavior with content. With no disrespect to the &#8220;best practice&#8221; reasons for not using them, you will find that inline event handlers can add a lot of savings to your footprint.</p><p>First of all, you won&#8217;t need to write event registration code (i.e., <code>addEventListener()/removeEventListener()</code>) which will save you several lines of code at the very least. Your application also won&#8217;t need to spend time executing your JavaScript (your event registration functions), which is much slower than native code (the DOM parser). And as a side benefit, you won&#8217;t have to worry about memory leaks due to forgetting to unregister a handler, since the handler dies with the node.</p><p>You also won&#8217;t need to assign an ID to the node in order to reach it within your code, nor do you need to walk the DOM to find that node (a method popularized by jQuery). You just saved some footprint there, as well as preventing your application from doing extra work.</p><p>And, since inline event handlers can preserve context, it allow you to conserve memory by eliminating the need to create closures to encapsulate context. You may not be aware, but whenever you wrap an event handler with an anonymous function, you are creating that closure:</p><pre class="brush: jscript; title: ; notranslate">
node.addEventListener(&quot;click&quot;, function(e) {
  menus.activate(e);
}, false);
</pre><p>Some libraries hide this behind a helper function, but it is the same issue nonetheless:</p><pre class="brush: jscript; title: ; notranslate">
node.addEventListener(&quot;click&quot;, menus.activate.bind(menus), false);
</pre><p>The problem escalates because some libraries will create a new anonymous function for every event handler registration, which means the number of closures will grow linearly with the number of handler registrations, which means precious memory is wasted. With inline event handlers, you don&#8217;t need to create the extra function or the closure.</p><pre class="brush: xml; title: ; notranslate">
&lt;div onclick=&quot;menus.activate(event);&quot;&gt;activate&lt;/div&gt;
</pre><h2>Tip 3: Use Templates Over DOM Creation</h2><p>If you are creating anything other than a few nodes, it takes less code to generate a DOM tree by assigning a string of HTML to the <code>innerHTML</code> property, than it does to create the nodes one by one with <code>document.createElement()</code>. And, you don&#8217;t have to worry about your HTML content being confined within your JavaScript code, because you can hide it safely within your website, as shown below.</p><pre class="brush: xml; title: ; notranslate">
&lt;body&gt;
  &lt;script type=&quot;text/html&quot; id=&quot;mytemplate1&quot;&gt;
    &lt;div&gt;hello&lt;/div&gt;
  &lt;/script&gt;
&lt;/body&gt;
</pre><p>Notice how the HTML content won&#8217;t be rendered, because it is placed inside a <code>&lt;script&gt;</code> tag. The <code>&lt;script&gt;</code> tag also uses a <code>text/html</code> mimetype so that the browser won&#8217;t confuse it for JavaScript. You can retrieve the string with the following code.</p><pre class="brush: jscript; title: ; notranslate">
var text = document.getElementById(&quot;mytemplate1&quot;).innerHTML;
</pre><p>Often times we don&#8217;t want just plain text, but want text with embedded symbols that allow for dynamic variable substitutions. That is the job of the template library and it makes DOM creation using templates much more powerful. A small template library should reduce your footprint over DOM creation code in the long run.</p><h2>Tip 4: Consider Stateless Singletons over Stateful Objects</h2><p>Applications are composed of components, and each component is typically a DOM node backed by a JavaScript object to store data. The more components there are, the more JavaScript objects there are. But, if you can share the same JavaScript object with multiple DOM nodes, then you can save some memory by reusing the JavaScript object. Achieving this requires designing your JavaScript objects to behave like singletons. The component will have no state, and only serve to call the singleton to perform a generic function. Alternatively, it can store some basic data as an attribute on the DOM node and the singleton can read that data from the node and act on it.</p><p>In a more complex scenario, the DOM node can store a unique ID as an attribute and the singleton can map the ID to a complex data object stored elsewhere. (Further complexity is best left for a future article.)</p><p>This technique is most suited for components where a lot of them are used at the same time such as list items, or for components which are very simple and stateless such as buttons. For example:</p><pre class="brush: xml; title: ; notranslate">
&lt;input type=&quot;button&quot; onclick=&quot;GenericButton.onclick(event);&quot; data-command=&quot;copy&quot;&gt;
</pre><pre class="brush: jscript; title: ; notranslate">
GenericButton.onclick = function(e) {
  e = e.target || e.srcElement;
  var cmd = e.getAttribute(&quot;data-command&quot;);
  if(cmd == &quot;copy&quot;) //...
};
</pre><h2>Tip 5: Make Full Use of Prototypical Inheritance</h2><p>If you are instantiating a lot of objects of the same type, choose prototypical inheritance over property injection. When you inject properties into an object, you are copying references onto each object. This causes the number of references to grow linearly with the number of objects.</p><pre class="brush: jscript; title: ; notranslate">
function A() {
  this.value = 100;  //injecting value into this object
}
var obj1 = new A();
var obj2 = new A();
</pre><p>If you instead, allow those properties to be inherited, those references only exist once on the prototype of that object. Then, the number of references does not grow linearly unless the property&#8217;s value is modified later.</p><pre class="brush: jscript; title: ; notranslate">
function A() {
}
A.prototype.value = 100;
var obj1 = new A();
var obj2 = new A();
</pre><h2>Tip 6: Use the Publish-Subscribe System to Simplify Communication</h2><p>Rather than use the observer pattern (e.g., <code>addActionListener()</code>) to communicate between components, consider using the publish-subscribe pattern to communicate between them. The publish-subscribe pattern uses less code to engage in communication and allows your application to be more decoupled, thereby not requiring as much code to maintain the coupling. There are lots of implementations of the publish-subscribe system available on the web that are thrift with memory that you can use.</p><h2>Tip 7: Use Smaller Libraries When Possible</h2><p>This last tip is the most obvious. Large libraries consume a lot of memory, and small libraries consume less. There is a site dedicated to showcasing tiny libraries called <a
href="http://microjs.com" title="Microjs: Fantastic Micro-Frameworks and Micro-Libraries for Fun and Profit!" target="_blank">microjs</a> where you may be able to find a library that just serves up your needs and nothing more.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/building-a-low-memory-web-application/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Introduction to the HTML5 WebSockets API</title><link>http://www.sitepoint.com/introduction-to-the-html5-websockets-api/</link> <comments>http://www.sitepoint.com/introduction-to-the-html5-websockets-api/#comments</comments> <pubDate>Mon, 18 Feb 2013 09:00:18 +0000</pubDate> <dc:creator>Sandeep Panda</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[WebSockets]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2061</guid> <description><![CDATA[HTML5 has introduced many new interesting APIs, including WebSockets. WebSockets allow developers to create powerful real time applications by establishing socket connections between the browser and the server. In other words both the client and server can exchange data at any time because of a persistent connection. This tutorial explains how to use WebSockets to [...]]]></description> <content:encoded><![CDATA[<p></p><p>HTML5 has introduced many new interesting APIs, including WebSockets. WebSockets allow developers to create powerful real time applications by establishing socket connections between the browser and the server. In other words both the client and server can exchange data at any time because of a persistent connection. This tutorial explains how to use WebSockets to create real time web applications.<br
/> <span
id="more-63979"></span></p><h1>The Problem</h1><p>In real time applications, the connection between server and client must be persistent. So, in order to create an illusion of server initiated transfer long polling is usually used. WebSockets solve this issue by establishing a persistent socket connection between the client and server. Once the connection is established, it remains open until the client or server wants to close it. It significantly reduces the burden on the server and is best suited for low latency applications.</p><h1>Getting Started</h1><p>Opening a WebSocket connection is fairly simple. You just need to call the <code>WebSocket()</code> constructor to create a connection.</p><pre class="brush: jscript; title: ; notranslate">var connection=new WebSocket(&quot;ws://localhost:8787&quot;,['soap','json']);</pre><p><code>ws:</code> and <code>wss:</code> are the URL schemas for normal and secured WebSocket connections, respectively. The second parameter is used to define the sub protocol name which can be an array of strings or a string. However, the server will accept only one sub protocol. During the lifetime of the connection the browser will receive several events such as connection opened, message received and connection closed. To handle these events use the following code:<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre class="brush: jscript; title: ; notranslate">
var connection=new WebSocket(&quot;ws://localhost:8787&quot;,'json');
connection.onopen = function () {
  connection.send('Hello, Server!!'); //send a message to server once connection is opened.
};
connection.onerror = function (error) {
  console.log('Error Logged: ' + error); //log errors
};
connection.onmessage = function (e) {
  console.log('Received From Server: ' + e.data); //log the received message
};
</pre><p>As soon as the connection is opened, the browser sends a message to the server using <code>connection.send()</code>. If an error is encountered, the above code simply logs it. If at any time the server sends a message to the browser, the <code>onmessage</code> callback is fired. The event handler gets an event object, with the <code>data</code> property of the object containing the received message.</p><p>The <code>connection.send()</code> method can be used to send binary data as well. To do so you can use either a <code>Blob</code> or an <code>ArrayBuffer</code>. The following code demonstrates using an <code>ArrayBuffer</code> to send an image drawn on canvas to server.</p><pre class="brush: jscript; title: ; notranslate">
var image = canvas2DContext.getImageData(0, 0, 440, 300);
var binary_data = new Uint8Array(image.data.length);
for (var i = 0; i &lt; image.data.length; i++) {
  binary_data[i] = image.data[i];
}
connection.send(binary_data.buffer);</pre><p>Similarly, the received message can be a string or binary data. The binary data can be received as a <code>blob</code> or an <code>arraybuffer</code>.</p><h1>Simple WebSocket Application</h1><p>In order to a create a working application, you also need a server side implementation. It&#8217;s possible to use technologies like node.js, Java, .NET, Ruby, or C++ to create server side implementation. This section will show you how to create a simple application using WebSockets.</p><p>The sample application will allow the user to ask specific questions to server. The server side implementation is done using the Java jWebSocket framework on Windows 7. So, to get the environment set up follow these simple steps. I assume you have already installed the latest JDK (JDK 7)on your Windows 7 PC.</p><h3>Step 1</h3><p>Head over to <a
href="http://jwebsocket.org/downloads/downloads.htm">jWebSocket Downloads</a> and download the first zip which is marked as server.</p><h3>Step 2</h3><p>Unzip the archive, and place it somewhere in your C:\. Then, create a new environment variable named <strong>JWEBSOCKET_HOME</strong>, which references the root of your jWebSocket installation. This is the path to the jWebSocket-1.0 folder. Add the following JARs to your class path:</p><ul><li>JWEBSOCKET_HOME/libs/jWebSocketServer-1.0.jar</li><li>JWEBSOCKET_HOME/libs/jWebSocketServerAPI-1.0.jar</li><li>JWEBSOCKET_HOME/libs/jWebSocketCommon-1.0.jar</li></ul><h3>Step 3</h3><p>Create a new Java Source file and name it <code>SocketListener.java</code>. Add the following code to this file.</p><pre class="brush: jscript; title: ; notranslate">
import java.util.Date;
import java.text.SimpleDateFormat;
import org.jwebsocket.factory.JWebSocketFactory;
import org.jwebsocket.server.TokenServer;
import org.jwebsocket.kit.WebSocketServerEvent;
import org.jwebsocket.api.WebSocketServerListener;
import org.jwebsocket.api.WebSocketPacket;
import org.jwebsocket.config.JWebSocketConfig;
import org.jwebsocket.instance.JWebSocketInstance;
class JWebSocketListener implements WebSocketServerListener {
  public void processOpened(WebSocketServerEvent event) {
    System.out.println(&quot;Connection Opened&quot;);
  }
  public void processPacket(WebSocketServerEvent event, WebSocketPacket packet) {
    switch(packet.getString()){
      case &quot;1&quot;:
        packet.setString(&quot;My Name is jWebSocketServer&quot;);
        break;
      case &quot;2&quot;:
        packet.setString(&quot;Windows 7 64 Bit&quot;);
        break;
      case &quot;3&quot;:
        SimpleDateFormat sdf=new SimpleDateFormat(&quot;hh:mm:ss&quot;);
        packet.setString(sdf.format(new Date()));
        break;
    }
    event.sendPacket(packet);
  }
  public void processClosed(WebSocketServerEvent event) {
  }
}
public class SocketListener{
  public static void main(String[] args){
    JWebSocketFactory.printCopyrightToConsole();
    JWebSocketConfig.initForConsoleApp(new String[]{});
    JWebSocketFactory.start();
    TokenServer server = (TokenServer)JWebSocketFactory.getServer(&quot;ts0&quot;);
    if(server!=null) {
      server.addListener(new JWebSocketListener());
    }
    while (JWebSocketInstance.getStatus() != JWebSocketInstance.SHUTTING_DOWN){
      try {
        Thread.sleep(250);
      }
      catch (InterruptedException e) {
      }
    }
  }
}
</pre><h4>Explanation</h4><p>The code implements the <code>WebSocketServerListener</code> interface. The interface declares the following three methods which should be implemented in our class, <code>JWebSocketListener</code>.</p><ul><li><code>processOpened()</code></li><li><code>processPacket()</code></li><li><code>processClosed()</code></li></ul><p><code>processOpened()</code> is called once a connection is opened. An example use of this will be starting a thread that sends updates to client in regular intervals. Similarly, <code>processClosed()</code> is called when the connection closes so that you can perform any clean ups.</p><p>In our application, the major processing is done in <code>processPacket()</code>. This method is called whenever the browser sends a message to the server. It receives two objects, of types <code>WebSocketServerEvent</code> and <code>WebSocketPacket</code>. First, we use <code>WebSocketPacket#getString()</code> to read the message (which is a question asked by the client). Depending on the question the server sends an answer. The message to be sent is wrapped inside a <code>WebSocketPacket</code> using <code>WebSocketPacket#setString()</code>. Then, we call <code>WebSocketServerEvent#sendPacket()</code>, passing the packet as an argument. Next, we create a public class called <code>SocketListener</code>. This class starts a WebSocket implementation server and registers our custom listener to it.</p><h3>Step 4</h3><p>Compile <code>SocketListener.java</code>, and start your server using the command <code>java SocketListener</code>.</p><h3>Step 5</h3><p>Now that you have done the server side implementation, it&#8217;s time to create the client that will interact with the server. The following is our initial HTML markup:</p><pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;WebSocket Test&lt;/title&gt;
    &lt;style&gt;
      #response{
        width: 200px;
        background: #F2F2F2;
        padding: 120px 0px 120px 0px;
        font-size:18px;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div align=&quot;center&quot;&gt;
      Choose a question to ask:
      &lt;select id=&quot;question&quot; name=&quot;question&quot; onchange=&quot;sendMessage(this.value);&quot;&gt;
        &lt;option value=&quot;1&quot;&gt;What's Your Name&lt;/option&gt;
        &lt;option value=&quot;2&quot;&gt;Which OS You Are Running On?&lt;/option&gt;
        &lt;option value=&quot;3&quot;&gt;What Time Is It?&lt;/option&gt;
      &lt;/select&gt;
      &lt;br/&gt;&lt;br/&gt;
      &lt;div id=&quot;response&quot;&gt;
        My Name is jWebSocketServer
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre><p>Now, add the following JavaScript to the HTML:</p><pre class="brush: jscript; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot;&gt;
var connection = new WebSocket('ws://localhost:8787', 'json');
connection.onopen = function () {
  console.log('Connection Opened');
};
connection.onerror = function (error) {
  console.log('WebSocket Error ' + error);
};
connection.onmessage = function (e) {
  if(e.data.indexOf(&quot;subProtocol&quot;)==-1)
    document.getElementById(&quot;response&quot;).innerHTML=e.data+&quot;&lt;br/&gt;&quot;;
};
function sendMessage(msg){
  connection.send(msg);
}
&lt;/script&gt;
</pre><h4>Explanation</h4><p>We created an HTML file that allows users to choose questions from a drop down menu. When an <code>onchange</code> event fires, we take the value of the selected item and send that value to the server. The server then processes the request and sends back an answer to the browser. When the message from the server is received, the <code>onmessage</code> callback is executed, which shows the response in the <code>response</code> <code>&lt;div&gt;</code>. The line <code>if(e.data.indexOf("subProtocol")==-1)</code> is not mandatory. I have included it because initially when the connection is opened, the server sends a long string containing information to the browser. As we don&#8217;t want to show this string, I have included the above condition.</p><p><strong>Note:</strong> Don&#8217;t directly open this HTML file. Put it in the <code>localhost</code> server and then access it in the browser.</p><h1>Conclusion</h1><p>Using the WebSocket API, you can create very powerful real time applications. But, keep in mind that cross origin communication is allowed by WebSockets. So, you should only communicate with servers and clients that you trust. The following are a few example apps that you can create with this API:</p><ul><li>Realtime Social Stream Updating</li><li>HTML5 Multiplayer Games</li><li>Online Chat Applications</li></ul><p>Check out <a
href="https://developer.mozilla.org/en-US/docs/WebSockets">Mozilla Developer Network</a> to learn more about the WebSockets API.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/introduction-to-the-html5-websockets-api/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>A Study in Experimental Game Development</title><link>http://www.sitepoint.com/a-study-in-experimental-game-development/</link> <comments>http://www.sitepoint.com/a-study-in-experimental-game-development/#comments</comments> <pubDate>Fri, 15 Feb 2013 09:00:22 +0000</pubDate> <dc:creator>James Edwards</dc:creator> <category><![CDATA[Gaming]]></category> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Gaming]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2054</guid> <description><![CDATA[How do you take a nebulous idea and turn it into a game — to get from technical details, to something interesting and challenging? Well recently, I found myself wondering whether CSS transitions could be used to make some kind of game. This article is about the exploration of that idea, and its development into [...]]]></description> <content:encoded><![CDATA[<p></p><p>How do you take a nebulous idea and turn it into a game — to get from technical details, to something interesting and challenging? Well recently, I found myself wondering whether <a
title="Using CSS transitions (MDN)" href="https://developer.mozilla.org/en-US/docs/CSS/Tutorials/Using_CSS_transitions">CSS transitions</a> could be used to make some kind of game. This article is about the exploration of that idea, and its development into an elegant and (as far as I know) unique kind of game-play.</p><p><span
id="more-63978"></span></p><h2>The Basic Idea</h2><p>The basic idea was to animate the <code>left</code> and <code>top</code> positions of an object, using a slow transition that the player partly controls. So, we&#8217;re going to need a playing area — let&#8217;s call that the <strong>board</strong>, and an animated object — let&#8217;s call that the <strong>ball</strong>:</p><pre class="brush: xml; title: ; notranslate">
&amp;lt;body&amp;gt;
  &amp;lt;div id=&amp;quot;board&amp;quot;&amp;gt;
    &amp;lt;span id=&amp;quot;ball&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
</pre><p>The board has an aspect ratio of 3:2, while the ball is 5% of its width. Neither of those values are particularly crucial, they&#8217;re just what seemed most fitting — the aspect ratio was chosen so that it could (eventually) fit onto an iPhone screen, and the ball made relatively small so it has plenty of space to move around. The basic layout, with the ball at the top-left corner of the board is shown in the following demo.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><ul><li><strong><a
href="http://jspro.brothercake.com/ease/demo1-board.html">Demo 1: The Board and Ball</a></strong></li></ul><p>The ball has negative margins, to offset it by half its own width and height, so that whatever position we set on the ball will be its center origin (e.g. the ball in that first demo is positioned at <code>0,0</code>). Here&#8217;s the CSS for that demo:</p><pre class="brush: css; title: ; notranslate">
#board
{
  position:relative;
  display:block;
  width:720px;
  height:480px;
  margin:24px auto 0 auto;
  border-radius:2px;
  background:#fff;
  box-shadow:0 0 16px -2px rgba(0,0,0, 0.5);
}
#ball
{
  position:absolute;
  left:0;
  top:0;
  display:block;
  width:36px;
  height:36px;
  margin:-18px 0 0 -18px;
  border-radius:18px;
  background:#f00;
  box-shadow:inset 0 0 0 2px rgba(0,0,0, 0.35), 4px 10px 10px rgba(0,0,0, 0.15);
}
</pre><p>Ideally we would apply the board and ball sizes dynamically, based on the available window or screen space (this would be essential to port the game to mobile browsers), but to keep these examples simple, the dimensions are fixed — the board is 720×480 and the ball is 36×36.</p><p>The range of possible movement for the ball can now be described in percentage co-ordinates — from <code>0%,0%</code> at the top-left to <code>100%,100%</code> at the bottom-right. Using percentages is simpler than calculating pixels, and will allow for future flexibility in the sizes.</p><p>Now we can easily control the position by applying some simple JavaScript, that sets the <code>left</code> or <code>top</code> position according to directional key-presses, i.e. if the <kbd>Left Arrow</kbd> is pressed then set <code>style.left</code> to <code>"0"</code>, or if the <kbd>Down Arrow</kbd> is pressed then set <code>style.top</code> to <code>"100%"</code>:</p><pre class="brush: jscript; title: ; notranslate">
var
ball = document.getElementById('ball'),
positions =
{
  37  : ['left', '0'],
  38  : ['top', '0'],
  39  : ['left', '100%'],
  40  : ['top', '100%']
};
document.addEventListener('keydown', function(e, data)
{
  if(data = positions[e.keyCode])
  {
    ball.style[data[0]] = data[1];
    e.preventDefault();
  }
}, false);
</pre><p>The <code>positions</code> array defines a property and value for each arrow <code>keyCode</code>, and is also used in the first condition to know whether an arrow-key was pressed at all, in which case we have to use <code>preventDefault()</code> to block its native action (so that the page can&#8217;t scroll at the same time). Again for the sake of simplicity, I haven&#8217;t done any feature-detection to filter older browsers. In practice we would want to pre-test the browser, to make sure that the transitions are fully supported. The following demo allows moving the ball to any corner.</p><ul><li><strong><a
href="http://jspro.brothercake.com/ease/demo2-moving.html">Demo 2: Moving The Ball</a></strong></li></ul><p>Next, let&#8217;s add a slow <code>transition</code> rule to animate movements. Notice the inclusion of vendor prefixes.</p><pre class="brush: css; title: ; notranslate">
#ball
{
  -moz-transition:all 5s ease;
  -ms-transition:all 5s ease;
  -o-transition:all 5s ease;
  -webkit-transition:all 5s ease;
  transition:all 5s ease;
}
</pre><p>Now the arrow-key changes don&#8217;t trigger a snap movement, they trigger a slow and gradual movement of the ball across the board. And since each key-press only changes the <code>left</code> <em>or</em> <code>top</code> position (never both), the overall effect is a novel and rather elegant kind of movement — a kind of &#8220;elasticity&#8221; that would be much more complex to script:</p><ul><li><strong><a
href="http://jspro.brothercake.com/ease/demo3-elastic.html">Demo 3: Elastic Movement</a></strong></li></ul><p>Try, for example, the following actions in that demo:</p><ol><li>Refresh the page to reset the ball</li><li>Then press <kbd>Right Arrow</kbd> once</li><li>Wait until the ball is half-way across (after 2.5 seconds)</li><li>Then press <kbd>Down Arrow</kbd> once</li></ol><p>Pressing <kbd>Right Arrow</kbd> will start a transition that moves the ball rightwards, then pressing <kbd>Down Arrow</kbd> will trigger a second transition that moves it downwards. But the second transition doesn&#8217;t affect the first, which will still be going, and the overall effect is a <strong>smooth curve</strong> — describing an arc from the top-center down to the bottom-right.</p><h2>Refining the Game Play</h2><p>We can now move the ball anywhere inside the board, using the arrow-keys to suggest a direction of movement. This provides control, but not <em>full</em> control, and therein lies the basic challenge that makes for a playable game. The amount of control we have also varies, because of the way the transitions are applied. For example, if the ball is at <code>"left:0"</code> when you press the <kbd>Right Arrow</kbd>, it will take five seconds to reach the right-edge (as expected). However, if the ball is already at <code>"left:80%"</code> when you press the <kbd>Right Arrow</kbd>, it will <em>still</em> take the full five seconds to travel that much smaller distance to the right-edge. In other words, the speed of the ball depends on how close it is to the direction you specify, when changing to that direction.</p><p>The choice of transition timing-function also makes a big difference. In these examples I&#8217;ve used the <code>"ease"</code> function, which equates to the following <a
title="Understanding CSS cubic-bezier (Adventures in Code)" href="http://roblaplaca.com/blog/2011/03/11/understanding-css-cubic-bezier/">bezier curve</a>:</p><p>[image src="http://jspro.com/files/2013/02/ease-bezier.png" caption="The <code>"ease"</code> timing-function represented as a bezier curve"]</p><p>The graph shows relative speed, and illustrates how it accelerates at the start, then decelerates towards the end. So the ball will move more slowly near the start and end of the transition, and this will make it slightly easier to control at those points. In fact you could make the ball almost stand still, by rapidly and continually changing its direction.</p><h2>Adding the Real Challenge</h2><p>We&#8217;ve got a nice playable action now, but we still don&#8217;t have a game. There has to be something challenging — something you actually have to <em>do</em> within that restricted control. Perhaps we can use the same transition to add that extra something?</p><p>Since we&#8217;ve already defined the transition to apply to <code>"all"</code> properties, we can simply extend the JavaScript so that each arrow-key also applies a <strong>change in background color</strong>, with a different bold color to correspond with each direction:</p><pre class="brush: jscript; title: ; notranslate">
var
ball = document.getElementById('ball'),
positions =
{
  37  : ['left', '0'],
  38  : ['top', '0'],
  39  : ['left', '100%'],
  40  : ['top', '100%']
},
colors =
{
  37  : '255,0,0',
  38  : '255,255,0',
  39  : '0,0,255',
  40  : '0,255,255'
};
document.addEventListener('keydown', function(e, data)
{
  if(data = positions[e.keyCode])
  {
    ball.style[data[0]] = data[1];
    ball.style.backgroundColor = 'rgb(' + colors[e.keyCode] + ')';
    e.preventDefault();
  }
}, false);
</pre><p>And now, by pressing the arrow-keys, we not only change the ball&#8217;s position but also its primary color. Let&#8217;s also shift the ball&#8217;s default position to the center, and set its default color to gray (i.e. to a medium-bright color it will never have during play):</p><ul><li><strong><a
href="http://jspro.brothercake.com/ease/demo4-color.html">Demo 4: Color Change</a></strong></li></ul><p>But of course, the color doesn&#8217;t instantly change, it gradually fades from one to another over the course of a single transition, passing through various intermediate shades along the way. For example, if the ball is red and then you press <kbd>Right Arrow</kbd>, it will change from red to blue via various shades of purple (as well as moving to the right).</p><p>Since each direction has a different color, it&#8217;s also possible for the same movement to result in different colors. For example, if you press <kbd>Right Arrow</kbd> then quickly press <kbd>Down Arrow</kbd>, the ball will travel to the bottom-right corner and fade to cyan (because cyan is mapped to down). However, if you press those keys in the opposite order (down and then right), the ball will still move to the same corner, but this time fade to blue (because blue is mapped to right). So for any given physical position, there are any number of possible shades of color that the ball might have.</p><p>And now I think, we have everything we need to make a game. If it&#8217;s difficult to fully control the ball, and difficult to get it to be a <em>specific</em> color, then we can create a game challenge by saying that you have to <strong>get the ball to a specific position and a specific color</strong>.</p><h2>The Final Game Prototype</h2><p>We&#8217;ll add a series of additional elements with different background colors — let&#8217;s call them the <strong>targets</strong> — and then add scripting that monitors the position and color of the ball. If the ball is inside a target area while it&#8217;s also the same color, then we call that a match, and the target disappears. That&#8217;s easy to describe, but it&#8217;s rather convoluted to actually script, as shown below.</p><pre class="brush: jscript; title: ; notranslate">
var targets =
[
  { &amp;quot;color&amp;quot; : [220,180,40], &amp;quot;coords&amp;quot; : [5,5,12,35] },
  { &amp;quot;color&amp;quot; : [210,80,80], &amp;quot;coords&amp;quot; : [45,2.5,10,40] },
  { &amp;quot;color&amp;quot; : [160,90,60], &amp;quot;coords&amp;quot; : [65,5,20,20] },
  { &amp;quot;color&amp;quot; : [100,100,150], &amp;quot;coords&amp;quot; : [2.5,75,35,15] },
  { &amp;quot;color&amp;quot; : [150,70,100], &amp;quot;coords&amp;quot; : [55,65,10,20] },
  { &amp;quot;color&amp;quot; : [70,230,150], &amp;quot;coords&amp;quot; : [87.5,60,10,20] }
];
for(var len = targets.length, i = 0; i &amp;lt; len; i ++)
{
  var target = document.createElement('div');
  target.className = 'target';
  target.style.left = targets[i].coords[0] + '%';
  target.style.top = targets[i].coords[1] + '%';
  target.style.width = targets[i].coords[2] + '%';
  target.style.height = targets[i].coords[3] + '%';
  target.style.backgroundColor = 'rgb(' + targets[i].color.join(',') + ')';
  targets[i].target = ball.parentNode.insertBefore(target, ball);
}
var tracking = window.setInterval(function()
{
  var ballcolor = window.getComputedStyle(ball).backgroundColor.replace(/[^0-9,]/g, '').split(',');
  for(var n = 0; n &amp;lt; 3; n++)
  {
    ballcolor[n] = parseInt(ballcolor[n], 10);
  }
  for(var i = 0; i &amp;lt; targets.length; i ++)
  {
    if
    (
      ball.offsetLeft &amp;gt; targets[i].target.offsetLeft
      &amp;amp;&amp;amp;
      ball.offsetLeft + ball.offsetWidth &amp;lt; targets[i].target.offsetLeft + targets[i].target.offsetWidth
      &amp;amp;&amp;amp;
      ball.offsetTop &amp;gt; targets[i].target.offsetTop
      &amp;amp;&amp;amp;
      ball.offsetTop + ball.offsetHeight &amp;lt; targets[i].target.offsetTop + targets[i].target.offsetHeight
    )
    {
      var match = 0;
      for(var n = 0; n &amp;lt; 3; n ++)
      {
        if(Math.abs(ballcolor[n] - targets[i].color[n]) &amp;lt; 40)
        {
          match ++;
        }
      }
      if(match === 3)
      {
        targets[i].target.parentNode.removeChild(targets[i].target);
        targets.splice(i, 1);
        if(targets.length === 0)
        {
          window.clearInterval(tracking);
          window.setTimeout(function(){ alert('Yay!'); }, 250);
        }
      }
    }
  }
}, 62.5);
</pre><p>We have to allow for a certain amount of leeway when comparing the colors. We can&#8217;t expect the ball and target to be <em>exactly</em> the same (that would be all-but impossible), so we subtract one from the other and allow for a maximum difference. It&#8217;s because we need to do that, that the colors are applied using <abbr
title="Red Green Blue">RGB</abbr>, since RGB values are easier to work with programatically:</p><pre class="brush: jscript; title: ; notranslate">
var match = 0;
for(var n = 0; n &amp;lt; 3; n ++)
{
  if(Math.abs(ballcolor[n] - targets[i].color[n]) &amp;lt; 40)
  {
    match ++;
  }
}
if(match === 3)
{
  //... all three channels are sufficiently close
}
</pre><p>The tracking code itself is wrapped in a single <code>setInterval()</code> loop, which (as far as I know) is the only way of continually monitoring the ball&#8217;s properties — using <code>getComputedStyle()</code> along with offset properties, to get the ball&#8217;s color and position at each iteration. The interval shouldn&#8217;t be so fast as to put excessive strain on the browser, but it does still have to be fast enough to be <strong>accurate</strong> — based on the size and speed of the ball. Since the ball is 5% of the board, and moves the whole distance in five seconds, the ball will take an average <code>250ms</code> to move by its own width. So whatever proportion of that we use for the interval, will represent the maximum <em>tracking drift</em> as a proportion of the ball size, i.e. the maximum amount of discrepancy between the ball&#8217;s interval-calculated position, and its actual position. The speed I&#8217;ve set is <code>62.5ms</code>, which gives a maximum drift of one-quarter the ball&#8217;s size. Frankly, that&#8217;s a little faster than I&#8217;d have liked, but any slower than that will not be sufficiently accurate, and could give rise to a failure to detect valid matches.</p><p>It would all be much easier if there were some kind of per-frame callback event for CSS transitions, but there isn&#8217;t — the only event we have is a <code>transitionend</code> event, which fires at the end of a transition, but that&#8217;s no use to us here.</p><p>But anyway — we have a game now! Try the finished prototype below and see how you get on — the object of the game is to <strong>match every target until the board is clear</strong>:</p><ul><li><strong><a
href="http://jspro.brothercake.com/ease/demo5-prototype.html">Demo 5: Final Prototype</a></strong></li></ul><h2>Beyond the Prototype</h2><p>Nothing really happens when you&#8217;ve finished though, and it only has this one round! This is just a prototype, and even as it is, there are still refinements we could make. For example, if we restricted the ball&#8217;s movement so it&#8217;s not allowed to touch the edge, that would make the game-play more challenging and more edgy.</p><p>So join me soon for the <em>second and concluding part</em> of this article, in which we&#8217;ll look at how (and indeed, whether) we can develop this prototype further, into a finely-honed and distributable game.</p><p>In the meantime, you can download a zipfile of all this article&#8217;s demos:</p><ul><li><strong><a
href="https://github.com/jsprodotcom/source/blob/master/EaseGame.zip">Download the demos</a></strong></li></ul><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/a-study-in-experimental-game-development/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Fun with JavaScript Numbers</title><link>http://www.sitepoint.com/fun-with-javascript-numbers/</link> <comments>http://www.sitepoint.com/fun-with-javascript-numbers/#comments</comments> <pubDate>Sat, 09 Feb 2013 15:19:35 +0000</pubDate> <dc:creator>Colin Ihrig</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Raw Javascript]]></category> <category><![CDATA[Raw JavaScript]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2042</guid> <description><![CDATA[Data types are an essential component of every programming language, and numbers are perhaps the most important of all data types. After all, computers are really just expensive calculators. Like any worthwhile programming language, JavaScript supports numerical data. However, like many other aspects of JavaScript, numbers have several intricacies which can bite you if you&#8217;re [...]]]></description> <content:encoded><![CDATA[<p></p><p>Data types are an essential component of every programming language, and numbers are perhaps the most important of all data types. After all, computers are really just expensive calculators. Like any worthwhile programming language, JavaScript supports numerical data. However, like many other aspects of JavaScript, numbers have several intricacies which can bite you if you&#8217;re not careful. This article explores numerical data and some of its quirks.<br
/> <span
id="more-63977"></span></p><p><strong>Note -</strong> Before reading this article, you should have a basic familiarity with <a
href="http://cjihrig.com/blog/javascript-data-types/" title="JavaScript Data Types" target="_blank">JavaScript data types</a>.</p><h2>The <code>Number</code> Type</h2><p>In JavaScript, all numbers are represented using the Number data type. This includes integers, real numbers, hexadecimal numbers, and numbers written in scientific notation. The following example verifies this by applying the <a
href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/typeof" title="typeof - JavaScript | MDN" target="_blank"><code>typeof</code></a> operator to a variety of numbers. Each application of <code>typeof</code> in this example returns <code>number</code>.</p><pre class="brush: jscript; title: ; notranslate">
typeof(100);
typeof(3.14);
typeof(0xDEADBEEF);
typeof(7.89e2);
</pre><p>In the previous example, the numbers took on a variety of formats. However, internally, all JavaScript numbers are actually represented as <a
href="http://en.wikipedia.org/wiki/IEEE_floating_point" title="IEEE floating point - Wikipedia" target="_blank">IEEE 754</a> <a
href="http://en.wikipedia.org/wiki/Floating_point" title="Floating point - Wikipedia" target="_blank">floating point</a> data. This is important because it means that JavaScript has no concept of integers, despite the language&#8217;s <a
href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt" title="parseInt - JavaScript | MDN" target="_blank"><code>parseInt()</code></a> function. It also means that JavaScript math is not 100% accurate. For example, consider the following expression.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre class="brush: jscript; title: ; notranslate">
(0.1 + 0.2) === 0.3
</pre><p>If you are unfamiliar with floating point numbers, you would certainly expect this expression to evaluate to <code>true</code>. After all, 0.1 + 0.2 does equal 0.3. However, due to the way floating point numbers work, the sum is actually 0.30000000000000004. The difference is slight, but it is enough to cause the entire expression to evaluate as <code>false</code>.</p><h2>Positive and Negative Zero</h2><p>Another quirk of the IEEE 754 standard is the signed zero. This results in <a
href="http://css.dzone.com/articles/javascripts-two-zeros" title="JavaScripts Two Zeros  | Web Builder Zone" target="_blank">two zeroes</a> &#8211; a positive zero, +0, and a negative zero, -0. This may seem strange, but the fun is just beginning. Clearly, these are two distinct values, otherwise there would only be a single zero. However, if you display either of the zeroes, the sign is dropped. For example, the following code attempts to display the two zero values, side-by-side.</p><pre class="brush: jscript; title: ; notranslate">
alert((+0) + &quot; &quot; + (-0));
// displays 0 0
</pre><p>To make matters worse, JavaScript&#8217;s comparison operators can&#8217;t seem to tell the two values apart either, as shown in the following example.</p><pre class="brush: jscript; title: ; notranslate">
alert((+0 === -0));
// displays true
alert((-0 &lt; +0));
// displays false
</pre><p>There is a fairly simple workaround for this problem. In JavaScript, division by zero yields <code>Infinity</code>. Similarly, division by negative zero yields <code>-Infinity</code>. Therefore, to determine if a number is equal to -0, we must check that it is a zero, then perform division with it as the denominator, and check for <code>-Infinity</code> as shown below.</p><pre class="brush: jscript; title: ; notranslate">
function isNegativeZero(x) {
  return (x === 0 &amp;&amp; (1/x) === -Infinity);
}
</pre><h2>Not-a-Number</h2><p>JavaScript actually defines a number named Not-a-Number, or <code><a
href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/NaN" title="NaN - JavaScript | MDN" target="_blank">NaN</a></code>. <code>NaN</code> is a <a
href="http://cjihrig.com/blog/truthy-and-falsy-in-javascript/" title="Truthy and Falsy in JavaScript" target="_blank">falsy</a> value that is used to represent non-numbers as numbers. This value is interesting because its very name precludes it from being a number, yet <code>typeof(NaN)</code> is <code>number</code>. <code>NaN</code> is also fun because it is the only value in JavaScript that does not equal itself. For example, the following code will return <code>false</code>.</p><pre class="brush: jscript; title: ; notranslate">
alert((NaN === NaN));
// displays false
</pre><p>Instead of using the comparison operators, you can test for <code>NaN</code> using the <a
href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isNaN" title="isNaN - JavaScript | MDN" target="_blank"><code>isNaN()</code></a> function, as shown below.</p><pre class="brush: jscript; title: ; notranslate">
isNaN(1);
// returns false
isNaN(NaN);
// returns true
</pre><p>However, <code>isNaN()</code> is also fun because it can be misleading. If you pass in a value that can be coerced to a number, <code>isNaN()</code> will return <code>false</code>. In the following example, <code>isNaN()</code> is called with several values that are clearly not numbers. However, each call returns <code>false</code>.</p><pre class="brush: jscript; title: ; notranslate">
isNaN(true);
isNaN(false);
isNaN(&quot;&quot;);
isNaN(null);
// all return false
</pre><p>A better way to check for <code>NaN</code> is by exploiting the fact that it is not equal to itself. The following function tests for <code>NaN</code> using strict inequality. This function will only return <code>true</code> for the value <code>NaN</code>.</p><pre class="brush: jscript; title: ; notranslate">
function isNotANumber(x) {
  return x !== x;
}
</pre><h2>Other Fun Times</h2><p>There are a few other scenarios which can lead to problems with numbers. For starters, you should beware of old browsers that allow global properties like <code>Infinity</code>, <code>NaN</code>, and <code>undefined</code> to be redefined to new values. For example, the following code could create a lot of problems if <code>NaN</code> is used frequently. Luckily, modern browsers will ignore assignments to the previously mentioned properties. <a
href="http://cjihrig.com/blog/javascripts-strict-mode-and-why-you-should-use-it/" title="JavaScript’s Strict Mode and Why You Should Use It" target="_blank">Strict mode</a> goes one step further by turning these silent failures into errors.</p><pre class="brush: jscript; title: ; notranslate">
NaN = 1;
...
isNaN(NaN);
// now returns false
</pre><p>Another fun to diagnose error comes from adding a number and a string. An example of this is shown below. In this case, string concatenation overrides addition. This causes <code>foo</code> to be converted to the string <code>"100"</code>. The final result is the string <code>"1001"</code>, which is much different from the expected value of 101. This type of error is more common than you think, and tends to occur when reading user input.</p><pre class="brush: jscript; title: ; notranslate">
var foo = 100;
var bar = &quot;1&quot;;
alert(foo + bar);
// displays &quot;1001&quot;
</pre><h2>Conclusion</h2><p>This article has explored some of the idiosyncrasies of numbers in JavaScript. Hopefully, you now understand why these issues arise, and how you can avoid them. And, although you may not run into cases like the negative zero very often, at least now you are prepared.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/fun-with-javascript-numbers/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Event Delegation with jQuery</title><link>http://www.sitepoint.com/event-delegation-with-jquery/</link> <comments>http://www.sitepoint.com/event-delegation-with-jquery/#comments</comments> <pubDate>Fri, 08 Feb 2013 09:00:50 +0000</pubDate> <dc:creator>Ian Oxley</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[events]]></category> <guid
isPermaLink="false">http://jspro.com/?p=2026</guid> <description><![CDATA[jQuery makes event handling in JavaScript easy. However, the more event handlers you define, the more memory you use, which can end up decreasing performance and making the UI sluggish. This article looks at how event delegation can help prevent this, and how you can apply event delegation with jQuery. Event delegation is an event [...]]]></description> <content:encoded><![CDATA[<p></p><p>jQuery makes event handling in JavaScript easy. However, the more event handlers you define, the more memory you use, which can end up decreasing performance and making the UI sluggish. This article looks at how event delegation can help prevent this, and how you can apply event delegation with jQuery.<br
/> <span
id="more-63976"></span></p><p>Event delegation is an event handling technique where, instead of attaching event handlers directly to every element you want to listen to events on, you attach a single event handler to a parent element of those elements to listen for events occurring on it&#8217;s descendant elements. When handling the event, you check which element fired the event, and respond accordingly. Event delegation relies on event bubbling in the DOM. This is the process whereby an event triggered on a child element propagates up the DOM tree to its parent element, and its parent&#8217;s parent element, etc., until the <code>document</code> is reached. Bubbling can also be stopped by the programmer using <a
href="http://api.jquery.com/event.stopPropagation/"><code>event.stopPropagation()</code></a>. Note that not all DOM events propagate &#8211; focus, blur, load, and unload don&#8217;t.</p><p>Event delegation uses less memory because you replace multiple event handlers with a single event handler. For example, if you attach event handlers to each link in a list of ten links, you&#8217;d have ten event handlers taking up space in memory. If, instead, you use event delegation and handle events at the parent <code>&lt;ul&gt;</code> element, you only create one event handler and use less memory than you would&#8217;ve attaching to each link individually. In addition to reduced memory consumption, event delegation also has the following benefits.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><ul><li>No need to manually manage events when elements are added or removed from the DOM. If we used traditional event handling, we&#8217;d have to attach event handlers to elements added to the DOM, and remove event handlers from elements removed from the DOM.</li><li>Less code to manage, through fewer event handling functions. This can leave us with simpler code, without any duplicated event handling logic, which can help keep our JavaScript nice and <a
href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</li></ul><h2>An Example of Event Delegation in jQuery</h2><p>Suppose you&#8217;re developing a single page application that sells pictures of kittens. When the page loads, the first 20 kittens are displayed. As the user scrolls down the page, more kittens are loaded. Our HTML is shown below.</p><pre class="brush: xml; title: ; notranslate">
&lt;section id=&quot;cats&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;
      &lt;img src=&quot;http://placekitten.com/200/200&quot; alt=&quot;&quot;/&gt;
      &lt;a href=&quot;/moreinfo&quot;&gt;More info&lt;/a&gt;
      &lt;button&gt;Add to cart&lt;/button&gt;
    &lt;/li&gt;
    ...
  &lt;/ul&gt;
&lt;/section&gt;
</pre><p>With traditional event handling, we&#8217;ll need to wire up event handlers to:</p><ol><li>Display a larger picture when the user clicks on a thumbnail.</li><li>Display more info when the user clicks on the &#8216;More info&#8217; link.</li><li>Add the picture to the shopping cart when the user clicks &#8216;Add to cart&#8217;.</li><li>Attach these three events to the new DOM elements that are added as the user scrolls down the page.</li></ol><p>This code will resemble the following example. Note that this is boilerplate code intended to show how attaching event handlers to individual elements differs from using event delegation, so no implementation is given for the <code>loadImage()</code>, <code>moreInfo()</code>, <code>addToCart()</code>, and <code>loadNewKittens()</code> functions.</p><pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {
  var cats = $('#cats');
  cats.find('img')
    .on('click', function() {
      loadImage();
    })
  cats.find('a')
    .on('click', function(event) {
      event.preventDefault();
      moreInfo();
    });
  cats.find('button')
    .on('click', function() {
      addToCart();
    });
  $(window).scroll(function() {
    var fragment = loadNewKittens();
    // attach event handlers for new DOM elements
    fragment.find('img')
      .on('click', function() {
        loadImage();
      });
    fragment.find('a')
      .on('click', function(event) {
        event.preventDefault();
        moreInfo();
      });
    fragment.find('button')
      .on('click', function() {
        addToCart();
      });
    fragment.appendTo('#cats ul');
  });
});
</pre><p>That&#8217;s quite a bit of code. Now let&#8217;s see how our code looks if instead we use event delegation:</p><pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {
  $('#cats')
    .on('click', 'img, a, button', function(event) {
      event.preventDefault();
      var target = event.target;
  switch(target.tagName.toLowerCase()) {
    case 'img':
      loadImage();
      break;
    case 'a':
      moreInfo();
      break;
    case 'button':
      addToCart();
      break;
    default:
      // do nothing
  }
});
  $(window).scroll(function() {
    var fragment = loadNewKittens();
    fragment.appendTo('#cats ul');
  });
});
</pre><p>The key is the optional second argument to <a
href="http://api.jquery.com/on/"><code>on()</code></a>. By passing a selector here, <code>on()</code> knows it&#8217;s dealing with a delegated event handler rather than a directly bound event handler.</p><p>Our event handling code is a lot simpler now too. By getting a hold of <a
href="http://api.jquery.com/event.target/"><code>event.target</code></a>, and switching on it&#8217;s <code>tagName</code>, we can tell which element fired the event and can respond appropriately. Plus, we no longer have to attach event handlers for elements loaded in <code>$(window).scroll</code>, as the events fired by these new elements are delegated to the parent element.</p><p>A potential &#8216;gotcha&#8217; to be aware of when using event delegation is that any event handlers attached to child elements are handled <em>before</em> the deletated event handler fires. Therefore, it&#8217;s possible for a child event handler to call <code>event.stopPropagation()</code> or <code>return false</code>, which will prevent the event from bubbling up to the delegated event handler, and leave you scratching your head as to why your event isn&#8217;t being delegated.</p><h2>Conclusion</h2><p>In this article we&#8217;ve looked at event delegation. We&#8217;ve seen how it can help improve the performance of your site by lessening the event handling load it has to bear. We&#8217;ve also seen how to implement event delegation in jQuery via the <code>on()</code> function.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/event-delegation-with-jquery/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Why We Develop jQuery Plugins</title><link>http://www.sitepoint.com/why-we-develop-jquery-plugins/</link> <comments>http://www.sitepoint.com/why-we-develop-jquery-plugins/#comments</comments> <pubDate>Wed, 06 Feb 2013 09:00:26 +0000</pubDate> <dc:creator>Rakhitha Nimesh</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[plugins]]></category> <guid
isPermaLink="false">http://jspro.com/?p=1997</guid> <description><![CDATA[jQuery is one of the most popular JavaScript libraries among web developers and designers. And, many new plugins with amazing effects are created every day. Developers and users tend to select jQuery plugins whenever possible. If you&#8217;re still on the fence about jQuery, this article will help you understand why they are so popular. A [...]]]></description> <content:encoded><![CDATA[<p></p><p>jQuery is one of the most popular JavaScript libraries among web developers and designers. And, many new plugins with amazing effects are created every day. Developers and users tend to select jQuery plugins whenever possible. If you&#8217;re still on the fence about jQuery, this article will help you understand why they are so popular.<br
/> <span
id="more-63975"></span></p><p>A plugin is an independent module that adds custom functionality to an application. Enabling or disabling a plugin does not affect the core system or other plugins. As developers, we tend to look for quick fixes rather than focusing on maintainable solutions. With experience we change our approach to consider maintainability and future enhancements. To understand why plugins are such an attractive option, we must first understand what life would be like without them.</p><h2>Developing Without Plugins</h2><p>Assume that we have been given the task of converting a menu comprised of unordered lists into a select box. This will be a very handy feature to have in our responsive web design toolkit. So, we are going to use it as our base example for understanding why we develop jQuery plugins. Let&#8217;s look at a basic jQuery implementation.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
$(document).ready(function(){
  var select = $('&lt;select&gt;');
  $('#menu li').each(function() {
    var link  = $(this).find('&gt; a');
    var level = $(this).parents('li').length;
    var indent = '';
    for(i=0;i&lt;level;i++){
      indent += '-';
    }
    var option = $('&lt;option&gt;').text(indent + ' ' + link.text())
       .val(link.attr('href'))
       .appendTo(select);
  });
  $('#menu').replaceWith(select);
});
&lt;/script&gt;
</pre><p>The code snippet above converts the unordered list items into options inside a select box. You can see that the unordered list ID is hard coded. If we wanted to convert another list to a select box, we would have to duplicate the existing code, which can be error prone. Instead, we convert the code into a function to make it reusable. The code should be similar to the following:</p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
function convertMenusToSelect(menu){
  // Previous code with dynamic item instead of hard coding #menu
}
&lt;/script&gt;
</pre><p>Now, we have a common function that we can reuse over and over again. But, suddenly a new customer requirement comes in with the following two tasks.</p><ul><li>Selected menu options should be highlighted in a given color.</li><li>The indentation sign used for the sub menus should be dynamic.</li></ul><p>The immediate solution would be to add another two parameters to the <strong>convertMenusToSelect()</strong> function to handle both color and indentation sign. However, as more requirements comes in, we will have to add additional parameters, making it hard to maintain. Instead, we can consider passing parameters as an object, as shown below.</p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
function convertMenusToSelect(params){
}
var params={menuID: '#menu', color:'#EEE', indentMark : '#' };
convertMenusToSelect(params);
&lt;/script&gt;
</pre><p>There can be both mandatory and optional parameters within the object, so we need to check for the parameters manually in order to extract the correct values. As new requirements comes in, our solution is becoming very hard to maintain. So, let&#8217;s look at a solution using a jQuery plugin and see how it handles the changing requirements.</p><h2>Developing With jQuery Plugins</h2><p>We started the list-to-select box converter with plain jQuery code, and converted it to a reusable function in the process. Now, let&#8217;s look at a jQuery plugin implementation using the following code.</p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
(function($){
  $.fn.extend({
    selectConvert: function(options) {
      var defaults = {
        color: '#EEE',
        indentMark: '-',
      }
      var options =  $.extend(defaults, options);
      this.each(function() {
        var o = options;
        var currentItem = $(this);
        var select = $('&lt;select&gt;');
        $(currentItem).find('li').each(function() {
          var link  = $(this).find('&gt; a');
          var level     = $(this).parents('li').length;
          var indent = '';
          for(i=0;i&lt;level;i++){
            indent += o.indentMark;
          }
          var option = $('&lt;option&gt;').text(indent + ' ' + link.text())
            .val(link.attr('href')).css('background',o.color)
            .appendTo(select);
        });
        $(currentItem).replaceWith(select);
        return select;
      });
    }
  });
})(jQuery);
&lt;/script&gt;
</pre><p>In the above code <code>selectConvert</code> will be our plugin name, and will be a separate namespace inside the jQuery.fn object. Each of the plugin methods will be placed inside the <code>selectConvert()</code> function. The plugin function uses a variable called <code>options</code> to handle the data passed on initialization. The <code>defaults</code> variable contains all of the allowed variables and their default values. We can also assign functions to the <code>defaults</code> section.</p><p>Then, we compare the <code>defaults</code> against the options passed to the plugin using the jQuery <code>extend()</code> function. The final output will contain the passed option values and default values which are not provided in the initialization. Hence, adding new parameters is not such a difficult task with jQuery plugins. Finally, we execute the conversion code with the provided options and returns the converted item.</p><h2>The Importance of jQuery Plugins</h2><p>We made the decision to implement a plugin due to the issues we had with the plain jQuery implementation. Now, let&#8217;s see why we prefer jQuery plugins over pure JavaScript implementations.</p><ul><li><strong>Prevents Function Conflicts</strong><p>We create all the plugin related functions inside a unique namespace. So, the possibility of name conflicts is reduced with plugins.</li><li><strong>Extendability</strong><p>jQuery plugins automate the process of extending parameters and functions within the plugin. We can define the default parameters and functions inside the plugin and override them at runtime using extended values and functions. This reduces the work of handling required and optional parameters.</li><li><strong>Chainability</strong><p>I would assume chainability is the most powerful factor in jQuery plugins. In pure JavaScript we have to call functions, assign the results to variables, and pass them to the next function. With jQuery, we can call another function or plugin on the same returned results in one line of code. Consider the following code, which combines a jQuery autocomplete select box plugin with our design. You can chain together any number of functions or plugins on the same result set, making it easy to add and remove functionality dynamically.</p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
$(document).ready(function() {
  $('#menu').selectConvert().combobox();
});
&lt;/script&gt;
</pre></li><li><strong>Reusability</strong><p>jQuery plugins allows us to use the same functionality over multiple elements without duplicating code. We used a single menu in our initialization code as shown below.</p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
$(document).ready(function() {
  $('#menu').selectConvert();
});
&lt;/script&gt;
</pre><p>Generally, we need to use two lines for converting two menus. But jQuery makes is possible to reuse the same line of initialization code for both menus as shown in the following code.</p><pre class="brush: jscript; title: ; notranslate">
&lt;script&gt;
$(document).ready(function() {
  $('#menu,#menu2').selectConvert();
});
&lt;script&gt;
</pre></li><li><strong>Encapsulation</strong><p>We can define both public and private functions inside a jQuery plugin. Therefore, we can encapsulate the logic inside the plugin and decide which components are publicly visible and which are private to the plugin. So, plugin developers and users will only be able to call features publicly available.</li><li><strong>Usability</strong><p>Most of the people who uses jQuery plugins are not very experienced with JavaScript or jQuery. As developers, we need to make it as simple as possible to use the plugins. jQuery plugins provides a common initialization technique, where you can call the plugin initialization function on any compatible element. Therefore, users can just copy the initialization code and everything will work.</li></ul><h2>Conclusion</h2><p>We have used one of the most basic patterns of jQuery plugins in this tutorial. There are also several advanced patterns which make it even easier to write highly maintainable and extendable code. As a developer, you might be wondering why we can&#8217;t do the same with plain JavaScript. jQuery is built using JavaScript, so JavaScript <em>is</em> capable of providing anything jQuery provides. However, we prefer to use jQuery since it abstracts many common tasks and allows us to focus on application logic.</p><p>It&#8217;s time to share your opinion on jQuery plugins vs pure JavaScript implementation. Do you prefer developing and using jQuery plugins? Let us know. You can also download the code used in this article from the <a
href="https://github.com/jsprodotcom/source/blob/master/Why-We-Develop-jQuery-Plugins.zip" title="Source Code" target="_blank">JSPro GitHub page</a>.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/why-we-develop-jquery-plugins/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Intelligent String Abbreviation</title><link>http://www.sitepoint.com/intelligent-string-abbreviation/</link> <comments>http://www.sitepoint.com/intelligent-string-abbreviation/#comments</comments> <pubDate>Wed, 30 Jan 2013 09:00:04 +0000</pubDate> <dc:creator>James Edwards</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Raw Javascript]]></category> <category><![CDATA[functions]]></category> <guid
isPermaLink="false">http://jspro.com/?p=1973</guid> <description><![CDATA[For the seventh article in the small-and-sweet functions series, I&#8217;d like you show you a function called abbreviate() — the main purpose of which I&#8217;m sure you can guess! It abbreviates a string to a specified maximum length, but it does so intelligently — ensuring that the split will never occur in the middle of [...]]]></description> <content:encoded><![CDATA[<p></p><p>For the seventh article in the small-and-sweet functions series, I&#8217;d like you show you a function called <code>abbreviate()</code> — the main purpose of which I&#8217;m sure you can guess! It abbreviates a string to a specified maximum length, but it does so intelligently — ensuring that the split will never occur in the middle of a word, as well as pre-processing the string to remove extraneous whitespace.</p><p><span
id="more-63972"></span></p><p>Here&#8217;s the <code>abbreviate</code> function&#8217;s code:</p><pre class="brush: jscript; title: ; notranslate">
function abbreviate(str, max, suffix)
{
  if((str = str.replace(/^\s+|\s+$/g, '').replace(/[\r\n]*\s*[\r\n]+/g, ' ').replace(/[ \t]+/g, ' ')).length &lt;= max)
  {
    return str;
  }
  var
  abbr = '',
  str = str.split(' '),
  suffix = (typeof suffix !== 'undefined' ? suffix : ' ...'),
  max = (max - suffix.length);
  for(var len = str.length, i = 0; i &amp;lt; len; i ++)
  {
    if((abbr + str[i]).length &amp;lt; max)
    {
      abbr += str[i] + ' ';
    }
    else { break; }
  }
  return abbr.replace(/[ ]$/g, '') + suffix;
}
</pre><p>The function takes <strong>three arguments</strong> — the original input string, the maximum output length, and an optional suffix to add to the end of the abbreviated string. If the suffix is not defined then it defaults to <code>" ..."</code> (a space followed by three dots), which is a common and recognisable way of indicating abbreviation.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>What the Function&#8217;s For</h2><p>The function can be used whenever you need to limit the length of a string, as a more-intelligent alternative to a simple <code>substr</code> expression. There are any number of possible applications — such as processing form input, creating custom tooltips, displaying message subjects in a web-based email list, or pre-processing data to be sent via Ajax.</p><p>For example, to limit a string to <code>100</code> characters and add the default suffix, we&#8217;d call it like this:</p><pre class="brush: jscript; title: ; notranslate">
str = abbreviate(str, 100);
</pre><p>Which is notionally equivalent to this <code>substr</code> expression:</p><pre class="brush: jscript; title: ; notranslate">
str = str.substr(0, 96) + &quot; ...&quot;
</pre><p>But that&#8217;s a very blunt instrument, as it will often result in an output string which is split in the middle of a word. The <code>abbreviate</code> function is specifically designed not to do that, and will split the string <em>before</em> the last word rather than in the middle of it. So the output string produced by <code>abbreviate()</code> will often be <em>shorter</em> than the specified maximum — but it will <strong>never be longer</strong>.</p><p>The function also accounts for the space required by the abbreviation suffix, i.e. if the specific maximum if <code>100</code> but the suffix itself is 4 characters, then we can only use up to 96 characters of the main input string.</p><p>You can specify no suffix at all by passing an empty-string, or if you wanted to abbreviate a markup string then you can define it as an <abbr
title="HyperText Markup Language">HTML</abbr> close-tag. For example, the following input:</p><pre class="brush: jscript; title: ; notranslate">
abbreviate(&quot;&lt;p&gt;One two three four five&lt;/p&gt;&quot;, 15, &quot;&lt;/p&gt;&quot;);
</pre><p>Would produce this output:</p><pre class="brush: xml; title: ; notranslate">
&lt;p&gt;One two&lt;/p&gt;
</pre><h2>How the Function Works</h2><p>The key to the <code>abbreviate</code> function is the ability to split an input string into individual words, then to re-compile as many of the words as will fit into the maximum length.</p><p>To make this effective, we need to ensure that the splits between words are predictable, and the simplest way to do that is by <strong>minimising internal whitespace</strong> — converting line-breaks and tabs to spaces, and then reducing contiguous spaces, so that every chunk of internal whitespace becomes a single space. There are other ways of handling that, of course — for example, we could define a more flexible regular-expression for the <code>split</code>, that accounts for all the different kinds of character we might find between words. There&#8217;s even a word-boundary character for regular-expressions (<code>"\b"</code>) so we could just use that.</p><p>But I&#8217;ve found that the whitespace pre-processing is useful in its own right, especially when it comes to user input. And splitting by word-boundary doesn&#8217;t produce the desired results, since dashes, dots, commas, and most special characters in fact, count as word-boundaries. But I don&#8217;t think it&#8217;s appropriate to split the words by punctuation characters, unless the character is followed by a space, so that things like hyphenated words and code-fragments are not split in the middle.</p><p>So the function&#8217;s first job is to do that whitespace pre-processing, and then if the result is <em>already shorter</em> than the specified maximum, we can return it straight away:</p><pre class="brush: jscript; title: ; notranslate">
if((str = str.replace(/^\s+|\s+$/g, '').replace(/[\r\n]*\s*[\r\n]+/g, ' ').replace(/[ \t]+/g, ' ')).length &lt;= max)
{
  return str;
}
</pre><p>If we didn&#8217;t do that, then we might get cases where the string becomes abbreviated when it doesn&#8217;t have to be, for example:</p><pre class="brush: jscript; title: ; notranslate">
abbreviate(&quot;Already long enough&quot;, 20)
</pre><p>Without that first condition we&#8217;d get abbreviated output, since the specified maximum has to account for the length of the suffix:</p><pre class="brush: xml; title: ; notranslate">
Already long ...
</pre><p>Whereas adding that first condition produces unmodified output:</p><pre class="brush: xml; title: ; notranslate">
Already long enough
</pre><p>So unless we return at that point, we proceed to compile the abbreviated string — splitting the input string by spaces to create individual words, then iteratively adding each word-space pair back together, for as long as the abbreviated string is shorter than the specified maximum.</p><p>Once we&#8217;ve compiled as much as we need, we can break iteration, and then trim the residual space from the end of the abbreviated string, before adding the suffix and finally returning the result. It may seem a little wasteful to right-trim that residual space, only to add it back with the default suffix, but by doing so we allow for an input suffix to have no space at all.</p><h2>Conclusion</h2><p>So there you have it — a simple but intelligent function for abbreviating strings, which also pre-processes the input to remove extraneous whitespace. In my experience, these two requirements are often found together, and that&#8217;s why I&#8217;ve developed the function to work this way.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/intelligent-string-abbreviation/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>An Overview of the JavaScript History API</title><link>http://www.sitepoint.com/an-overview-and-usage-of-javascript-history-api/</link> <comments>http://www.sitepoint.com/an-overview-and-usage-of-javascript-history-api/#comments</comments> <pubDate>Mon, 28 Jan 2013 09:00:06 +0000</pubDate> <dc:creator>Sandeep Panda</dc:creator> <category><![CDATA[APIs]]></category> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <guid
isPermaLink="false">http://jspro.com/?p=1936</guid> <description><![CDATA[Modern web applications can access a user&#8217;s browsing history using the History API. As of HTML5 you can also manipulate history entries with great flexibility. This tutorial gives an overview of JavaScript&#8217;s History API, and explains how to use this feature while designing modern web applications. Controlling History The History API allows developers to add, [...]]]></description> <content:encoded><![CDATA[<p></p><p>Modern web applications can access a user&#8217;s browsing history using the History API. As of HTML5 you can also manipulate history entries with great flexibility. This tutorial gives an overview of JavaScript&#8217;s History API, and explains how to use this feature while designing modern web applications.<br
/> <span
id="more-1936"></span></p><h1>Controlling History</h1><p>The History API allows developers to add, remove, and replace history entries, altering the behavior of the Back and Forward buttons. Additionally, you can extract state information and use it to manipulate the content of a document. All of this is done using the <code>history</code> object &#8211; a property of <code>window</code>.</p><h2>Moving Backward and Forward</h2><p>The <code>history</code> object offers two useful methods for cycling through user history, <code>back()</code> and <code>forward()</code>. Calling <code>history.back()</code> will take the user one step back in the browser&#8217;s history. This has same effect as hitting the Back button. Similarly, calling <code>history.forward()</code> has the same effect as pressing the browser&#8217;s Forward button.</p><h2>Moving to a Specific History Point</h2><p>The <code>history</code> object provides another method, <code>go()</code>, which takes the user to a specific history point. For example, if you call <code>history.go(-3)</code> it will take the user back three pages. Similarly, calling <code>history.go(3)</code> will take the user three pages forward. Calling <code>history.go(-1)</code> and <code>history.go(1)</code> have the same effects as calling <code>history.back()</code> and <code>history.forward()</code>, respectively.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p><strong>Note:</strong> IE allows developers to pass URLs to <code>go()</code>. However, this is not standard, and should be avoided.</p><h2>Counting the Number of History Entries</h2><p>The number of pages in history can be found by accessing the <code>history</code> object&#8217;s length property, as shown below.</p><pre class="brush: jscript; title: ; notranslate">
alert(history.length);
</pre><h1>Manipulating History Entries</h1><p>The <code>history</code> object provides two methods, <code>pushState()</code> and <code>replaceState()</code>, for adding and replacing history entries.</p><h2>Using <code>pushState()</code></h2><p>Let&#8217;s say the following code is executed on <code>http://localhost/index.html</code>:</p><pre class="brush: jscript; title: ; notranslate">
history.pushState({page:2},&quot;Page 2&quot;,&quot;page2.html&quot;);
</pre><p>This will cause the browser to change the URL of the current page to <code>http://localhost/page2.html</code>. But, it will not change the content of the page or reload it. The browser won&#8217;t even check that <code>page2.html</code> exists. It will simply display the URL in the address bar.</p><p>Now, suppose you visit <code>http://jspro.com</code> and hit the Back button. The browser will load <code>http://localhost/page2.html</code> as it was added to the history stack previously. As the page is loaded, it will also receive a <code>popstate</code> event. In the above JavaScript code we passed an object to <code>pushState()</code> as the first argument (this is known as <code>state</code> object). We can retrieve this object from the <code>popstate</code> event&#8217;s <code>state</code> property and use it to manipulate the content of the document.</p><p>The <code>pushState()</code> method takes the following three parameters:</p><ol><li>State Object &#8211; This object is associated with the new history entry that&#8217;s being added to the stack.</li><li>Title &#8211; The title of the new history entry. Currently Firefox ignores this parameter, but it may be used in future.</li><li>URL &#8211; The URL to display to the user. It can be absolute or relative, but the URL should be of same origin as the current URL. Otherwise, the method will throw an exception.</li></ol><p>To reinforce the concept of pushing states, assume we have three pages: <code>index.html</code>, <code>page1.html</code>, and <code>page2.html</code>. The HTML content of <code>index.html</code> is shown below.</p><pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Demo Page&lt;/title&gt;
    &lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;input type=&quot;button&quot; id=&quot;push&quot; value=&quot;Push History&quot;/&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre><p>Now the following JavaScript code is added to the document:</p><pre class="brush: jscript; title: ; notranslate">
$(document).ready(function(){
  $(&quot;#push&quot;).click(function(){
    history.pushState({page: 1},&quot;Page 1&quot;,&quot;page1.html&quot;);
    history.pushState({page: 2},&quot;Page 2&quot;,&quot;page2.html&quot;);
  });
});
</pre><p>The following JavaScript code is added to <code>page2.html</code>:</p><pre class="brush: jscript; title: ; notranslate">
$(document).ready(function(){
  window.onpopstate=function(event){
  alert(&quot;location: &quot;+document.location+&quot; and state: &quot;+event.state.page);
  }
});
</pre><p>If you load <code>http://localhost/index.html</code> and click the Push History button, it will add two history entries and cause the browser to display the URL <code>http://localhost/page2.html</code>. However, the content of page will not change. If you navigate to some other page and then press the Back button, the browser will load <code>page2.html</code>. The page will also receive a <code>popstate</code> event. The <code>state</code> property of this event will contain a copy of the state object used while adding the history entry with <code>history.pushState()</code>.</p><p>If you again press the Back button again, the URL will change to <code>http://localhost/page1.html</code> and another <code>popstate</code> event will be received by <code>page2.html</code>. Note that although the URL is changed to <code>page1.html</code>, the content of <code>page2.html</code> is displayed.</p><h2>Using <code>replaceState()</code></h2><p><code>history.replaceState()</code> acts in the same way as <code>history.pushState()</code>, but it modifies the current history entry instead of adding a new one.</p><h1>Practical Usage</h1><p>When you click on a specific photo in a Facebook album you can see that the URL changes and a picture is displayed. All of this happens without reloading the page.</p><p>Also check out the <a
href="https://chrome.google.com/webstore">Chrome Web Store</a>. When you click on a specific app, all the details of the app are shown in a modal window, and the URL of the page changes. The point is that each app has its own URL that users can bookmark.</p><p>We can implement a similar functionality using the History API. In this example, we will create a simple photo gallery. If the user clicks on a specific photo, the picture opens up in a light box style. We enhance the functionality by giving each photo its own URL. When a picture opens, the URL of the page is changed to reflect the currently opened picture&#8217;s address.</p><h2>Step 1</h2><p>We start by creating a simple HTML page and adding a few images to it, as shown below. Note that I have included prettyPhoto, a jQuery plugin for creating a lightbox effect.</p><h4>demo.html</h4><pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Demo Page&lt;/title&gt;
    &lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;js/jquery.prettyPhoto.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;css/prettyPhoto.css&quot;/&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;customurl.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div align=&quot;center&quot;&gt;
      &lt;a href=&quot;/demos/history/pics/image1.jpg&quot; rel=&quot;prettyPhoto&quot; id=&quot;1&quot;&gt;&lt;img src=&quot;pics/image1.jpg&quot; height=&quot;300&quot;
      width=&quot;300&quot;/&gt;&lt;/a&gt;
      &lt;a href=&quot;/demos/history/pics/image2.jpg&quot; rel=&quot;prettyPhoto&quot; id=&quot;2&quot;&gt;&lt;img src=&quot;pics/image2.jpg&quot; height=&quot;300&quot;
      width=&quot;300&quot;/&gt;&lt;/a&gt;
      &lt;a href=&quot;/demos/history/pics/image3.jpg&quot; rel=&quot;prettyPhoto&quot; id=&quot;3&quot;&gt;&lt;img src=&quot;pics/image3.jpg&quot; height=&quot;300&quot;
      width=&quot;300&quot;/&gt;&lt;/a&gt;
      &lt;a href=&quot;/demos/history/pics/image4.jpg&quot; rel=&quot;prettyPhoto&quot; id=&quot;4&quot;&gt;&lt;img src=&quot;pics/image4.jpg&quot; height=&quot;300&quot;
      width=&quot;300&quot;/&gt;&lt;/a&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre><h2>Step 2</h2><p>We proceed to add some JavaScript to the page. The content of customurl.js, which is included in the page, is shown below. First, we create a photo gallery by initializing prettyPhoto. Next, when the user clicks on a link, we grab the image number and create a fake image URL based on the number. Then we push it onto the history stack. Similarly, when the user closes an image we pop the current history entry from the stack. As a result the original URL comes back to address bar.</p><pre class="brush: jscript; title: ; notranslate">
$(document).ready(function(){
  $(&quot;a[rel^='prettyPhoto']&quot;).prettyPhoto({
    callback: function(){history.pushState(&quot;&quot;,&quot;&quot;,&quot;/demos/history/demo.html&quot;); document.title=&quot;Demo Page&quot;;}
  });
  $(&quot;a&quot;).click(function(){
    var id=$(this).attr(&quot;id&quot;);
    var img=&quot;image&quot;+id;
    var url=&quot;images/&quot;+img+&quot;/&quot;;
    history.pushState(&quot;&quot;,&quot;&quot;,url);
    document.title=img;
  });
  function getParameter(name){
    if(name=(new RegExp('[?&amp;]'+encodeURIComponent(name)+'=([^&amp;]*)')).exec(location.search))
      return decodeURIComponent(name[1]);
  }
  var image=getParameter(&quot;id&quot;);
  if(typeof image !='undefined'){
    var event=document.createEvent('MouseEvents');
    event.initEvent('click',true,true);
    document.getElementById(image).dispatchEvent(event);
  }
});
</pre><h2>Step 3</h2><p>What if a user directly accesses the fake image URL? The browser will send a 404 error indicating that the page was not found. To overcome this, we create a server side PHP script. The script gets the image number from the request and redirects the user to <code>demo.html</code>, appending the image number as a query string parameter.</p><p>In our JavaScript code inside <code>demo.html</code>, we have defined the <code>getParameter()</code> function which searches the URL to find the image number. We have already given our photo gallery links specific <code>id</code> attributes which represent the image number. If the image number is found from the URL, we create a <code>click</code> event programmatically on the particular link. As a result, the image is displayed with lightbox effect.</p><p>You can find a complete working demo <a
href="http://extremecss.com/demos/history/demo.html">here</a>.</p><h1>Further Reading</h1><p>You can visit the <a
href="https://developer.mozilla.org/en-US/docs/DOM/Manipulating_the_browser_history">Mozilla Developer Network</a> to learn more about the History API. Also, check out the <a
href="https://developer.mozilla.org/en-US/docs/DOM/window.history"><code>history</code></a> object to learn more about its properties and methods.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/an-overview-and-usage-of-javascript-history-api/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Basic Canvas Animation Using JavaScript</title><link>http://www.sitepoint.com/basic-animation-with-canvas-and-javascript/</link> <comments>http://www.sitepoint.com/basic-animation-with-canvas-and-javascript/#comments</comments> <pubDate>Fri, 25 Jan 2013 09:00:37 +0000</pubDate> <dc:creator>Sandeep Panda</dc:creator> <category><![CDATA[Intermediate]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[Raw Javascript]]></category> <category><![CDATA[canvas]]></category> <category><![CDATA[HTML 5]]></category> <guid
isPermaLink="false">http://jspro.com/?p=1852</guid> <description><![CDATA[The &#60;canvas&#62; element, introduced in HTML5, allows developers to dynamically create bit map graphics using JavaScript. In this tutorial you will learn about some of the basic operations supported by the &#60;canvas&#62; element and create a simple animation using JavaScript. Canvas was first introduced by Apple in 2004 for use in Mac OS X and [...]]]></description> <content:encoded><![CDATA[<p></p><p>The <code>&lt;canvas&gt;</code> element, introduced in HTML5, allows developers to dynamically create bit map graphics using JavaScript. In this tutorial you will learn about some of the basic operations supported by the <code>&lt;canvas&gt;</code> element and create a simple animation using JavaScript.<br
/> <span
id="more-63965"></span></p><p>Canvas was first introduced by Apple in 2004 for use in Mac OS X and Safari. Now it has been adopted by every major browser. Current versions of Mozilla Firefox, Chrome, Opera, Safari, and IE 9 and 10 all support the <code>&lt;canvas&gt;</code> element.</p><h1>How To Use Canvas</h1><p>The following code adds a <code>&lt;canvas&gt;</code> element.</p><pre class="brush: xml; title: ; notranslate">
&lt;canvas id=&quot;canvasDemo&quot; height=&quot;400&quot; width=&quot;300&quot;&gt;
Sorry, your browser does not support canvas.
&lt;/canvas&gt;
</pre><p>The <code>id</code> attribute is used so that we can access the <code>&lt;canvas&gt;</code> element from JavaScript. The <code>height</code> and <code>width</code> attributes are used to size the canvas. Whatever you write inside the <code>&lt;canvas&gt;</code> tag will appear if the browser does not support canvases. This acts as a fallback for older browsers. From JavaScript we can access the <code>&lt;canvas&gt;</code> element as shown below.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><pre class="brush: jscript; title: ; notranslate">
var canvas=document.getElementById(&quot;canvasDemo&quot;);
var context=canvas.getContext(&quot;2d&quot;);
</pre><p>The following example shows how to draw a line on the canvas. The code draws a straight line from coordinate (30, 40) to (145, 120), with the upper left corner of the canvas acting as coordinate (0, 0). It should be noted that <code>&lt;canvas&gt;</code> elements do not maintain any DOM. As a result if you want to alter anything on the canvas, you will probably have to redraw the whole thing.</p><pre class="brush: jscript; title: ; notranslate">
var canvas=document.getElementById(&quot;canvasDemo&quot;);
var context=canvas.getContext(&quot;2d&quot;);
context.strokeStyle=&quot;green&quot;;
context.moveTo(30,40);
context.lineTo(145,120);
context.stroke();
</pre><p>The modified canvas is shown in the following figure.</p><p>[image src="http://jspro.com/files/2013/01/line.png"]</p><h1>Drawing Basic Shapes</h1><p>Before moving on to animations, you need to understand the basic shapes that can be drawn on canvas. We will need these basic shapes every time we want to create something. Let&#8217;s start with the following operations related to rectangles.</p><ul><li><code>fillRect(x,y,width,height);</code></li><li><code>clearRect(x,y,width,height);</code></li><li><code>strokeRect(x,y,width,height);</code></li></ul><p>The first two parameters of each function represent the coordinates of the upper left corner of the rectangle. The next two parameters specify the width and height of the rectangle. Consider the following JavaScript snippet:</p><pre class="brush: jscript; title: ; notranslate">
var context=document.getElementById(&quot;canvasDemo&quot;).getContext(&quot;2d&quot;);
context.strokeStyle=&quot;green&quot;;
context.fillStyle=&quot;red&quot;;
context.strokeRect(70,70,80,80);
context.fillRect(80,80,60,60);
context.clearRect(95,95,30,30);
</pre><p>It produces the following output:</p><p>[image src="http://jspro.com/files/2013/01/Rectangles.png"]</p><p>As you can see, the <code>fillRect()</code> method creates a rectangle and fills it with the color specified by the <code>context.fillStyle</code> property. <code>clearRect()</code> clears a rectangular portion from the canvas, and <code>strokeRect()</code> draws a rectangular outline whose color is determined by the <code>context.strokeStyle</code> property.</p><h2>Drawing Lines</h2><p>Lines can be drawn using the <code>lineTo()</code> function. The method takes two parameters which represent the coordinates of the end point. To draw a line you need to first call <code>moveTo()</code>, which represents the starting point of line. The first example in this article draws a line in this fashion.</p><h2>Drawing Arcs</h2><p>An arc is drawn using the <code>arc()</code> function, shown below.</p><pre class="brush: jscript; title: ; notranslate">
arc(x,y,radius,startAngle,endAngle,direction);
</pre><p>The first two parameters represent the center&#8217;s coordinate. <code>startAngle</code> represents the starting angle for the arc. To create a circle, set this to zero. The <code>endAngle</code> determines the angle at which the arc ends. While drawing a circle you will set this to 360 degrees. For a semi circle it should be 180 degrees. Note that the angles should be specified in radians. Therefore, you should use the Math.PI constant to convert from degrees. Finally, the <code>direction</code> parameter denotes, whether the arc should be drawn clockwise or counterclockwise.</p><p>Consider the following snippet:</p><pre class="brush: jscript; title: ; notranslate">
var ctx = document.getElementById('canvasDemo').getContext('2d');
ctx.arc(180,180,70,0,Math.PI,true);
ctx.stroke();
</pre><p>It produces the following output.</p><p>[image src="http://jspro.com/files/2013/01/arc2.png"]</p><p>However, if you want to change the direction to clockwise then you need to call <code>arc()</code> with the last argument set to <code>false</code>. This results in the following output.</p><p>[image src="http://jspro.com/files/2013/01/arc1.png"]</p><h1>Drawing Paths</h1><p>Usually a path consists of several shapes. Each path is internally represented by a list of sub paths like rectangles, lines, or arcs. Paths can be drawn using the following functions.</p><ul><li><code>beginPath()</code></li><li><code>closePath()</code></li><li><code>stroke()</code></li><li><code>fill()</code></li></ul><p>Every path maintains a list of sub paths. When <code>beginPath()</code> is called this list is reset and we can start drawing different shapes for the path. The following example shows the path functions in action.</p><pre class="brush: jscript; title: ; notranslate">
var ctx = document.getElementById(&quot;canvasDemo&quot;).getContext(&quot;2d&quot;);
ctx.beginPath();
ctx.arc(180,180,70,0,Math.PI*2,true);
ctx.moveTo(230,180);
ctx.arc(180,180,50,0,Math.PI,false);
ctx.moveTo(155,150);
ctx.arc(150,150,5,0,Math.PI*2,true);
ctx.moveTo(215,150);
ctx.arc(210,150,5,0,Math.PI*2,true);
ctx.fillText(&quot;Happy&quot;, 165, 270);
ctx.stroke();
</pre><p>The resulting canvas is shown below.</p><p>[image src="http://jspro.com/files/2013/01/happy-face.png"]</p><h1>Drawing Images</h1><p>Drawing an image on canvas is pretty easy. You can create an <code>Image</code> object and draw it on the canvas as shown below.</p><pre class="brush: jscript; title: ; notranslate">
var ctx = document.getElementById(&quot;canvasDemo&quot;).getContext(&quot;2d&quot;);
var img =new Image();
img.onload=function(){
  ctx.drawImage(img,15,25);
}
img.src=&quot;myImg.png&quot;;
</pre><p>Another way is to add an image to your document and make it invisible. In JavaScript we can access it by <code>id</code> and draw it as shown below.</p><pre class="brush: jscript; title: ; notranslate">
var ctx = document.getElementById(&quot;canvasDemo&quot;).getContext(&quot;2d&quot;);
var img = document.getElementById(&quot;myimage&quot;);
ctx.drawImage(img,0,0);
</pre><p>For a complete tutorial about drawing basic shapes you can refer to the Mozilla Developer Network <a
href="https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Drawing_shapes">documentation</a>.</p><h1>Creating a Bouncing Ball Application</h1><p>This example will create an application containing a bouncing ball. You need to catch the ball with a paddle when it reaches the bottom of the screen. We will use the <code>setTimeout()</code> function to create the animation. We already know that whatever you draw on canvas persists until you clear it. So, to make an object move on canvas you need to call a function periodically that clears the canvas and updates the position of the object.</p><p>In our case, a custom <code>draw()</code> function will be called every ten milliseconds. It will clear the entire canvas and update <code>x</code> and <code>y</code> coordinates of the ball. This gives the illusion that the ball is moving continuously.</p><p>Place the following JavaScript code in a file named <code>bouncingball.js</code>.</p><pre class="brush: jscript; title: ; notranslate">
var canvas;
var ctx;
var dx = 1;
var dy = 2;
var bar=new Bar(400,500);
var circle=new Circle(400,30,10);
var dxBar=6;
var timer;
var barImg;
function Bar(x,y){
  this.x=x;
  this.y=y;
}
function Circle(x,y,r){
  this.x=x;
  this.y=y;
  this.r=r;
}
function drawBall(c) {
  ctx.beginPath();
  ctx.arc(c.x, c.y, c.r, 0, Math.PI*2, true);
  ctx.fill();
}
function doKeyDown(e){
  if(e.keyCode==37){
    if(bar.x-dxBar&gt;0)
      bar.x-=dxBar;
  }
  else if(e.keyCode==39){
    if(bar.x+dxBar&lt;canvas.width)
      bar.x+=dxBar;
  }
}
function init() {
  window.addEventListener(&quot;keydown&quot;,doKeyDown,false);
  barImg=document.getElementById(&quot;bar&quot;);
  canvas = document.getElementById(&quot;canvas&quot;);
  ctx = canvas.getContext(&quot;2d&quot;);
  timer=setInterval(draw, 10);
  return timer;
}
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = &quot;#FAF7F8&quot;;
  ctx.fillRect(0,0,canvas.width,canvas.height);
  ctx.fillStyle = &quot;#003300&quot;;
  drawBall(circle);
  if (circle.x +dx &gt; canvas.width || circle.x +dx &lt; 0)
    dx=-dx;
  if(circle.y+dy&gt;bar.y &amp;&amp; circle.x&gt;bar.x &amp;&amp; circle.x&lt;bar.x+barImg.width)
    dy=-dy;
  if (circle.y +dy &gt; canvas.height || circle.y +dy &lt; 0)
    dy=-dy;
  circle.x += dx;
  circle.y += dy;
  ctx.drawImage(barImg,bar.x,bar.y);
  if(circle.y&gt;bar.y){
    clearTimeout(timer);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    alert(&quot;Game Over&quot;);
  }
}
</pre><p>The HTML document which includes the JavaScript code is shown below.</p><pre class="brush: xml; title: ; notranslate">
&lt;!doctype html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Canvas Demo&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;bouncingball.js&quot;/&gt;
  &lt;/head&gt;
  &lt;body onload=&quot;init();&quot;&gt;
    &lt;div&gt;
      &lt;canvas id=&quot;canvas&quot; width=&quot;800&quot; height=&quot;600&quot;&gt;
      Sorry, browser does not support canvas.
      &lt;/canvas&gt;
    &lt;/div&gt;
    &lt;img src=&quot;bar.png&quot; id=&quot;bar&quot; style=&quot;display:none&quot;/&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre><p>You can try out the game via the <a
href="http://extremecss.com/demos/bouncing-ball/">online demo</a>. Note that several optimizations and improvements can be done on this game. First we begin by defining two objects, <code>ball</code> and <code>bar</code>. The bar can reflect the ball when it reaches the bottom of the screen. The variables <code>dx</code> and <code>dy</code> determine how fast the ball moves along the x-axis and y-axis, respectively. <code>dxBar</code> represents how fast the bar moves along the x-axis.</p><p>The <code>init()</code> function is called when the body is loaded. Next, we register an event listener which listens for <code>keydown</code> events. If the user presses the left arrow we shift the <code>x</code> value of the bar by <code>dxBar</code> pixels left. If the user presses the right arrow we shift the bar to the right.</p><p>Then we initialize the canvas and get a 2D context which initializes the <code>ctx</code> variable. After that, we register the <code>draw()</code> function with <code>setTimeout()</code> so that it will be called every ten milliseconds.</p><p>Every time <code>draw()</code> is executed, we clear the canvas and draw the updated ball and bar. Inside the function we check whether the ball collides with the bar. If so, the ball bounces back. If the ball gets off screen, the canvas is cleared and the animation stops, ending the game.</p><h1>Where To Go From Here</h1><p>If you&#8217;re interested in improving the game, check out the guide to <a
href="https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Optimizing_canvas">optimizing canvases</a>. You could also use <a
href="https://developer.mozilla.org/en-US/docs/DOM/window.requestAnimationFrame">requestAnimationFrame()</a> to perform animation. It instructs the browser to schedule a repaint of the window so that the next animation frame can be rendered. Unfortunately, it’s an experimental technology and its specification has not stabilized yet. You should also learn about various <a
href="https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Transformations">transformations</a> that can be done on the canvas and check out a few <a
href="https://developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/Basic_animations">animations</a> in MDN.</p><div
class='after-content-widget-1'><div
id="sitepointcontextualcontentmanagerwidget-5" class="widget widget_sitepointcontextualcontentmanagerwidget"><div
class="dfp-ad show-desktop"><div
id="div-gpt-ad-1340873946991-4" style="width: 728px; height: 90px;"> <script type="text/javascript">googletag.cmd.push(function() { googletag.display("div-gpt-ad-1340873946991-4"); });</script> </div></div></div></div>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/basic-animation-with-canvas-and-javascript/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 45/81 queries in 0.227 seconds using memcached
Object Caching 2177/2366 objects using memcached

Served from: www.sitepoint.com @ 2013-05-13 15:45:51 --