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

<channel>
	<title>Broken Links &#187; Scripting</title>
	<atom:link href="http://www.broken-links.com/category/scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.broken-links.com</link>
	<description>Thoughts on web development and technologies by Peter Gasston</description>
	<lastBuildDate>Fri, 03 Feb 2012 19:47:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<atom:link rel='hub' href='http://www.broken-links.com/?pushpress=hub'/>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Data Attributes in HTML and jQuery</title>
		<link>http://www.broken-links.com/2010/11/18/data-attributes-in-html-and-jquery/</link>
		<comments>http://www.broken-links.com/2010/11/18/data-attributes-in-html-and-jquery/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 14:11:58 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[html]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[rdfa]]></category>
		<category><![CDATA[semantics]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=1068</guid>
		<description><![CDATA[Sometimes the existing HTML attributes aren't sufficient for describing an element's content. We can use class, ref, rel, title and more, but even so there are occasions where we need more. <abbr>HTML5</abbr> addresses this problem with the introduction of Data Attributes, which allow you to add simple metadata to individual elements, largely for the purpose of providing information to make JavaScript functions easier.]]></description>
			<content:encoded><![CDATA[<p>Sometimes the existing HTML attributes aren’t sufficient for describing an element’s content. We can use <code>class</code>, <code>ref</code>, <code>rel</code>, <code>title</code> and more, but even so there are occasions where that’s not enough. <abbr>HTML5</abbr> addresses this problem with the introduction of Data Attributes, which allow you to add simple metadata to individual elements, largely for the purpose of providing information to make JavaScript functions easier.</p>
<p><span id="more-1068"></span></p>
<p>The syntax is a key:value pair, with the key being a keyword prefixed with <code>data–</code>, like so:</p>
<pre>&lt;div data-foo="bar"&gt;&lt;/div&gt;</pre>
<p>Note that this is not intended to compete with or replace <a href="http://microformats.org/">Microformats</a> or <a href="http://www.w3.org/TR/xhtml-rdfa-primer/"><abbr title="Resource Description Framework in attributes">RDFa</abbr></a>; data attributes were developed only to <q><a href="http://dev.w3.org/html5/spec/elements.html#custom-data-attribute">store custom data [about an element] when there is no more appropriate attribute or element available</a></q>.</p>
<p><a href="http://blog.jquery.com/2010/10/16/jquery-143-released/">jQuery introduced support for data attributes in version 1.4.3</a>, which was released in October 2010. You use the existing <code>data()</code> method to get and set values. Getting a value involves just using the keyword, as in this example which operates on the markup above:</p>
<pre>var baz = $('div').data('foo');</pre>
<p>This would set the value of ‘bar’ to the <code>baz</code> variable. jQuery’s implemenation is so clever that the variable will take on the correct value type — string, number, boolean — automatically. In the example above it would be a string, but given markup like this:</p>
<pre>&lt;div data-retail="3.99"&gt;&lt;/div&gt;</pre>
<p>The value of the variable would be provided as a number type. You can also use <a href="http://www.json.org/js.html"><abbr title="JavaScript Object Notation">JSON</abbr></a> syntax in data attributes, like so:</p>
<pre>&lt;div data-foobar='{"foo":"bar"}'&gt;&lt;/div&gt;</pre>
<p>Note that the attribute uses single quotes while the key:value pair inside are in double quotes; this is required to be valid <abbr>JSON</abbr> syntax. To access this with jQuery, just add the key name as an object at the end of the string:</p>
<pre>var baz = $('div').data('foobar').foo;</pre>
<p>This will once again instruct the variable <code>baz</code> to have the value ‘bar’.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=1068&amp;md5=7b1629c867aec301a7fe0fd97e7f038b" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/11/18/data-attributes-in-html-and-jquery/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=1068&amp;md5=7b1629c867aec301a7fe0fd97e7f038b" type="text/html" />
	</item>
		<item>
		<title>New jQuery release and Mobile Alpha</title>
		<link>http://www.broken-links.com/2010/10/17/new-jquery-release-and-mobile-alpha/</link>
		<comments>http://www.broken-links.com/2010/10/17/new-jquery-release-and-mobile-alpha/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 22:42:54 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Asides]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery mobile]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=1026</guid>
		<description><![CDATA[A new version of jQuery has quietly been released over the weekend. It’s only a minor point release but has a couple of features which look amazing: some selector functions now work up to 8x faster than the previous release; and there is support — very clever support — for HTML5 data attributes. Take a [...]]]></description>
			<content:encoded><![CDATA[<p>A new version of jQuery has quietly been released over the weekend. It’s only a minor point release but has a couple of features which look amazing: some selector functions now work up to 8x faster than the previous release; and there is support — very clever support — for HTML5 data attributes. Take a look at <a href="http://blog.jquery.com/2010/10/16/jquery-143-released/">the jQuery 1.4.3 release notes</a> for more.</p>
<p>Also released was <a href="http://jquerymobile.com/2010/10/jquery-mobile-alpha-1-released/">the first alpha of jQuery Mobile</a>, a touch-optimised amalgam of jQuery and jQuery UI. It’s actually a little buggy on my Galaxy S Android phone, but as it’s an alpha release that’s perfectly forgiveable. It looks pretty smart and comprehensive.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=1026&amp;md5=f25e947fd5a81816fb09a67e7302e6f5" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/10/17/new-jquery-release-and-mobile-alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=1026&amp;md5=f25e947fd5a81816fb09a67e7302e6f5" type="text/html" />
	</item>
		<item>
		<title>JavaScript: The Selectors API</title>
		<link>http://www.broken-links.com/2010/09/28/javascript-the-selectors-api/</link>
		<comments>http://www.broken-links.com/2010/09/28/javascript-the-selectors-api/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 13:00:44 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[basics]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[selectors api]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=1011</guid>
		<description><![CDATA[JavaScript libraries like jQuery and Prototype are amazing; flexible and powerful, they standardise processes and make cross-browser scripting really easy. I rarely work on a project nowadays where a library isn’t used. Their ease-of-use has a slight drawback, however: it’s easy to rely on them too much, and lose sight of new developments in JavaScript. [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript libraries like jQuery and Prototype are amazing; flexible and powerful, they standardise processes and make cross-browser scripting really easy. I rarely work on a project nowadays where a library isn’t used.</p>
<p>Their ease-of-use has a slight drawback, however: it’s easy to rely on them too much, and lose sight of new developments in JavaScript. This was the reason for my not really paying much attention to an exciting recent introduction, the <a href="http://www.w3.org/TR/selectors-api/">Selectors <abbr>API</abbr></a>, until I had cause to use it on a personal project.</p>
<p><span id="more-1011"></span></p>
<p>I may be completely out of the loop, and perhaps everyone knows about this already; in case you don’t here’s a quick overview. The Selectors <abbr>API</abbr> has a pair of methods which allow you to select elements by using <abbr>CSS</abbr> selectors in the argument string; for example:</p>
<pre>var foo = document.querySelector('.foo p');
var bar = document.querySelectorAll('.foo p');</pre>
<p>The first method, <a href="https://developer.mozilla.org/En/DOM/Document.querySelector"><code>querySelector()</code></a>, returns the first element matching the specified argument; the second, <a href="https://developer.mozilla.org/En/DOM/Document.querySelectorAll"><code>querySelectorAll()</code></a> returns a NodeList of all elements matching the argument. So given the following markup:</p>
<pre>&lt;div class="foo"&gt;
&lt;p&gt;It was the best of times.&lt;/p&gt;
&lt;p&gt;It was the worst of times.&lt;/p&gt;
&lt;/div&gt;</pre>
<p>The variable <em>foo</em> would return the first paragraph, and the variable <em>bar</em> would return a list of both paragraphs — so you could loop through the list with <code>for</code>, or get a single property value:</p>
<pre>var barOne = bar[0];</pre>
<p>Anyone used to working with libraries like jQuery should find this pretty easy to grasp, as many already use a syntax similar to this. Probably the best news about this new <abbr>API</abbr> is that it’s already well implemented; Firefox, Chrome/Safari, Opera and <abbr>IE8</abbr>+ all support it.</p>
<p>One other happy discovery regarding JavaScript: the IE9 beta has support for the <a href="http://www.quirksmode.org/js/events_advanced.html"><code>addEventListener()</code></a> method. I’m pretty sure I don’t need to explain that one.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=1011&amp;md5=e75a21ae10e77965f1a5db5cd67ebdbb" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/09/28/javascript-the-selectors-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=1011&amp;md5=e75a21ae10e77965f1a5db5cd67ebdbb" type="text/html" />
	</item>
		<item>
		<title>Using SVG in CSS with JavaScript detection</title>
		<link>http://www.broken-links.com/2010/09/22/using-svg-in-css-with-javascript-detection/</link>
		<comments>http://www.broken-links.com/2010/09/22/using-svg-in-css-with-javascript-detection/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 10:25:01 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[feature detection]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[svg]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=993</guid>
		<description><![CDATA[With the release of <abbr>IE9</abbr> and Firefox 4 all major browsers are going to support using <abbr>SVG</abbr> in the <code>img</code> element or as a <abbr>CSS</abbr> background image, which is great news as <abbr>SVG</abbr> images are good for high definition, scalable websites. I've written a couple of posts recently about using <abbr>SVG</abbr> with the <code>background-image</code> property, and how to cope with browsers that don't support it. <a href="/2010/06/14/using-svg-in-backgrounds-with-png-fallback/">The method I came up with</a> works, but is far from elegant; for one thing, it doesn't allow for transparency.

Another approach we can take to the problem is to use JavaScript to detect <abbr>SVG</abbr> support. <a href="http://my.opera.com/Fyrd/blog/svg-image-and-background-image-replacer">Alexis Deveria wrote a script which detects if your browser supports <abbr>SVG</abbr> and, if not, replace the images with <abbr>PNG</abbr></a>. It's a good script, but I wondered if there was an alternative.]]></description>
			<content:encoded><![CDATA[<p>With the release of <abbr>IE9</abbr> and Firefox 4 all major browsers are going to support using <abbr>SVG</abbr> in the <code>img</code> element or as a <abbr>CSS</abbr> background image, which is great news as <abbr>SVG</abbr> images are good for high definition, scalable websites. I’ve written a couple of posts recently about using <abbr>SVG</abbr> with the <code>background-image</code> property, and how to cope with browsers that don’t support it. <a href="http://www.broken-links.com/2010/06/14/using-svg-in-backgrounds-with-png-fallback/">The method I came up with</a> works, but is far from elegant; for one thing, it doesn’t allow for transparency.</p>
<p>Another approach we can take to the problem is to use JavaScript to detect <abbr>SVG</abbr> support. <a href="http://my.opera.com/Fyrd/blog/svg-image-and-background-image-replacer">Alexis Deveria wrote a script which detects if your browser supports <abbr>SVG</abbr> and, if not, replace the images with <abbr>PNG</abbr></a>. It’s a good script, but I wondered if there was an alternative.</p>
<p><span id="more-993"></span></p>
<p>I’ve come up with a script based on Alexis’s, but which simply adds a class to the body of the document, allowing you to specify alternative images if <abbr>SVG</abbr> support isn’t implemented on a visitor’s browser. <strong>Update:</strong> Changed the script to use <code>onload</code> instead of <code>addEventListener</code> to ensure compatibility with <abbr>IE</abbr>. Still looking into Opera issue.</p>
<p>Here’s the script:</p>
<pre>function setCSS() {
  var docBody = document.getElementsByTagName('body');
  docBody[0].className = 'svg';
}
function SVGDetect() {
  var testImg = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNzUiIGhlaWdodD0iMjc1Ij48L3N2Zz4%3D';
  var img = document.createElement('img');
  img.setAttribute('src', testImg);
  img.onload = setCSS;
}
img.onload = SVGDetect;</pre>
<p>This creates an <code>img</code> element with an <abbr>SVG</abbr> data <abbr>URI</abbr> and tests to see if the browser loads it; if it does, it adds a class of <em>svg</em> to the body. To finish the method you just need to add alternatives in your stylesheet:</p>
<pre>div { background-image: url('image.png'); }
.svg div { background-image: url('image.svg'); }</pre>
<p>Here’s a demo: <a href="http://broken-links.com/tests/svg/svg_detect.html">Using SVG in CSS with JavaScript detection</a>. View it in Safari, Chrome, Opera, <abbr>IE9</abbr> beta or Firefox 4 beta to see the <abbr>SVG</abbr>s, and Firefox 3.6 or IE8 to see the <abbr>PNG</abbr>s. Try zooming in to the page to see the advantage of using <abbr>SVG</abbr>.</p>
<p>There are a couple of drawbacks with this method that need to be ironed out: first is that in theory it doesn’t work in browsers which allow <abbr>SVG</abbr> in the <code>img</code> element but not in <code>background-image</code> — in practice, however, there are no browsers where this is an issue; second is that it loads the <abbr>PNG</abbr> images first, and there’s a brief delay before the <abbr>SVG</abbr> images replace them — the script definitely needs tweaking to stop this, so consider it Version 0.1.</p>
<p>This technique is for the <abbr>CSS</abbr> <code>background-image</code> only; if you want to replace <code>img</code> elements I advise you to use Alexis’ script instead. As always, if you see a way in which my code could be optimised, don’t hesitate to let me know.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=993&amp;md5=7da2d302a94b5b40c1c4c2446fbbf3da" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/09/22/using-svg-in-css-with-javascript-detection/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=993&amp;md5=7da2d302a94b5b40c1c4c2446fbbf3da" type="text/html" />
	</item>
		<item>
		<title>My Name In Print</title>
		<link>http://www.broken-links.com/2010/05/26/my-name-in-print/</link>
		<comments>http://www.broken-links.com/2010/05/26/my-name-in-print/#comments</comments>
		<pubDate>Wed, 26 May 2010 13:06:31 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Miscellanea]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[glow]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[magazine]]></category>
		<category><![CDATA[print]]></category>
		<category><![CDATA[selfpromotion]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=814</guid>
		<description><![CDATA[I hope you’ll forgive a little self-promotion, as I’d just like to play a few quick notes on my own trumpet. The latest issue of Net magazine is now on sale, and features a tutorial article, Create A Dynamic Content Panel, written by me. In the article I explain how to build a dynamic Contact [...]]]></description>
			<content:encoded><![CDATA[<p>I hope you’ll forgive a little self-promotion, as I’d just like to play a few quick notes on my own trumpet. <a href="http://www.netmag.co.uk/zine/latest-issue/issue-203">The latest issue of Net magazine</a> is now on sale, and features a tutorial article, <em>Create A Dynamic Content Panel</em>, written by me.</p>
<p>In the article I explain how to build a dynamic Contact area, as we did on our recent redesign of <a href="http://preloaded.com/">Preloaded.com</a>, using the <a href="http://www.w3.org/TR/webstorage/">Web Storage API</a> and <a href="http://www.bbc.co.uk/glow/">the BBC’s Glow Javascript library</a>.</p>
<p>I’m not sure what the rights situation is with this article, but I hope that at some point in the future I’ll be able to post it here on my blog. But in the meantime, you can buy a copy of Net magazine in the UK at all good newsagents, as the saying goes (I don’t know if it will be in overseas editions also).</p>
<p><img src="/wp-content/uploads/2010/05/tut_js-1.jpg" alt="Printed Tutorial" title="Tutorial Page 1" width="190" height="250" class="aligncenter size-full wp-image-833" /><img src="/wp-content/uploads/2010/05/tut_js-2.jpg" alt="Printed Tutorial" title="Tutorial Page 2" width="190" height="250" class="aligncenter size-full wp-image-834" /><img src="/wp-content/uploads/2010/05/tut_js-3.jpg" alt="Printed Tutorial" title="Tutorial Page 3" width="190" height="250" class="aligncenter size-full wp-image-835" /></p>
<p>On the subject of print, I’m also currently writing a book about CSS3 which should be published later this year. I’ll have more information on that nearer the time.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=814&amp;md5=09c44add3a197c7626bbcbc2ca965f40" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/05/26/my-name-in-print/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=814&amp;md5=09c44add3a197c7626bbcbc2ca965f40" type="text/html" />
	</item>
		<item>
		<title>Building a better HTML5 video player with Glow</title>
		<link>http://www.broken-links.com/2010/04/14/building-a-better-html5-video-player-with-glow/</link>
		<comments>http://www.broken-links.com/2010/04/14/building-a-better-html5-video-player-with-glow/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 12:52:33 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[html]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[glow]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=767</guid>
		<description><![CDATA[Last year I wrote a post (Building HTML5 video controls with JavaScript) introducing the HTML5 Media Elements API and demonstrating a simple set of controls for playing video. In this (somewhat belated) follow-up I’m going to explore building a more interactive set of controls using a JavaScript UI library; I’m going to use Glow, but [...]]]></description>
			<content:encoded><![CDATA[<p>Last year I wrote a post (<a href="http://www.broken-links.com/2009/10/06/building-html5-video-controls-with-javascript/">Building HTML5 video controls with JavaScript</a>) introducing the HTML5 Media Elements API and demonstrating a simple set of controls for playing video.</p>
<p>In this (somewhat belated) follow-up I’m going to explore building a more interactive set of controls using a JavaScript UI library; I’m going to use <a href="http://www.bbc.co.uk/glow/">Glow</a>, but it could easily be adapted to <a href="http://jqueryui.com/">jQuery UI</a> or similar.</p>
<p><span id="more-767"></span></p>
<p>You can see the player I’ll be using as an example here — although it must be stressed that it’s not a final version, for reasons I’ll cover at the end:</p>
<p><a href="http://www.broken-links.com/tests/videoglow/">HTML5 &amp; Glow Video Player</a></p>
<h2>The markup</h2>
<p>The video player itself is pretty straightforward:</p>
<pre>&lt;video autobuffer controls height="180" poster="BBB_poster.jpg" width="320"&gt;
  &lt;source src="bbb.mp4" type="video/mp4"&gt;
  &lt;source src="bbb.webm" type="video/ogg"&gt;
  &lt;source src="bbb.theora.ogg" type="video/ogg"&gt;
  &lt;img alt="Film Poster" height="180" src="BBB_poster.jpg" width="320"&gt;
&lt;/video&gt;</pre>
<p>The <code>video</code> element has the <code>controls</code> attribute set, which we’ll remove with JavaScript later. Note also the <code>poster</code> attribute, which displays a still image until the video is ready to be played, at which point it displays the first frame instead.</p>
<p>Next there are two <code>source</code> elements, which serve the video to Firefox, Opera and Chrome (ogg) and Safari (mp4). Finally there’s an <code>img</code> element, which displays if the browser doesn’t have video support. <strong>Update:</strong> Added <a href="http://www.webmproject.org/">WebM</a> support.</p>
<p>As for the controls, rather than list them here I’ll ask you to view the source to see what I’ve done. Basically I’ve added a bunch of form elements; two <code>input</code> <code>image</code> types for the play and volume icons, and two <code>input</code> <code>text</code> types for the duration and volume sliders. The latter two aren’t necessary, but I wanted them there for accessibility reasons.</p>
<h2>The style</h2>
<p>How I’ve styled the player doesn’t matter too much; I’ve been influenced by the Quicktime player for the layout of the controls, but really the CSS isn’t too important here. The only thing to note is that I’ve added some rules here for screen overlays, which I’ll explain in due course:</p>
<pre>.overlay { background-repeat: no-repeat; height: 180px; position: absolute; width: 320px; }
.paused { background-color: rgba(0,0,0,0.2); background-image: url('pause.png'); background-position: left bottom; }
.play { background-image: url('play.png'); background-position: center center; }</pre>
<h2>The JavaScript</h2>
<p>You can see all the script I’ve used in the file <a href="http://www.broken-links.com/tests/videoglow/video.js">video.js</a>. I’ll go through some of the more important functions in turn.</p>
<h3>Setting up</h3>
<p>The first thing I’ve done is removed the native controls from the player for people who have JS enabled, so as not to provide two conflicting sets of controls:</p>
<pre>video[0].controls = false;</pre>
<p>Next I’ve defined some of the key variables which I’ll be using throughout the script. One of those variables, <em>volumeSlide</em>, is assigned to one of Glow’s native widgets, a <a href="http://www.bbc.co.uk/glow/docs/1.7/api/glow.widgets.slider.shtml">Slider</a>; this will be used to control the volume:</p>
<pre>volumeSlide = new glow.widgets.Slider('#volume',{bindTo:'#vol_count', buttons:false, step:0.1, min:0, max:1, size:70, val:1});</pre>
<p>You can see what all the options do in the Glow documentation, but the key ones I’ve set are for it to appear in &lt;div id=“volume”&gt;, to have a minimum value of 0 and a max of 1, and to increment in steps of 0.1. This matches the volume setting for the <code>video</code> element.</p>
<h3>Waiting for the metadata</h3>
<p>For the next step I’m going to create another slider, but this time for the duration/seek bar. In order to do this, however, I need to query the video’s metadata to know what the duration of the video is, and in Safari (which uses mp4 video) that doesn’t load before the rest of my JS has run.</p>
<p>To get around this I’ll poll the <code>readyState</code> attribute every half a second — with the <code>setInterval</code> function — until it’s value is at least 1, which means the metadata has loaded; once that’s done, I’ll load the slider:</p>
<pre>t = window.setInterval(function() {
  if (video[0].readyState >= 1) {
    window.clearInterval(t);
    durationSlide = new glow.widgets.Slider('#vid_duration',{bindTo:'#duration_count', buttons:false, step:1, min:1, max:Math.round(video[0].duration-1), size:260, val:0});
    playVid();
  }
},500);</pre>
<p>So you can see there that I’ve created the slider with a minimum value of 1 and a maximum of the duration of the video (in seconds), to increment in steps of 1. After that the setup is complete so I can begin the actual playback functions.</p>
<h3>Playback controls</h3>
<p>There are too many functions to go into in detail, so I’ll quickly go through what happens. First an overlay is placed over the top of the video, which begins playback when clicked. Next, event listeners are added to the play button, the volume icon, and the volume and duration sliders.</p>
<p>The listener on the play button runs the function <em>playControl</em>, which determines the state of playback (<em>ended</em>, <em>paused</em> or playing) and either plays or pauses the video accordingly. It also updates the icon to reflect its action (if it is paused, the icon changes to a play icon, and <span lang="la">vice versa</span>), and adds the pause overlay onto the video screen when relevant:</p>
<pre>function playControl() {
  if (video[0].paused === true) {
    video[0].play();
    /* Further functions here */
  };
} else if (video[0].ended === true) {
    video[0].play();
     /* Further functions here */
} else {
    video[0].pause();
     /* Further functions here */
}</pre>
<p>There’s a function called <em>startCount</em> which uses <code>setInterval</code> to move the duration slider along by one second while the video is playing, and a function called <em>pauseCount</em> which uses <code>clearInterval</code> to pause.</p>
<p>The <em>muteToggle</em> function does what you expect, and mutes the video; it also changes the volume icon to show that state, and disables the volume slider while it is active.</p>
<p>A further function, <em>volumeIcons</em>, sets the state of the volume icon; there are four possible icon states, which are used depending on the value of the volume.</p>
<p>And the last function, <em>secondsToTime</em>, converts second values into hour/minute/second values, allowing for the timer to be updated. This is done every second by the <em>startCount</em> function, and also used for the function which is called from the event listener on the duration slider.</p>
<p>That event is probably worth looking at in detail:</p>
<pre>glow.events.addListener(durationSlide,'slideStop',function(event){
  video[0].currentTime = event.currentVal;
  var currentSecs = secondsToTime(event.currentVal);
  vidTimer.text(currentSecs.h + ':' + currentSecs.m + ':' + currentSecs.s);
});</pre>
<p>Using the <code>slideStop</code> event I can check when the slider has been moved, and first set the video to begin playback from that point, then update the timer with the same values. The volume slider has a similar event set on it.</p>
<h2>Next steps</h2>
<p>So as a reminder, here’s what I have so far:</p>
<p><a href="http://www.broken-links.com/tests/videoglow/">HTML5 &amp; Glow Video Player</a></p>
<p>Please bear in mind that this is very much a work in progress; I started writing the controls without Glow and introduced it at a later stage, so some of the JavaScript could do with being optimised.</p>
<p>The markup for the controls could also do with some extra work to make them fully accessible, which they probably aren’t right now. Also, all of the dimensions are built around this video size, and won’t scale if different sized videos are used.</p>
<p>I hope to return to this topic when I have more time, and create a robust set of video player controls which can be used in any site without extra work.</p>
<p>Please feel free to let me know if you encounter any bugs or oddities as you use this; it will help with the next stage of development.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=767&amp;md5=4ed76e9e964e3d93b7fd6fe2084766ec" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/04/14/building-a-better-html5-video-player-with-glow/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=767&amp;md5=4ed76e9e964e3d93b7fd6fe2084766ec" type="text/html" />
	</item>
		<item>
		<title>Building Preloaded.com: The Front-end</title>
		<link>http://www.broken-links.com/2010/01/21/building-preloaded-com-the-front-end/</link>
		<comments>http://www.broken-links.com/2010/01/21/building-preloaded-com-the-front-end/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 15:53:37 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[glow]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=686</guid>
		<description><![CDATA[This post discusses the redesign project of my employer’s own website, Preloaded.com, and is cross-posted from there with permission.

At the beginning of the redesign project we agreed some design tenets: the new site should be a best-practice showcase and an opportunity to learn and use some of the latest web technologies; and it should employ existing services where practical.]]></description>
			<content:encoded><![CDATA[<p><em>This subject of this post is the redesign of my employer’s website, <a href="http://preloaded.com/">Preloaded.com</a>, and is cross-posted from the Preloaded blog with permission.</em></p>
<p>At the beginning of the redesign project we agreed some design tenets: the new site should be a best-practice showcase and an opportunity to  learn and use some of the latest web technologies; and it should employ existing services where practical.</p>
<p><span id="more-686"></span></p>
<p>To achieve the former we targeted users with the most modern web browsers, using the <a href="http://en.wikipedia.org/wiki/Progressive_enhancement">graceful (or progressive) enhancement</a> method to ensure that even with older technology, no-one would be left unable to read all of the site content.</p>
<p>The most obvious example of this is in the design of the buttons; users with a decent browser (e.g. Firefox or Safari) would see these with rounded corners — because these browsers are capable of producing them natively with the CSS3 <em>border-radius </em>declaration — while users of other browsers (e.g. Internet Explorer) would see them square:</p>
<p><img src="http://preloaded.com/site_media/uploads/blog/preloaded_frontend/comparison.jpg" alt="" width="475" height="243" /></p>
<p><em>Browser comparison. Top: Safari 4; Bottom: Internet Explorer 8</em></p>
<p>While all users see the same content, those with a modern browser are rewarded with a slightly improved experience. We used other variations of this method elsewhere throughout the site.</p>
<h2>Technology</h2>
<h3>Web Fonts</h3>
<p>In order to achieve brand consistency we had a font in mind which we were going to implement using the <a href="http://cufon.shoqolate.com/">Cufón</a> Javascript technique. During the process of adding this the font foundry clarified their licensing, excluding this font from online use in this way, so we had to scrap it and look for a different angle.</p>
<p>While we were trying out various alternatives using Flash and Javascript (we now know more about font licensing and implementation than we ever wanted to), a new solution presented itself. Using <a href="http://www.fontsquirrel.com/fontface/generator">Font Squirrel’s web font generator</a> and <a href="http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/">Paul Irish’s bulletproof syntax</a> we were able to use the browsers’ own built-in font support (with <em>@font-face</em>) and achieve our desired result for 95% of our users; the other 5% will see a standard system font, as per the graceful en­hance­ment method.</p>
<h3>Glow</h3>
<p><a href="http://www.bbc.co.uk/glow/">Glow</a> is a BBC-developed Javascript library, with a jQuery-like syntax but a focus on interface widgets, which makes it easy to create animations and UI elements for websites. Having already used it briefly on a project earlier in the year, we decided it would be a good fit for what we wanted — and something new to learn.</p>
<p>The image carousel on the homepage was made with Glow, as was the slide-down contact details on each page, and the lightbox overlay effect for screenshots on the case study pages.</p>
<p>The only drawback we found with Glow was a bug in their carousel rendering in IE8; this meant that we had to force <a href="http://blogs.msdn.com/ie/archive/2008/08/27/introducing-compatibility-view.aspx">compatibility view</a> for IE8 to display as IE7, but it’s something we’re hoping to change after the next Glow release.</p>
<h3>HTML5</h3>
<p>Under the bonnet we used some cutting-edge code to mark up our content. HTML5 is a very new specification and still somewhat in a state of flux, but we used it in two different ways:</p>
<p>First was to provide semantic structure to the pages with the new structural elements (the definitions of which are still being discussed, so may not be completely correct — <a href="http://html5doctor.com/">HTML5 Doctor</a> was an invaluable resource for this).</p>
<p>Second, and of more impact to the user, was using <em>sessionStorage</em> to take advantage of the opportunities for storing data in the user’s browser. We used this in conjunction with Glow to create the carousel and slide-down effects; if you have a modern browser these are created only once and held in the browser’s storage, whereas older browsers create them anew each time you visit the page — this leads to the site being somewhat snappier in modern browsers.</p>
<h2>Conclusion</h2>
<p>Working with brand new and cutting edge features meant spending time chasing down false leads and up blind alleys, but was a great way of learning and gave us invaluable experience to take into the sites we make for our clients in future.</p>
<p>There are still one or two changes which we’ll be rolling into the site in the coming months, but if you spot any problems — or just want to talk more in-depth about the methods and techniques we’ve used — don’t hesitate to leave a comment.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=686&amp;md5=b4ba5d4aed69ab5a4147d523004ecb96" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2010/01/21/building-preloaded-com-the-front-end/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=686&amp;md5=b4ba5d4aed69ab5a4147d523004ecb96" type="text/html" />
	</item>
		<item>
		<title>Mozilla release Bespin Embedded preview</title>
		<link>http://www.broken-links.com/2009/11/18/mozilla-release-bespin-embedded-preview/</link>
		<comments>http://www.broken-links.com/2009/11/18/mozilla-release-bespin-embedded-preview/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 10:27:07 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Asides]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[bespin]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[mozilla]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=622</guid>
		<description><![CDATA[Mozilla’s Bespin is a code editor built using web technologies. It’s still in its infancy, but shows promise. A new release, Bespin Embedded, lets you use the basic editor functionality on your own websites, using just a couple of lines of Javascript. If you don’t want to download it yourself, I’ve got a working demo. [...]]]></description>
			<content:encoded><![CDATA[<p>Mozilla’s <a href="https://bespin.mozilla.com/">Bespin</a> is a code editor built using web technologies. It’s still in its infancy, but shows promise. A new release, <a href="http://mozillalabs.com/bespin/2009/11/13/bespin-embedded-first-preview-release/">Bespin Embedded</a>, lets you use the basic editor functionality on your own websites, using just a couple of lines of Javascript. If you don’t want to download it yourself, <a href="http://www.broken-links.com/tests/bespin-embedded/">I’ve got a working demo</a>. The editor doesn’t really do much at the moment, so this is really only a proof of concept.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=622&amp;md5=fe5c653e63b0242c6c916bc66d501c75" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2009/11/18/mozilla-release-bespin-embedded-preview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=622&amp;md5=fe5c653e63b0242c6c916bc66d501c75" type="text/html" />
	</item>
		<item>
		<title>Using the GeoLocation API</title>
		<link>http://www.broken-links.com/2009/11/11/using-the-geolocation-api/</link>
		<comments>http://www.broken-links.com/2009/11/11/using-the-geolocation-api/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 00:32:42 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[browsers]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=613</guid>
		<description><![CDATA[With the <a href="http://www.brandon-hall.com/workplacelearningtoday/?p=7870">rapid growth of the mobile web</a>, location-aware services are very much in-demand; the <a href="http://dev.w3.org/geo/api/spec-source.html">GeoLocation API</a> was proposed to cater to this need.

Implementation is spotty at the moment; Firefox 3.5 supports it, as does Safari for iPhone (although not on the desktop, <abbr title="as far as I can see">AFAICS</abbr>). But it's so <a href="https://developer.mozilla.org/en/using_geolocation">simple to use</a>, I've no doubt it will be adopted rapidly.]]></description>
			<content:encoded><![CDATA[<p>With the <a href="http://www.brandon-hall.com/workplacelearningtoday/?p=7870">rapid growth of the mobile web</a>, location-aware services are very much in-demand; the <a href="http://dev.w3.org/geo/api/spec-source.html">GeoLocation API</a> was proposed to cater to this need.</p>
<p>Implementation is spotty at the moment; Firefox 3.5 supports it, as does Safari for iPhone (although not on the desktop, <abbr title="as far as I can see">AFAICS</abbr>). But it’s so <a href="https://developer.mozilla.org/en/using_geolocation">simple to use</a>, I’ve no doubt it will be adopted rapidly.</p>
<p><span id="more-613"></span></p>
<p>I’ve put together <a href="http://www.broken-links.com/tests/geolocation/">a small demo of the GeoLocation API</a> in action; it uses data from the Arts Council England website, so visitors from outside of England won’t get any meaningful results from this, I’m afraid. Visitors from England will probably get best results using a mobile device (such as an iPhone).</p>
<p>First, the JavaScript function tests that the browser supports the API:</p>
<pre>var hasGeoLocation = navigator.geolocation ? true : false;
if (hasGeoLocation === true) { ... }</pre>
<p>If so, it requests the current position from the browser using the <code>getCurrentPosition</code> method (the user will have to give permission for this) and passes the result into a function:</p>
<pre>navigator.geolocation.getCurrentPosition(function(position) {
    getJSON(position.coords.latitude,position.coords.longitude);
});</pre>
<p>This result is used in the latitude and longitude attributes of the coords object, which I then use for the rest of my function (using <a href="http://docs.jquery.com/Ajax/jQuery.getJSON">jQuery’s getJSON function</a> to mine microformatted data from <a href="http://www.artscouncil.org.uk/map/">the map page</a> of the Arts Council England website, transforming it using <a href="http://microformatique.com/optimus/">Optimus</a>, then parsing it back into HTML for my demo).</p>
<p>There’s a lot more to this, of course; the API is quite extensive, covering altitude and heading as well as lat/long, and there’s a massive amount of <a href="http://en.wikipedia.org/wiki/Geotagging">geotagged</a> data available (<a href="http://flickr.com/">Flickr</a> photos, for example). Hopefully my demo serves as an example of how easy it is to make the move into the mobile space.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=613&amp;md5=c9d77dc7cbf660e5893ab5a2c8a7bead" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2009/11/11/using-the-geolocation-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=613&amp;md5=c9d77dc7cbf660e5893ab5a2c8a7bead" type="text/html" />
	</item>
		<item>
		<title>Building HTML5 video controls with JavaScript</title>
		<link>http://www.broken-links.com/2009/10/06/building-html5-video-controls-with-javascript/</link>
		<comments>http://www.broken-links.com/2009/10/06/building-html5-video-controls-with-javascript/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 16:04:06 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[html]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.broken-links.com/?p=582</guid>
		<description><![CDATA[The HTML5 video element is now included in Firefox, Safari &#38; Chrome, and on its way in Opera. By using JavaScript to access the media elements API it’s easy to build your own custom controls for it; in this article I’m going to show how I built a (very) basic control interface. A quick disclaimer: [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#video">HTML5 video element</a> is now included in Firefox, Safari &amp; Chrome, and on its way in Opera. By using JavaScript to access the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/media-elements.html#media-elements">media elements API</a> it’s easy to build your own custom controls for it; in this article I’m going to show how I built a (very) basic control interface.</p>
<p><span id="more-582"></span></p>
<p>A quick disclaimer: my JavaScript is a little rusty, so may not use best practice throughout; if you can see a way my code could be better, don’t hesitate to let me know.</p>
<p>Anyway, <a href="http://www.broken-links.com/tests/video/">here’s the finished demo</a>.</p>
<h2>Getting started</h2>
<p>First you must include the <code>video</code> element. <del datetime="2010-04-01T16:39:46+00:00">There are a number of attributes available, but for our purposes we need define only the <code>src</code>, which is the URI of our video file</del> <strong>Update</strong>: changed the markup to use the more correct <code>source</code> elements inside <code>video</code>.</p>
<pre>&lt;video&gt;
  &lt;source src="filename.mp4"&gt;
  &lt;source src="filename.webm"&gt;
  &lt;source src="filename.ogg"&gt;
&lt;/video&gt;</pre>
<p>The video has been encoded twice, once in Theora and once in H264, to cater for different browsers; <a href="http://camendesign.com/code/video_for_everybody">Kroc Camen’s Video for Everybody</a> explains the reasons behind this (and how to make a bulletproof player). <strong>Update:</strong> added <a href="http://www.webmproject.org/">WebM</a> support.</p>
<p>Having marked up a few controls with HTML (I’ve used <code>id</code> attributes on all of them to make this demo easier), the next step is to write the JavaScript to access the API (<a href="https://developer.mozilla.org/En/NsIDOMHTMLMediaElement">which is well explained in this article at the Mozilla Developer Center</a>) for the controls.</p>
<p>The first and most important control is the play/pause button; for this I’ve written a function which checks so see if the <code>paused</code> attribute is true or false, and triggers the <code>play()</code> or <code>pause()</code> methods accordingly:</p>
<pre>play.addEventListener('click',playControl,false);
function playControl() {
    if (video.paused == false) {
        video.pause();
        this.firstChild.nodeValue = 'Play';
        pauseCount();
    } else {
        video.play();
        this.firstChild.nodeValue = 'Pause';
        startCount();
    }
}</pre>
<p>You’ll notice that it also updates the control text to indicate the action that the control will perform. There are also two function calls — <code>pauseCount()</code> and <code>startCount()</code> — which control the timer shown next to the play button.</p>
<p>The timer uses the <code>currentTime</code> and <code>duration</code> attributes (although the latter doesn’t seem to be currently supported by Chrome). To get the current time I’ve used <code>setInterval</code> to create a loop:</p>
<pre>function startCount() {
    t = window.setInterval(function() {
        if (video.ended != true) {
            timer.firstChild.nodeValue = Math.round(video.currentTime + 1);
        } else {
            play.firstChild.nodeValue = 'Play';
            window.clearInterval(t);
        }
    },1000);
}</pre>
<p>First it uses an <code>if…else</code> statement on the <code>ended</code> attribute to check that the video has not finished playing; if it hasn’t, it updates the timer with <code>currentTime</code> (plus a little maths). If the video HAS finished, it uses <code>clearInterval</code> to stop the loop; this is also used in a function to pause the timer if the pause control is used:</p>
<pre>function pauseCount() {
    window.clearInterval(t);
}</pre>
<p>To complete the controls we have functions to increase and decrease the volume. Both are very similar:</p>
<pre>vUp.addEventListener('click',volUp,false);
function volUp() {
    if (video.volume < 1) {
        video.volume = Math.round((video.volume + 0.1)*10)/10;
        volume.firstChild.nodeValue = Math.round(video.volume*10);
    }
}</pre>
<p>First they check that the minimum/maximum limits have not been reached, and increase/decrease the <code>volume</code> attribute if not. Volume is on a scale of 0 to 1, and this function changes that value in increments of 0.1. The on-screen volume counter is also changed accordingly.</p>
<p>There are a number of small details elsewhere in the script, so feel free to have a dig through to see what else I’ve done; <a href="http://www.broken-links.com/tests/video/">here’s another link to the finished demo</a>.</p>
<h2>Further steps</h2>
<p>I’ve obviously used a little CSS to tidy the controls up, but a lot more could be done; using images instead of text, for example, or perhaps using something like <a href="http://jqueryui.com/">jQuery’s user interface library</a> to make more dynamic controls.</p>
<p>This article was intended only to show how easy it is to get started; what will be exciting is to see how these techniques can be expanded upon.</p>
<p><strong>Update:</strong> If you found this article useful, you may be interested to know that I returned to this subject in a later post, <a href="http://www.broken-links.com/2010/04/14/building-a-better-html5-video-player-with-glow/">Building a better HTML5 video player with Glow</a>.</p>
 <p><a href="http://www.broken-links.com/?flattrss_redirect&amp;id=582&amp;md5=3163e583299e3d687b576b6695158945" title="Flattr" target="_blank"><img src="http://www.broken-links.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.broken-links.com/2009/10/06/building-html5-video-controls-with-javascript/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<atom:link rel="payment" href="http://www.broken-links.com/?flattrss_redirect&amp;id=582&amp;md5=3163e583299e3d687b576b6695158945" type="text/html" />
	</item>
	</channel>
</rss>

