<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Brian Hadaway</title>
	
	<link>http://www.brianhadaway.com</link>
	<description>Professionally nerdy since 2002.</description>
	<lastBuildDate>Wed, 12 Dec 2012 22:16:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/GoodWithCode" /><feedburner:info uri="goodwithcode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Easy JavaScriptMVC Model and Controller Access from the Chrome Dev Tools Console</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/qFEigU7L760/</link>
		<comments>http://www.brianhadaway.com/easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console/#comments</comments>
		<pubDate>Tue, 18 Sep 2012 19:28:10 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[JavaScriptMVC]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=693</guid>
		<description><![CDATA[<p>JavaScriptMVC has some great convenience functions for accessing Controllers and Models associated with elements. These functions can really speed up development and debugging. Here I&#8217;ll show you how to use the Chrome Developer Tools&#8217; $0 token to make these convenience methods even more convenient. First let&#8217;s look at few examples of how to use the...  <a href="http://www.brianhadaway.com/easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console/" title="Read Easy JavaScriptMVC Model and Controller Access from the Chrome Dev Tools Console" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console/">Easy JavaScriptMVC Model and Controller Access from the Chrome Dev Tools Console</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>JavaScriptMVC has some great convenience functions for accessing Controllers and Models associated with elements. These functions can really speed up development and debugging. Here I&#8217;ll show you how to use the Chrome Developer Tools&#8217; <code>$0</code> token to make these convenience methods even more convenient.</p>
<p>First let&#8217;s look at few examples of how to use the JMVC convenience methods:</p>
<blockquote><p><code>//get all controllers for an element<br />
$(".someclass").controllers()<br />
&nbsp;<br />
//get all controllers of type MyController<br />
$(".someclass").controllers(MyController);<br />
&nbsp;<br />
//get the first controller<br />
$(".someclass").controller();<br />
&nbsp;<br />
//call the MyWidget.prototype.doSomething function with an argument<br />
$(".someclass").myWidget("doSomething", "HELLO!");<br />
&nbsp;<br />
//get the model for an element<br />
$(".someclass").model();<br />
</code></p></blockquote>
<p>Here&#8217;s where the <code>$0</code> token comes into play. The Chrome Developer Tools <code>$0</code> token is simply a reference to an inspected node (the highlighted element in the &#8220;Elements&#8221; tab.) If, for example, you wanted to see a map of the custom data- attributes of an element you would do the following:</p>
<blockquote>
<ol style="list-style: decimal;">
<li>Right-click on an element and choose &#8220;Inspect Element&#8221;</li>
<li>Type &#8220;Command + [" to switch to the Console tab</li>
<li>Type $0.dataset in the Console tab</li>
</ol>
</blockquote>
<p>After following the steps above, the console will return a DOMStringMap of the data- attributes on the element you inspected. It's pretty obvious how the <code>$0</code> token simplifies calling the JavaScriptMVC convenience methods on elements (especially in situations where your Model/Controller elements don't have IDs.) When you have a Model/Controller element selected, you can simply replace the class selectors in the examples above with the token as such:</p>
<blockquote><p><code>//get all controllers for an element<br />
$($0).controllers()<br />
&nbsp;<br />
//get all controllers of type MyController<br />
$($0).controllers(MyController);<br />
&nbsp;<br />
//get the first controller<br />
$($0).controller();<br />
&nbsp;<br />
//call the MyWidget.prototype.doSomething function with an argument<br />
$($0).myWidget("doSomething", "HELLO!");<br />
&nbsp;<br />
//get the model for an element<br />
$($0).model();</code></p></blockquote>
<div id="attachment_725" class="wp-caption aligncenter" style="width: 299px"><img class="size-full wp-image-725 " title="Inspecting a JavascriptMVC Model in the Console" src="http://www.brianhadaway.com/wp-content/uploads/2012/09/console.png" alt="Inspecting a JavascriptMVC Model in the Console" width="289" height="447" /><p class="wp-caption-text">Assuming you inspected an element with either a Controller or Model associated, you should see something similar to this.</p></div>
<p style="text-align: center;">
<p>If you want to try this out on a live JavaScriptMVC application, head over to the <a title="Sample JavaScriptMVC Todos Application" href="http://javascriptmvc.com/todo/todo.html">JMVC sample Todos application</a>, add a few todos and inspect away!</p>
<p>The post <a href="http://www.brianhadaway.com/easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console/">Easy JavaScriptMVC Model and Controller Access from the Chrome Dev Tools Console</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/qFEigU7L760" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=easy-javascriptmvc-model-controller-access-from-chrome-dev-tools-console</feedburner:origLink></item>
		<item>
		<title>JavaScriptMVC Anti-Patterns</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/K9xi2Zrobus/</link>
		<comments>http://www.brianhadaway.com/javascriptmvc-anti-patterns/#comments</comments>
		<pubDate>Sat, 15 Sep 2012 17:18:15 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[JavaScriptMVC]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=621</guid>
		<description><![CDATA[<p>In early 2011, I was faced with the task of recommending a framework for a complex JavaScript application. I resisted the urge to build my own MV* framework and instead opted to learn how to use one of the battle-tested options. I considered several frameworks including JavaScriptMVC, Backbone and KnockoutJS before ultimately deciding on JavaScriptMVC....  <a href="http://www.brianhadaway.com/javascriptmvc-anti-patterns/" title="Read JavaScriptMVC Anti-Patterns" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/javascriptmvc-anti-patterns/">JavaScriptMVC Anti-Patterns</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>In early 2011, I was faced with the task of recommending a framework for a complex JavaScript application. I resisted the urge to build my own MV* framework and instead opted to learn how to use one of the battle-tested options. I considered several frameworks including JavaScriptMVC, Backbone and KnockoutJS before ultimately deciding on <a href="http://javascriptmvc.com/" title="JavaScriptMVC">JavaScriptMVC</a>. (If I were doing this today, I&#8217;d probably include Ember, AngularJS and a few others in my assessment.)<span id="more-621"></span></p>
<p>JavaScriptMVC is a great MV* framework that comes pre-rolled with a lot of the solutions developers need in order to build complex JavaScript applications. Among the problems JavaScriptMVC solves are dependency management, templates, unit tests, build scripts, and documentation. The framework allows developers to focus on building an application instead of assembling a frontend stack or writing yet another MVC-esque JavaScript framework. </p>
<p>While working with JavaScriptMVC for the better part of 18 months, I identified some anti-patterns that can wreak havoc on application development. In order to take full advantage of JavaScriptMVC, you should avoid these patterns.</p>
<p><strong>Using JavaScriptMVC when you don&#8217;t really need it</strong><br />
Before discussing anti-patterns in a JavaScriptMVC application, let&#8217;s consider whether an application needs an MVC framework at all. Are you building a single-page web application in which the frontend only communicates to the server to retrieve data? If so, you should consider a frontend framework. However, if your application is built around a page-based architecture in which the backend is serving views in addition to data, then it is unlikely that you will benefit from a frontend MV* framework. You should also steer clear of frontend frameworks if you aren&#8217;t familiar with an MV* design pattern (such as MVC, MVVM or MVP) and you are unsure of how to separate the concerns of an application into models, views and controllers. Now, on to the actual anti-patterns.</p>
<p><strong>Manually binding event handlers</strong><br />
JavaScriptMVC has a built-in way of binding event handlers that should always be used instead of manual binding. For example in JavaScriptMVC, instead of doing this:<br />
<blockquote><code class="bad">$.Controller('MyExample', {}, {<br />
&nbsp;&nbsp;&nbsp;&nbsp;init : function() { $("#myElement").click(function(){...})}<br />
});</code></p></blockquote>
<p>You should bind event handlers using the method prescribed by the framework:<br />
<blockquote><code class="good">$.Controller('MyExample', {}, {<br />
&nbsp;&nbsp;&nbsp;&nbsp;'#myElement click' : function() {...}<br />
});</code></p></blockquote>
<p>There are numerous advantages to binding handlers the JavaScriptMVC way. One advantage is that the Controller will automatically delegate event handling to the controller&#8217;s element. This results in a smaller memory footprint and better performance. Controllers will also automatically unbind correctly-bound handlers when the destroy method is called. This will free memory when the Controller&#8217;s element is removed from the DOM and the Garbage Collector runs. Lastly, bound handlers are automatically scoped to the Controller&#8217;s DOM element which serves to encapsulate Controller logic.</p>
<p><strong>Declaring markup in Controllers</strong><br />
Generating markup in Controllers is another anti-pattern that undermines efficiencies gained by using JavaScriptMVC. If you&#8217;ve used JavaScript (or jQuery) to add basic interactivity to a website you are probably guilty of using the following pattern:<br />
<blockquote><code class="bad">$("#myElement").html(["&lt;p&gt;", myVar, "&lt;/p&gt;"].join(""));</code></p></blockquote>
<p>This may seem innocent enough, but imagine using this anti-pattern when more complex markup is required (like a datagrid). You would quickly create a nightmarish array of tags that would be impossible to maintain. If I inherit code like this from you, I will hunt you down and make you pay! But more importantly, if you inject markup into the DOM this way you&#8217;re not taking advantage &#8220;V&#8221; part of JavaScriptMVC. Here&#8217;s the JavaScriptMVC way of getting markup into the DOM:<br />
<blockquote><code class="good">/* Controller */<br />
$("#myElement").html($.View("myView.ejs", {myVar: myVar});</p>
<p>/* Template */<br />
&lt;p&gt;&lt;%= myVar %&gt;&lt;/p&gt;</code></p></blockquote>
<p>The above example is a bit simplistic but it&#8217;s important to understand how JavaScriptMVC Views improve your application. The View class abstracts the frontend templates from the Controller allowing an application to make use of one or more JavaScript templating languages (EmbeddedJS, JAML, Micro and jQuery.Tmpl by default.) Extending the View class will allow you to use additional template languages as well. Also, by stealing views (i.e. including them via JavaScriptMVC&#8217;s dependency loader) you are adding them to the list of assets subject to concatenation and caching by the JavaScriptMVC build script. This will reduce HTTP requests and ultimately produce a faster application. Using frontend templates helps you write readable, easy to maintain and reusable markup.   </p>
<p><strong>Replacing node contents instead of using $.View</strong><br />
Another View-related anti-pattern involves replacing individual node contents from the Controller instead of using the View like this:<br />
<blockquote><code class="bad">$.Controller('DataGrid', {}, {<br />
&nbsp;&nbsp;"{model} data" : function(DataGrid, ev, data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, ilen = datagrid.rows.length; i &lt; ilen; i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("tr").eq(i).html(["&lt;td&gt;", data.rows[i].column1, "&lt;/td&gt;"].join(""));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
});</code></p></blockquote>
<p>In the above example, we are accessing the DOM multiple times in an effort to replace part of the markup of the DataGrid. A better pattern is to let the View work automagically update the DOM like this:<br />
<blockquote>
<code class="good">$.Controller('DataGrid', {}, {<br />
&nbsp;&nbsp;"{model} data" : function(DataGrid, ev, data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;$("table").html($.View("table.ejs", {rows: data.rows});<br />
&nbsp;&nbsp;}<br />
});</code></p></blockquote>
<p>This reduces the number of times the DOM is accessed and once again keeps the Controller free of markup.</p>
<p><strong>Failure to call <code>_super()</code> when overriding <code>destroy</code></strong><br />
The life of a page in a single-page web application is much longer than the life of a page in a traditional web application. This means that small memory leaks can add-up over time resulting in a sluggish, possibly unusable application. Luckily JavaScriptMVC provides a clear pattern for avoiding such memory leaks through the Controller&#8217;s <code>destroy</code> method. This is one of my favorite features of the framework &#8211; memory leak prevention via automatically unbound and undelegated event handlers. </p>
<p>The <code>$.Controller.destroy()</code> method is automatically called when the related element is removed from the DOM. But it&#8217;s common for objects that extend <code>$.Controller</code> to perform teardown operations before destroy runs. In this case, a controller would override the destroy method like this:<br />
<blockquote><code class="good">$.Controller('DataGrid', {}, {<br />
&nbsp;&nbsp;destroy : function() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;//perform controller-specific teardown tasks<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.element.html("You destroyed me");<br />
&nbsp;&nbsp;&nbsp;&nbsp;//if you forget the next function call, bad things will happen<br />
&nbsp;&nbsp;&nbsp;&nbsp;this._super();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}});</code></p></blockquote>
<p>Calling <code>this._super()</code> triggers the <code>$.Controller</code> to perform it&#8217;s default teardown operations such as unbinding and undelegating event handlers. If you don&#8217;t call <code>this._super()</code> when overriding the destroy method, your controller&#8217;s handlers remain bound and delegated which keeps a reference to the controller in memory. Objects remain in memory as long as they are referenced, so call <code>this._super()</code> when overriding <code>destroy</code> to prevent memory leaks in JavaScriptMVC applications.</p>
<p><strong>Using DOM node attributes instead of model attributes.</strong><br />
I often use HTML5 custom data attributes to store information that isn&#8217;t of immediate importance to the user but may be relevant in the future. Like this<br />
<blockquote><code class="bad">&lt;ul&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li id="brian" data-kingdom="animalia" data-phylum="chordata" data-clazz="mammalia" data-order="primata"&gt;BRIAN&lt;/li&gt;<br />
&lt;/ul&gt;</code></p></blockquote>
<p>This is ugly, but it&#8217;s convenient if you want to alert the user of the biological classification of an organism on click like this:<br />
<blockquote><code class="good">var brian = document.getElementById("brian"),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clickHandler = function(event){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var el = event.target;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert( [el.innerHTML, "is a", el.dataset.kingdom, el.dataset.phylum, el.dataset.clazz, el.dataset.order].join(" ") );<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
			brian.addEventListener("click", clickHandler, true);</code></p></blockquote>
<p>However, in JavaScriptMVC creating a model to store the organism details would be much cleaner. To refactor the above code, we would first create an organism View:<br />
<blockquote><code class="good">&lt;li &lt;%= this %&gt; &gt;&lt;%= this.name %&gt;&lt;/li&gt;</code></p></blockquote>
<p>Then an organism Controller:<br />
<blockquote><code class="good">$.Controller('Organism', {listensTo: ['click']}, {<br />
&nbsp;&nbsp;init : function() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;var model = $.Model.extend({},{name: "Brian", kingdom: "animalia", phylum: "chordata", clazz: "mammalia", order: "primata"});<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.element.html($.View('organism.ejs', model);<br />
&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;click : function(el, ev) { alert( [el.model().name, "is a", el.model().kingdom, el.model().phylum, el.model().clazz, el.model().order].join(" ") };<br />
});</code></p></blockquote>
<p>This pattern keeps the markup clean as the complexity of the organism object increases.</p>
<p>There are a few additional anti-patterns that don&#8217;t warrant a lengthy explanation like the ones above:<br />
<strong>Manipulating data in the View</strong><br />
If you need to manipulate the data being rendered in your View, do that in your Model, not the template.</p>
<p><strong>Accessing DOM from a Model</strong><br />
Your Models should have no knowledge of the DOM, so if your model queries the DOM you&#8217;ve done something wrong. If your model needs external data, pass it to the Model via the <code>attr</code> method.</p>
<p><strong>Using OpenAjax(global pub/sub) instead of events. (<3.1)</strong><br />
If your application uses multiple instances of the same controller at once, global pub/sub is a terrible way to notify your views of changes in the model. Use model attribute binding instead. </p>
<p><strong>Failure to use JSLint as you go</strong><br />
The JavaScriptMVC build script opens your JavaScript files in Rhino, which has little tolerance for seemingly-innocuous problems in your files (like trailing commas in object literals.) You should use JSLint as you go or run steal.clean before your build. (Note: If you use TextMate, check out the <a href="https://github.com/johnmuhl/javascript-tools-tmbundle" title="JavaScript Tools bundle for TextMate">JavaScript Tools bundle</a> which notifies you warnings/errors as you save)</p>
<p>These are just a few of the anti-patterns that can plague single-page JavaScript application development. By avoiding these anti-patterns and using best practices, you can appreciate the power of JavaScriptMVC.</p>
<p>The post <a href="http://www.brianhadaway.com/javascriptmvc-anti-patterns/">JavaScriptMVC Anti-Patterns</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/K9xi2Zrobus" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/javascriptmvc-anti-patterns/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/javascriptmvc-anti-patterns/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=javascriptmvc-anti-patterns</feedburner:origLink></item>
		<item>
		<title>UbaPlayer – The jQuery HTML5 Audio Player with Flash Fallback</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/_MyrG0KDXDo/</link>
		<comments>http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/#comments</comments>
		<pubDate>Sat, 17 Mar 2012 16:15:25 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[progressive enhancement]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=511</guid>
		<description><![CDATA[<p>I received a lot of questions and feedback about my HTML5 Audio Player with Flash Fallback, so I decided to rewrite it to fix some bugs and add some of the most requested features and call it UbaPlayer. This is a full rewrite of my previous jquery.audiocontrol.js. If you&#8217;re still using jquery.audiocontrol.js, STOP and update...  <a href="http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/" title="Read UbaPlayer &#8211; The jQuery HTML5 Audio Player with Flash Fallback" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/">UbaPlayer &#8211; The jQuery HTML5 Audio Player with Flash Fallback</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>I received a lot of questions and feedback about my <a href="http://www.brianhadaway.com/audio/oneButtonAudioPlayer.html">HTML5 Audio Player with Flash Fallback</a>, so I decided to rewrite it to fix some bugs and add some of the most requested features and call it <a href="http://www.brianhadaway.com/audio/oneButtonAudioPlayer.html">UbaPlayer</a>. This is a full rewrite of my previous jquery.audiocontrol.js. If you&#8217;re still using jquery.audiocontrol.js, STOP and update to ubaPlayer now.<span id="more-511"></span></p>
<p>UbaPlayer is free and open source (<a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>/<a href="http://www.opensource.org/licenses/mit-license.php">MIT</a>). <a href="https://github.com/brianhadaway/UbaPlayer/zipball/master">Download UbaPlayer 1.0.0</a>.</p>
<h2>Live Examples</h2>
<p><a href="http://0800studio.ch/hoeren.html">0800 Studio</a><br />
<a href="http://www.manythings.org/ipad/listen/'>Listen and Read Along (a tool for studying English as a foreign language)</a><br />
<a href="http://www.mysongbook.com">MySongbook.com</a><br />
<a href="http://www.trumpetmoments.com/">TrumpetMoments.com</a><br />
<a href="http://loveaurell.com/">LoveAurell.com</a></p>
<h2>Browser Compatibility</h2>
<p>UbaPlayer is tested to work in the following browsers:<br />
	Mac (Chrome 10+, Safari 4+, Firefox 3.5+, Opera)<br />
	PC (Chrome 10+, Safari 4+, Firefox3.5+, Opera, IE6+)<br />
	iOS 3+ (Safari Mobile)<br />
	Android 2.2+ (Chrome, Firefox 4, Opera 11)</p>
<h2>Audio Formats</h2>
<p>Since UbaPlayer is a simple player, it only supports two codecs by default &#8211; <strong>OGG</strong> and <strong>MP3</strong>. These two formats are all you really need to play audio natively in modern browsers and via Flash in antiquated browsers. If you need to transcode audio it&#8217;s quick an painless if you have the right tool. <a href="http://audacity.sourceforge.net/">Audacity</a> is a good free tool for Mac (I&#8217;m not aware of a tool for PC.) If the task of transcoding audio seems daunting, you may want to reconsider whether you have the technical aptitude to be a web developer.  If you want to add support for other codecs read on and I&#8217;ll show you how.</p>
<h2>Basic Usage</h2>
<p><a href="https://github.com/brianhadaway/UbaPlayer">Fork or Download UbaPlayer</a> and place the contents of the deploy directory in your web server. Launch ubaplayer.html in your browser of choice. Verify that the demo works before making any customizations to the code.</p>
<p>UbaPlayer requires at least one <code>&lt;ul&gt;</code> with a class of &#8216;controls&#8217; that contains one or more <code>&lt;li&gt;</code> with the class of &#8216;audioButton&#8217; and an href attribute with the path of the corresponding media file (with no file extension). In the example file, the markup looks like this:<br />
<script src="https://gist.github.com/2305230.js?file=UbaPlayer"></script></p>
<p>UbaPlayer can be instantiated on any DOM element. I&#8217;ll instantiate the div with the id of &#8216;ubaPlayer&#8217; in the markup above like this:<br />
<script src="https://gist.github.com/2305435.js?file=UbaPlayer%20-%20Basic%20Instantiation"></script><br />
<iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/brianhadaway/DmX34/36/embedded/result/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p>At this point UbaPlayer has been instantiated and is ready to play. But what if you want to configure UbaPlayer? Below are some simple configurations:</p>
<p><strong>Setting Volume</strong><br />
Note that setting the volume only works on desktop devices. <a href="http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW1">Media volume on mobile devices is managed by the user </a> and can&#8217;t be set via JavaScript.<br />
<script src="https://gist.github.com/2305661.js?file=UbaPlayer%20-%20Setting%20Volume"></script><br />
<iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/brianhadaway/2xrf6/4/embedded/result/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p><strong>Auto Play</strong><br />
Just pass the element that corresponds to the audio you want to play.<br />
<script src="https://gist.github.com/2305705.js?file=UbaPlayer%20-%20Autoplay"></script><br />
<a href="http://brianhadaway.com/audio/autoplay.html">Auto Play example</a></p>
<p><strong>Set Codec Preferences/Add Additional Codecs</strong><br />
UbaPlayer supports OGG and MP3 by default. You can add additional codecs or set the order of preference as such:<br />
<script src="https://gist.github.com/2305724.js?file=UbaPlayer%20-%20Specifying%20Codecs"></script></p>
<p><strong>Limit Codecs</strong><br />
If UbaPlayer is unable to play any provided codecs natively, it uses Flash to play. The following code with tell UbaPlayer to attempt to play MP3 files natively then use Flash instead of attempting to play OGG files.<br />
<script src="https://gist.github.com/2305730.js?file=UbaPlayer%20-%20MP3%20Only"></script></p>
<p><strong>External Controls</strong><br />
If you want to provide a way for users to control playback outside of the single button, you can provide external controls. The code below assumes you have a button in the DOM that toggles playback of the current track.<br />
<script src="https://gist.github.com/2305745.js?file=UbaPlayer%20-%20External%20Controls"></script><br />
<iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/brianhadaway/mND5e/10/embedded/result/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<p><a href="https://github.com/brianhadaway/UbaPlayer/zipball/master">Download UbaPlayer &#8211; The jQuery HTML5 Audio Player with Flash Fallback</a></p>
<p>The post <a href="http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/">UbaPlayer &#8211; The jQuery HTML5 Audio Player with Flash Fallback</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/_MyrG0KDXDo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/feed/</wfw:commentRss>
		<slash:comments>65</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=ubaplayer-the-jquery-html5-audio-player-with-flash-fallback</feedburner:origLink></item>
		<item>
		<title>OGG Files Causing Errors in HTML5 Audio Player in Firefox</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/ehy6tamiDuo/</link>
		<comments>http://www.brianhadaway.com/ogg-files-causing-errors-in-html5-audio-player-in-firefox/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 18:36:30 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[browser quirks]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=504</guid>
		<description><![CDATA[<p>About a year ago I created an HTML5 Audio Player with Flash Fallback that several developers have used in their sites. It&#8217;s not the most robust player, but what it lacks in features it makes up for in simplicity. It plays audio files natively in modern browsers and uses a simple Flash player to backfill...  <a href="http://www.brianhadaway.com/ogg-files-causing-errors-in-html5-audio-player-in-firefox/" title="Read OGG Files Causing Errors in HTML5 Audio Player in Firefox" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/ogg-files-causing-errors-in-html5-audio-player-in-firefox/">OGG Files Causing Errors in HTML5 Audio Player in Firefox</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>About a year ago I created an <a href="http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/">HTML5 Audio Player with Flash Fallback</a> that several developers have used in their sites. It&#8217;s not the most robust player, but what it lacks in features it makes up for in simplicity. It plays audio files natively in modern browsers and uses a simple Flash player to backfill audio tag functionality in antiquated browsers. The UI is styled with CSS regardless of whether the browser plays audio natively or via Flash and implementing the plugin is simple enough for novice developers.<span id="more-504"></span></p>
<p>Given the simplicity of the player, I was surprised when I recently received an email from someone asking me to help determine why my <a href="http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/">HTML5 Audio Player</a> wouldn&#8217;t work for him in Firefox. He had seemingly configured everything correctly and the player worked in every other popular browser, but he still couldn&#8217;t get the player to work in Firefox. <strong>As it turns out most servers (including those used by GoDaddy) by default don&#8217;t serve the appropriate MIME Types for OGG files.</strong> That being the case, you&#8217;ll need set the appropriate MIME Types for OGG files if you want HTML5 audio players to work correctly in Firefox. So for an Apache server, you would need to add the following to your .htaccess file:</p>
<p><code>AddType audio/ogg .oga<br />
AddType video/ogg .ogv<br />
AddType application/ogg .ogg</code></p>
<p>Evidently, other browsers will guess the MIME Type based on file extension if a MIME Type isn&#8217;t served. I had just been lucky that all the servers I used up until this point were already configured to serve the right MIME Types.</p>
<p>If you want more info about this, check <a href="https://developer.mozilla.org/en/Configuring_servers_for_Ogg_media">this page on the Mozilla Developer Network</a>.</p>
<p>The post <a href="http://www.brianhadaway.com/ogg-files-causing-errors-in-html5-audio-player-in-firefox/">OGG Files Causing Errors in HTML5 Audio Player in Firefox</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/ehy6tamiDuo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/ogg-files-causing-errors-in-html5-audio-player-in-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/ogg-files-causing-errors-in-html5-audio-player-in-firefox/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=ogg-files-causing-errors-in-html5-audio-player-in-firefox</feedburner:origLink></item>
		<item>
		<title>iPhone-Style Alphabetical Contact List with HTML, CSS and JavaScript (jQuery)</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/YXrPhJ4pI84/</link>
		<comments>http://www.brianhadaway.com/iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery/#comments</comments>
		<pubDate>Wed, 04 May 2011 16:40:23 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[Labs]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=438</guid>
		<description><![CDATA[<p>Here&#8217;s what you&#8217;re most likely looking for &#8211; the demo and the source. Feel free to read the explanation while you&#8217;re here. Front-end developers are often called on to build UI elements that aren&#8217;t entirely original. Whether the cause of this phenomenon is a lack of creativity on the part of designers or a particular...  <a href="http://www.brianhadaway.com/iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery/" title="Read iPhone-Style Alphabetical Contact List with HTML, CSS and JavaScript (jQuery)" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery/">iPhone-Style Alphabetical Contact List with HTML, CSS and JavaScript (jQuery)</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p><em>Here&#8217;s what you&#8217;re most likely looking for &#8211; <a href="http://www.brianhadaway.com/ioslist/index.html">the demo</a> and <a href="https://github.com/brianhadaway/iOSList/zipball/master">the source</a>. Feel free to read the explanation while you&#8217;re here.</em></p>
<p>Front-end developers are often called on to build UI elements that aren&#8217;t entirely original. Whether the cause of this phenomenon is a lack of creativity on the part of designers or a particular affinity for certain UI elements among the web-browsing public, <del>ripping-off</del> drawing inspiration from others&#8217; ideas is common in web design. One of the most prominent sources of such &#8220;inspiration&#8221; over the past few years is Apple&#8217;s Aqua interface. Thanks to this glossy, semi-transparent, gradient-laden design, front-end and Flash developers have spent several years worth of billable hours creating simulated reflections and configuring cover flow components for clients insistent upon having sites that &#8220;look more web 2.0&#8243;. <span id="more-438"></span></p>
<p>Thanks to the advent of iOS devices, there&#8217;s a new set of Apple-designed UI elements that designers are using as inspiration. In fact, there&#8217;s already an open source project, iUI, that aims to provide &#8220;a more &#8216;iPhone-like&#8217; experience in your WebApps&#8221; using HTML, CSS and Javascript. The iUI project not only imitates the look of the iOS interface, but it also seeks to emulate the subtleties of the experience of using an iPhone, iPad or iPod. One such subtlety, that I haven&#8217;t seen successfully recreated in HTML, CSS and JavaScript is the alphabetical lists seen in Contacts and Music (among other places) in the iPhone, iPad and iPod. To test my mettle, I set out to recreate that seemingly-simple UI component.</p>
<p>One of the most prominent places alphabetical lists are used is in Music and Contacts. In case you aren&#8217;t familiar, here&#8217;s what it looks like in Music:</p>
<div id="attachment_439" class="wp-caption alignnone" style="width: 330px"><img src="http://www.brianhadaway.com/wp-content/uploads/2011/05/ioslist1.png" alt="" title="ioslist1" width="320" height="480" class="size-full wp-image-439 screenshot" /><p class="wp-caption-text">The heading for the current list section (A) remains stationary as the user scrolls through the section.</p></div>
<div id="attachment_440" class="wp-caption alignnone" style="width: 330px"><img src="http://www.brianhadaway.com/wp-content/uploads/2011/05/ioslist2.png" alt="" title="ioslist2" width="320" height="480" class="size-full wp-image-440 screenshot" /><p class="wp-caption-text">As the adjacent section (B) approaches the top of the list container, the current section (A) and header scroll off screen.</p></div>
<div id="attachment_441" class="wp-caption alignnone" style="width: 330px"><img src="http://www.brianhadaway.com/wp-content/uploads/2011/05/ioslist3.png" alt="" title="ioslist3" width="320" height="480" class="size-full wp-image-441 screenshot" /><p class="wp-caption-text">Once the header for the new section (B) reaches the top of the list container, its position becomes fixed and it remains in place until the user scrolls to a new section.</p></div>
<h4>The Concept</h4>
<p>The main challenge to overcome is the need to reposition the current section’s header every time the list’s scroll event fires. For instance, while A is the current section, its header must appear to remain fixed at the top of the list until it “collides” with the next section’s header (B). Once A’s header “collides” with B’s header, A’s header becomes fixed to the bottom of its section where it remains until the bottom of the section A exceeds the height of its header. Performing these calculations as the scroll event fires (inconsistently across browsers) is taxing and on users&#8217; machines and results in the header flickering as the list scrolls.</p>
<p>Given this challenge, it is necessary to resort to some sleight of hand. I can create a “fake header” that will remain fixed at the top of the list. This header will remain visible until I need to show headers A and B collide at which time I will hide the fake header, show the animation then update the text in the fake header and unhide it. This alleviates the need to reposition the current section’s header every time the list’s scroll event fires resulting in a better-performing, flicker-free iPhone-style contact list.</p>
<div id="attachment_467" class="wp-caption alignnone" style="width: 296px"><img src="http://www.brianhadaway.com/wp-content/uploads/2011/05/example.jpg" alt="" title="example" width="286" height="660" class="size-full wp-image-467 screenshot" /><p class="wp-caption-text">(1) Fake Header visible (2) Fake Header hidden, 'A' header positioned to bottom of its parent, (3) Fake Header visible with text updated to 'B'</p></div>
<h4>The Markup</h4>
<p>This is the perfect use of the under-appreciated definition list element (DL). By using a DL, I can use its child element DT as the header and DD as the list item. There’s only one issue with this approach. I need to keep the elements associated with a certain heading grouped so I can measure groups’ height and position. I could wrap each group in a DIV, but that would be semantically incorrect (DL should only have DT and DD as children), so I’ll use individual DL elements for each group. I wrap my DL elements in a DIV with the ID of “list1” and the class of “listContainer”. This will be the scrolling container and will allow multiple list instances in one page.</p>
<h4>The JavaScript</h4>
<p>The logic in the JavaScript for this component is quite simple. I’ve already discussed the logic to some extent in “The Concept” above, so let’s talk about optimizing the script.</p>
<p>When using jQuery, developers often fall into the trap of repeatedly accessing the same DOM element. Without exercising care performance will tank so I want to call methods that access the DOM as infrequently as possible. The obvious way of doing this is by caching elements and wrapped sets. Another way I reduce DOM access method calls is by operating on cached element properties instead of repeatedly retrieving those properties from the DOM. For instance, every time the scroll event fires I need to determine which element is at the top of the list and which element and its previous sibling. To do this efficiently, I reference cached element properties stored in an array instead of accessing the DOM elements’ properties. This drastically increases performance.</p>
<h4>The CSS</h4>
<p>Much of the list’s CSS is used to adhere (loosely) to a visual design but some of the styles are instrumental to the functionality. View the source of the sample to see what&#8217;s going on with the CSS. It&#8217;s pretty simple.</p>
<h5>Download the <a href="http://www.brianhadaway.com/ioslist/index.html">Demo</a> and <a href="https://github.com/brianhadaway/iOSList/zipball/master">Source</a> or <a href="https://github.com/brianhadaway/iOSList">fork it on GitHub</a></h5>
<p>The post <a href="http://www.brianhadaway.com/iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery/">iPhone-Style Alphabetical Contact List with HTML, CSS and JavaScript (jQuery)</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/YXrPhJ4pI84" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=iphone-apple-style-alphabetical-contact-lists-in-html-css-javascript-jquery</feedburner:origLink></item>
		<item>
		<title>Responsive Web Design Using CSS3 Media Queries</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/I-vwjGzrwgg/</link>
		<comments>http://www.brianhadaway.com/responsive-web-design-using-css3-media-queries/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 21:25:44 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[progressive enhancement]]></category>
		<category><![CDATA[responsive design]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=392</guid>
		<description><![CDATA[<p>Responsive web design is a type of progressive enhancement that uses fluid grids, flexible-size images and media queries to optimize a website for a users&#8217; specific viewing context. At its core, responsive web design is about adjusting layout, typography and imagery to provide a consistent, device-independent web experience. Fluid grids and flexible size images aren&#8217;t...  <a href="http://www.brianhadaway.com/responsive-web-design-using-css3-media-queries/" title="Read Responsive Web Design Using CSS3 Media Queries" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/responsive-web-design-using-css3-media-queries/">Responsive Web Design Using CSS3 Media Queries</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Responsive web design is a type of progressive enhancement that uses fluid grids, flexible-size images and media queries to optimize a website for a users&#8217; specific viewing context.  At its core, responsive web design is about adjusting layout, typography and imagery to provide a consistent, device-independent web experience. Fluid grids and flexible size images aren&#8217;t new concepts to web design, so I&#8217;ll spend most of this post discussing media queries. <span id="more-392"></span></p>
<p>There has been a lot of recent debate about whether responsive web designs are a valid alternative to dedicated mobile sites and/or native applications.  Some call the practice &#8220;fools gold&#8221; while others think responsive web design finally lets developers achieve the code-once-for-all-platforms-nirvana we&#8217;ve been seeking for so long. In reality, it&#8217;s likely neither of the above. But the fact remains that I want my site to look good and be easy to use on mobile devices without having to create a dedicated mobile site. For me, CSS3 media queries are the answer.</p>
<p>The &#8220;media&#8221; part of media queries isn&#8217;t new to CSS. Prior to CSS3 you could limit the scope of stylesheets, but we were confined to a set of media types like print, screen and projection. This was a serviceable solution back when all screens were similarly-sized. But now, since screens vary so greatly in size, it is necessary to further-inspect the media on which a user is viewing a site to determine how best to display the site. Thankfully, the CSS3 specification expands media type-dependent stylesheet support by allowing the use of expressions to further limit the scope of stylesheets. Using CSS3 media queries, we can inspect characteristics of users&#8217; devices, such as size, orientation, resolution and pixel density, and adapt styles accordingly.</p>
<p>Media queries can exist in HTML or @import and @media rules in CSS. As if the name wasn&#8217;t a dead giveaway, media queries consist of a media type and a query. Media types include print, projection, screen, handheld, aural, Braille, tty, tv and all. If you&#8217;re familiar media types, you may ask why we can&#8217;t simply use the handheld type to target mobile devices. Technically you can but the Symbian browser, Opera and mobile Safari ignore the handheld type. According to Apple&#8217;s developer guides mobile Safari &#8220;ignores the print and handheld media queries because these types do not supply high-end content.&#8221;</p>
<p>The second part of media queries, the query, inspects media features to determine when specific styles are used. The most commonly used media features include width, height, device-width, device-height and orientation. Media features that pertain to width and height accept the min- and max- prefixes allowing us to further refine the scope of a particular style. Orientation is calculated by comparing the browser width and height. This makes it possible to query the orientation any device, not just tablets and mobiles.</p>
<p>One additional media feature of interest, device-pixel-ratio, allows inspection of pixel density. Querying this media feature allows you to serve higher-resolution images for the iPhone Retina display. Unfortunately, at the time of this writing, it is necessary to use vendor prefixes so you&#8217;ll need to add -webkit and -moz to make this work. Eventually you&#8217;ll be able to use just device-pixel-ratio. You can also apply the min- and max- prefixes to device-pixel-ratio.</p>
<p>One of the keys to successfully implementing a responsive web design is determining the resolutions at which your site should &#8220;respond&#8221;. This highly dependent upon the design of your site but you will likely want your site to respond at (or near) common tablet and mobile device resolutions (1024px and 768px for iPad, 960px and 640px for iPhone 4 and 480px and 320px for iPhone 3GS and older).</p>
<p>So what does a media query look like? It depends on where you put it. As mentioned earlier, media queries can exist in HTML or @import and @media rules in CSS:</p>
<h4>Media Query in HTML</h4>
<p><code>&lt;link rel="stylesheet" media="screen and (max-width: 1024px)" rel="stylesheet" href="example.css"&gt;</code></p>
<h4>Media Query in @import</h4>
<p><code>@import url(example.css) screen and (max-width: 1024px)</code></p>
<h4>Media Query in stylesheet</h4>
<p><code>@media screen and (max-width: 1024px) { ..styles go here  }</code></p>
<p>The stylesheet I use to achieve my responsive design for this site consists of a set of base styles and three sets of media queries. The base styles apply to all browsers with a width greater than 994px. Browsers that don&#8217;t support CSS3 use the base styles as well. There are several options for adding media query support to those browsers, but since the goal of my responsive design is to improve the appearance and usability of my site on mobile devices and tablets (all of which have browsers that support CSS3), I chose not to implement a fallback.</p>
<p>Here are the media queries used in my site:</p>
<p><code>@media only screen and (min-device-width: 768px) and (orientation: portrait),<br />
screen and (max-width: 994px) { /* for tablets in portrait mode and desktops with less than 994px of horizontal browser width */ }</p>
<p>@media screen and (max-width: 555px),<br />
screen and (max-device-width: 480px) { /* for desktops with less than 555px of horizontal browser width and devices with less than 480px wide (most phones in landscape orientation) */ }</p>
<p>@media screen and (max-width: 320px) { /* anything less than 320px (primarily phones in portrait */ }<br />
</code></p>
<p>In addition to these media queries, I use a viewport meta tag to set the initial scale of the site and disable zooming on mobile devices and tablets. The viewport meta tag looks like this:</p>
<p><code>&lt;meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"&gt;</code></p>
<p>Here&#8217;s what my site looks like at various browser sizes:<br />
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/04/full.jpg" alt="BrianHadaway.com - Full Size" title="BrianHadaway.com - Full Size" width="532" height="351" class="alignleft size-full wp-image-422 screenshot" /></p>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/04/netbook.jpg" alt="BrianHadaway.com - Tablet Landscape Orientation" title="BrianHadaway.com - Tablet Landscape Orientation" width="376" height="350" class="alignleft size-full wp-image-425 screenshot" />
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/04/tablet.jpg" alt="BrianHadaway.com - Tablet Portrait Orientation" title="BrianHadaway.com - Tablet Portrait Orientation" width="280" height="350" class="alignleft size-full wp-image-426 screenshot" />
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/04/mobile_landscape.jpg" alt="BrianHadaway.com - Mobile Landscape Orientation" title="BrianHadaway.com - Mobile Landscape Orientation" width="154" height="351" class="alignleft size-full wp-image-423 screenshot" />
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/04/mobile_portrait.jpg" alt="BrianHadaway.com - Mobile Portrait Orientation" title="BrianHadaway.com - Mobile Portrait Orientation" width="112" height="351" class="alignleft size-full wp-image-424 screenshot" />
<p>As much as I like responsive web design, there are some valid criticisms of the practice. Responsive web design assumes that there is only one use case for all browsing contexts which is not always the case. For instance, visitors using tablets or desktops may be interested in viewing a retail site&#8217;s photo gallery or testimonials, while someone using a mobile device may be solely interested in finding a phone number or store hours. Also, the practice of only using media queries to implement responsive design can result in unnecessary overhead when loading elements that aren&#8217;t used in smaller contexts. If a media query for a small mobile context hides a slideshow, the browser still may unnecessarily load the related script and images.</p>
<p>Dedicated mobile sites and native applications may be the right solution for some projects, but responsive web design with CSS3 media queries is a quick and easy way to provide a consistent user experience across all browsing contexts.</p>
<p>The post <a href="http://www.brianhadaway.com/responsive-web-design-using-css3-media-queries/">Responsive Web Design Using CSS3 Media Queries</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/I-vwjGzrwgg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/responsive-web-design-using-css3-media-queries/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/responsive-web-design-using-css3-media-queries/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=responsive-web-design-using-css3-media-queries</feedburner:origLink></item>
		<item>
		<title>HTML5 Audio Player with Flash Fallback</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/7po2RsngGDQ/</link>
		<comments>http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 16:12:24 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Labs]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=358</guid>
		<description><![CDATA[<p>UPDATE (Mar 17, 2012): I recently rewrote jquery.audiocontrol.js as a new plugin, UbaPlayer, which includes many features requested by users over the past year. UbaPlayer is conceptually similar to the old player but more flexible. Keep this in mind as you read the comments below &#8211; they may not apply to ubaPlayer. I wanted to...  <a href="http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/" title="Read HTML5 Audio Player with Flash Fallback" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/">HTML5 Audio Player with Flash Fallback</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>UPDATE (Mar 17, 2012): I recently rewrote jquery.audiocontrol.js as a new plugin, <a href="http://www.brianhadaway.com/ubaplayer-the-jquery-html5-audio-player-with-flash-fallback/">UbaPlayer</a>, which includes many features requested by users over the past year. UbaPlayer is conceptually similar to the old player but more flexible. Keep this in mind as you read the comments below &#8211; they may not apply to ubaPlayer.</p>
<p>I wanted to create a <a href="http://www.brianhadaway.com/audio/oneButtonAudioPlayer.html">simple one-button audio player using HTML5</a> that would be suitable for playing samples of audio tracks. This one-button player would toggle between play, pause and loading states and would stop playing the current track when another instance of the button is clicked. Naturally, I would want to include a Flash fallback for browsers that don&#8217;t support HTML5 audio playback. I also wanted to use HTML/CSS to style a single set of controls that serve as the UI for both the HTML5 and Flash versions of the player.</p>
<p>What resulted from this exercise was a jQuery audiocontrol plugin that controls playback and an &#8220;invisible&#8221; Flash audio player that emulates the HTML5 <code>&lt;audio&gt;</code> element. The control lacks some necessary features such as support for playlists and &#8220;bundled&#8221; playback. This would allow users to listen to a group of tracks without continually clicking play. Also, there is currently no publicly-exposed method to kill audio playback from outside the control. This is also my first jQuery plugin so there&#8217;s probably some improvement to be made in that code. But it&#8217;s still a <a href="http://www.brianhadaway.com/audio/oneButtonAudioPlayer.html">good basic HTML5 audio player with Flash fallback</a> that allows you to style the buttons with CSS regardless of whether the audio is playing natively in the browser or in the Flash plugin.</p>
<p>The code is tested to work in the following browsers:</p>
<ol>
<li>Firefox 3.6 – Mac/PC</li>
<li>Safari 5 – Mac</li>
<li>Chrome 10 – Mac</li>
<li>Internet Explorer 7+ &#8211; PC</li>
<li>Firefox 4 – T-Mobile G2 (Android 2.2)</li>
<li>Opera Mobile 11 – T-Mobile G2 (Android 2.2)</li>
<li>Default Browser – T-Mobile G2 (Android 2.2)</li>
<li>Safari Mobile – iPad and iPod Touch (iOS)</li>
</ol>
<p>Take a look at a <a href="http://www.brianhadaway.com/audio/oneButtonAudioPlayer.html">demo of my HTML5 audio player with Flash fallback</a> here. Feel free to <a href="https://github.com/brianhadaway/UbaPlayer/zipball/master">download the source</a> and use it however you like. You&#8217;ll find some documentation in the jQuery plugin or you can hit me up with a comment or email if you have questions about how to customize this to your needs.</p>
<p>The post <a href="http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/">HTML5 Audio Player with Flash Fallback</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/7po2RsngGDQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/feed/</wfw:commentRss>
		<slash:comments>111</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=html5-audio-player-with-flash-fallback</feedburner:origLink></item>
		<item>
		<title>HTML5 Audio Support on Android Devices</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/z7CglPI4eXY/</link>
		<comments>http://www.brianhadaway.com/html5-audio-support-on-android-devices/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 20:50:01 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[browser quirks]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=291</guid>
		<description><![CDATA[<p>UPDATE: Here&#8217;s a new post about a cross-browser HTML5 audio player with Flash fallback that effectively solves the problem described below. In a previous post, I mentioned that I wanted to see first-hand how each browser renders default controls for the HTML5 audio element. I created a simple demo page and tested it in the...  <a href="http://www.brianhadaway.com/html5-audio-support-on-android-devices/" title="Read HTML5 Audio Support on Android Devices" class="excerpt-read-more">Read more &#187;</a></p><p>The post <a href="http://www.brianhadaway.com/html5-audio-support-on-android-devices/">HTML5 Audio Support on Android Devices</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE:</strong> Here&#8217;s a new post about a <a href="http://www.brianhadaway.com/html5-audio-player-with-flash-fallback/">cross-browser HTML5 audio player with Flash fallback</a> that effectively solves the problem described below.</p>
<p>In a previous post, I mentioned that I wanted to see first-hand <a href="http://www.brianhadaway.com/how-html5-audio-controls-render-in-modern-browsers/">how each browser renders default controls for the HTML5 audio element</a>. I created a simple demo page and tested it in the following browsers:</p>
<ol>
<li>Firefox 4 &#8211;  Mac (OSX 10.6)</li>
<li>Safari 5 &#8211; Mac (OSX 10.6)</li>
<li>Chrome 10 &#8211; Mac (OSX 10.6)</li>
<li>Internet Explorer 9 &#8211; PC (Vista)</li>
<li>Firefox 4 &#8211; T-Mobile G2 (Android 2.2)</li>
<li>Opera Mobile 11 &#8211; T-Mobile G2 (Android 2.2)</li>
<li>Default Browser &#8211;  T-Mobile G2 (Android 2.2) </li>
<li>Safari &#8211; iPad and iPod Touch (iOS)</li>
</ol>
<p> As I tested the demo on the G2 in Android 2.2&#8242;s (aka Froyo) default browser I was surprised to see that I get neither the browser&#8217;s default controls nor the fallback message enclosed inside the audio element. How could this be? <span id="more-291"></span></p>
<p>It&#8217;s my understanding that any text between the opening and closing audio tags will be displayed in browsers that do not support the audio element. So if that text doesn&#8217;t appear in then the browser supports HTML5 audio, right? So why does Android 2.2&#8242;s browser display the following:</p>
<img class="alignnone size-full wp-image-297" title="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Native Browser" src="http://www.brianhadaway.com/wp-content/uploads/2011/03/AndroidNative.png" alt="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Native Browser" width="202" height="18" />
<p>In every other browser tested, the following code rendered either audio controls or the fallback text:<br />
<code>&lt;audio controls="true"&gt;<br />
                 &lt;source src="media/AwMan.mp3"/&gt;<br />
                 &lt;source src="media/AwMan.ogg"/&gt;<br />
                 Your browser does not support HTML5 audio.<br />
             &lt;/audio&gt;</code></p>
<p>Logically, this tells me Android 2.2&#8242;s browser doesn&#8217;t support mp3 or ogg media types which is odd given the fact that every other tested browser supports one of the two codecs. So if Android&#8217;s browser doesn&#8217;t support these codecs, which does it support? Again, I created a test page to help me answer this question. (<a href="http://www.brianhadaway.com/audio/test.html">Click here to see which audio codecs your browser supports.</a>)</p>
<p>If you view the source on the test page you&#8217;ll see that first I check whether the browser can create an instance of the audio tag and whether it has the canPlayType method. If that test succeeds, I then test the most widely used codecs to see if they are supported in this particular browser. Calling canPlayType for a particular codec returns either &#8220;probably&#8221;, &#8220;maybe&#8221; or empty. Empty means that the codec isn&#8217;t supported. When I visit this test page on my Android device I see the following:</p>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/audio_support.png" alt="Android 2.2 HTML5 Audio Support" title="Android 2.2 HTML5 Audio Support" width="400" height="240" class="alignnone size-full wp-image-329" />
<p>As you can see, technically Android 2.2&#8242;s default browser supports HTML5 audio (in the sense that programmatically-created element has the canPlayType method) but it can&#8217;t play any media files encoded with popular codecs. So as it turns out in the case of the native Android 2.2 browser, you can&#8217;t simply let the browser interpret the markup to make the determination as to whether it can play audio. Though Google will likely fix this in future versions of Android, it will be up to the various service providers as to when this update is distributed to users. So it&#8217;s likely that this will continue to be an issue for awhile. This is definitely something to consider when providing fallback content for HTML5 audio.</p>
<p>The post <a href="http://www.brianhadaway.com/html5-audio-support-on-android-devices/">HTML5 Audio Support on Android Devices</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/z7CglPI4eXY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/html5-audio-support-on-android-devices/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/html5-audio-support-on-android-devices/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=html5-audio-support-on-android-devices</feedburner:origLink></item>
		<item>
		<title>How HTML5 Audio Controls Render In Modern Browsers</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/_P4PkUntQPY/</link>
		<comments>http://www.brianhadaway.com/how-html5-audio-controls-render-in-modern-browsers/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 21:51:33 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[browser quirks]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=295</guid>
		<description><![CDATA[<p>I created a test page using the most basic implementation of the HTML <code><audio></code> tag so I could see how modern browsers render the default controls. As is the case with almost everything browser-related, there is quite a bit of discrepancy in how each browser renders the controls.</p><p>The post <a href="http://www.brianhadaway.com/how-html5-audio-controls-render-in-modern-browsers/">How HTML5 Audio Controls Render In Modern Browsers</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>I created a test page using the most basic implementation of the HTML5 audio tag so I could see how modern browsers render the default controls. (<a href="http://www.brianhadaway.com/audio/basic.html">You can view my test page here.</a>) As is the case with almost everything browser-related, there is quite a bit of discrepancy in how each browser renders the controls. What&#8217;s surprising is how mobile versions of browsers render controls differently from their desktop counterparts. <span id="more-295"></span></p>
<p>You&#8217;ll also notice that the Native Browser on Android 2.2 (Froyo) doesn&#8217;t render the HTML5 audio controls at all. This is a known issue with Froyo and should be fixed in Android 3. <em>Update:</em> <a href="http://www.brianhadaway.com/html5-audio-support-on-android-devices/">Read more about this here</a>.</p>
<p>Take a look at how each browser renders HTML5 audio controls below:</p>
<h3>Firefox</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/FireFox.png" alt="Default HTML5 Audio Controls - Firefox" title="Default HTML5 Audio Controls - Firefox" width="300" height="37" class="alignnone size-full wp-image-300" />
<h3>Chrome</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/Chrome.png" alt="Default HTML5 Audio Controls - Chrome" title="Default HTML5 Audio Controls - Chrome" width="300" height="32" class="alignnone size-full wp-image-299" />
<h3>Safari</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/Safari.png" alt="Default HTML5 Audio Controls - Safari" title="Default HTML5 Audio Controls - Safari" width="200" height="25" class="alignnone size-full wp-image-303" />
<h3>Internet Explorer 9</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/IE9.png" alt="Default HTML5 Audio Controls - Internet Explorer 9" title="Default HTML5 Audio Controls - Internet Explorer 9" width="450" height="36" class="alignnone size-full wp-image-301" />
<h3>Native Browser &#8211; Android 2.2 (Froyo)</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/AndroidNative.png" alt="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Native Browser" title="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Native Browser" width="202" height="18" class="alignnone size-full wp-image-297" />
<h3>Firefox &#8211; Android 2.2 (Froyo)</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/AndroidFF.png" alt="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Firefox" title="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Firefox" width="296" height="137" class="alignnone size-full wp-image-296" />
<h3>Opera &#8211; Android 2.2 (Froyo)</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/AndroidOpera.png" alt="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Opera" title="Default HTML5 Audio Controls - Android 2.2 (Froyo) - Opera" width="534" height="53" class="alignnone size-full wp-image-298" />
<h3>Safari &#8211; iOS (iPhone and iPad)</h3>
<img src="http://www.brianhadaway.com/wp-content/uploads/2011/03/iOS.png" alt="Default HTML5 Audio Controls - iOS - Safari" title="Default HTML5 Audio Controls - iOS - Safari" width="394" height="51" class="alignnone size-full wp-image-302" />
<p>The post <a href="http://www.brianhadaway.com/how-html5-audio-controls-render-in-modern-browsers/">How HTML5 Audio Controls Render In Modern Browsers</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/_P4PkUntQPY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/how-html5-audio-controls-render-in-modern-browsers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/how-html5-audio-controls-render-in-modern-browsers/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=how-html5-audio-controls-render-in-modern-browsers</feedburner:origLink></item>
		<item>
		<title>Make @font-face Work on Android Devices</title>
		<link>http://feedproxy.google.com/~r/GoodWithCode/~3/tRdT2jic3c0/</link>
		<comments>http://www.brianhadaway.com/font-face-declarations-on-android-devices/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 20:55:16 +0000</pubDate>
		<dc:creator>Brian Hadaway</dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[@font-face]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.brianhadaway.com/?p=286</guid>
		<description><![CDATA[<p>If you use FontSquirrel to generate @font-face kits you may have noticed that they abandoned the Smiley method of generating CSS in favor of newer methods like FontSpring or Mo Bulletproofer.</p><p>The post <a href="http://www.brianhadaway.com/font-face-declarations-on-android-devices/">Make @font-face Work on Android Devices</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>If you use FontSquirrel to generate @font-face kits you may have noticed that they abandoned the Smiley method of generating CSS in favor of newer methods like FontSpring or Mo Bulletproofer. This is great because CSS generated by FontSquirrel will now successfully render fonts in browsers on Android devices. <span id="more-286"></span></p>
<p>What if you want to update existing declarations to be Android-friendly? Instead of regenerating the entire @font-face kit, you can simply update your @font-face declarations manually to support Android devices. Here&#8217;s a code snippet to get you started:</p>
<p><code>@font-face {<br />
	font-family: 'MyFont';<br />
	src: url('MyFont.eot?') format('eot'), url('MyFont.woff') format('woff'), url('MyFont.ttf') format('truetype'), url('MyFont.svg#webfontwTBKaDwa') format('svg');<br />
	font-weight: normal;<br />
	font-style: normal;<br />
}</code></p>
<p>BAM!</p>
<p>The post <a href="http://www.brianhadaway.com/font-face-declarations-on-android-devices/">Make @font-face Work on Android Devices</a> appeared first on <a href="http://www.brianhadaway.com">Brian Hadaway</a>.</p><img src="http://feeds.feedburner.com/~r/GoodWithCode/~4/tRdT2jic3c0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.brianhadaway.com/font-face-declarations-on-android-devices/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.brianhadaway.com/font-face-declarations-on-android-devices/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=font-face-declarations-on-android-devices</feedburner:origLink></item>
	</channel>
</rss>
