How to fallback from CDN to local jQuery

External dependencies are, in fact, external. As such, they are calculated risks with tradeoffs. CDNs are great, but for those minutes or hours that they go down a year, they can be very annoying.

How can we as application developers fallback gracefully when an external dependency like a CDN goes down?

With JavaScript we can detect when our CDN-hosted JavaScript resources like jQuery or jQuery UI aren't loaded successfully and try again to load them from local locations.

One way to create a CDN fallback is to check for a type or variable that should be present after a script load. If that variable is not there, try getting that script locally.

Note the important escape characters within the document.write. Here's a jQuery example:

view plain print about
1<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
2<script>
3if (typeof jQuery == 'undefined') {
4 document.write(unescape("%3Cscript src='/js/jquery-2.0.0.min.js' type='text/javascript'%3E%3C/script%3E"));
5}
6</script>

Or you can do something like this:

view plain print about
1<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
2<script>window.jQuery || document.write('<script src="js/jquery-2.0.0.min.js">\x3C/script>
')</script>

You can also use RequireJS, which has a great shorthand for fallback URLs:

view plain print about
1requirejs.config({
2 enforceDefine: true,
3 paths: {
4 jquery: [
5 '//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
6 //If the CDN location fails, load from this location
7 'js/jquery-2.0.0.min'
8 ]
9 }
10});
11
12//Later
13require(['jquery'], function ($) {
14});

As always, plan for the worst and hope for the best!

Compatibility Cheatsheet for Web Developers

This is a great resource for checking compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers.

Bookmark it!

http://caniuse.com/

FOR Loops Overwriting Ajax Responses (and how to fix)

I encountered a problem today with a FOR loop inside of a JavaScript function. This for loop makes Ajax requests (using jQuery 1.8.1) and populates a specific div, based on where we are in the loop, with the results of the call. However, we noticed that it stopped updating all of the divs and appeared to populate the last one multiple times.

[More]

PEMDAS

The title above refers to order of operations in Math. I remember it by "Please Excuse My Dear Aunt Sally" but your teachers may have taught you something different. For those of you who didn't like math it means handle Parentheses first, then Exponents, then Multiple or Divide going left to right, then Add or Subtract going left to right.

This blog is actually about what you can and can't nest in code. I was always a little bit of a math nerd so I thought the blog is about order so I can do an intro about order of operations, I know it's a stretch, but it got your attention didn't it? Anyway, I recently had a fight with a cfform in particular a cfinput of type datefield. I could not get the JS of the calendar to render. I had a table to aid with the formatting of the form variables.

[More]

Developing Chrome Extensions - What you should know

Recently, I've delved into the world of Chrome extensions, partially because I'm interested in learning the technology, but more because the add-ons I wanted just didn't exist yet. If you're interested in getting started but want to know what you'll need to get moving I'd recommend the following resources:

https://github.com/EdGuiness/date-picker/wiki/What-I-learned-from-writing-my-first-Chrome-extension -This is a general explanations of some little things to look out for while developing and states what you'll need to get started.

http://developer.chrome.com/extensions/getstarted.html -The Chrome extensions development page for getting started. A required resource for specific questions including code samples.

http://tutorialzine.com/2010/06/making-first-chrome-extension/ -Finally, a basic tutorial covering the steps to creating an extension.

With these resources you should be well on your way to building your first Chrome extension as well. I was surprised how much of it was simply Javascript, and if your comfortable with that, you'll have no problem learning extensions. Have any other good resources? How about a browser extension that you shouldn't live without? Share it in the comments!

-Jonny

Keyboard Shortcuts in Chrome Developer Tools

Working more with jQuery has made browser development tools mandatory for the Ravenglass team. This Google+ entry has some of the most commonly-used ones keyboard shortcuts for Chrome's developer environment:

https://plus.google.com/u/0/115133653231679625609/posts/e4W2kdrFJY9

Binding delegated events with jQuery's .on()

Isaac and I got into a discussion today stemming from an interesting blog post from Raymond Camden. Raymond was discussing how he had run into issues binding events in jQuery mobile on the 'pageshow' event. While the solution he presents is adequate, there is another neat way to do this.

.on() is a very powerful function that combines the functionality of three recently deprecated methods: .bind(), .live(), and .delegate()

Below is a tutorial on how to bind delegated events.

Let's take a basic jQuery mobile snippet with 3 buttons.

view plain print about
1<div data-role="page" id="demopage">
2
3 <div data-role="header">
4 <a data-rel="back" data-icon="home">Home</a>
5 <h1>.on() Demo Page</h1>
6 </div>
7
8 <div data-role="content">
9 <button class="testButton" data-bacon="I accidently ate all the bacon!">Test 1</button>
10 <button class="testButton" data-bacon="I like bacon!">Test 2</button>
11 <button class="testButton" data-bacon="That was my bacon!">Test 3</button>
12 <div id="status"></div>
13 </div>
14
15 <div data-role="footer">
16 <h4>Footer content</h4>
17 </div>
18
19</div>

Now let's bind a click event to the buttons so they display the value of the data-bacon attribute in the status div.

view plain print about
1$(document).on('click', 'button', function()
2 {
3 $("#status").text($(this).attr("data-bacon"))
4 });

So what happens here?

We call .on() passing 'click' as the event type, 'button' as the selector to apply the event to, and a function to run when the event fires.

Now, when you click a button on the body, #status displays the particular data-bacon attribute of the clicked button.

You can view the complete sample here: http://jsfiddle.net/Bw9Kh/

Reference: http://www.raymondcamden.com/index.cfm/2012/4/1/Reminder--Use-the-proper-jQuery-Mobile-event-handler http://api.jquery.com/on/

Help Wanted: Web Application Developer

Ravenglass Technologies, Inc., located near Syracuse, New York (USA) is seeking a full-time Web Application Developer.

Degree in Computer Science or related field required. Must have demonstrable experience with HTML, AJAX, CSS, and SQL. Web application development experience in at least one of the following: ColdFusion, JSP, ASP.NET, or PHP. Mobile application development experience is a strong plus.

Professionalism and strong communications skills are a must. Salary plus full benefits, flexible commuting arrangements considered. Apply with resume and cover letter to jobs@ravenglass.com.

Using CFHTMLHEAD

Last week one of my team members gave a presentation to the rest of us on Coldbox. We are using this framework for a project and we were discussing the basics of convention and how to work with the different layers - which brought up the question, where exactly is the optimal place to put the Javascript in this?.

I used this opportunity to bring up the CFHTMLHEAD tag, which allows you to place code into the head tag from anywhere on the page. This would allow us to keep Javascript from loading on unnecessary pages and still keep everything componentized. I also thought this would be a good opportunity to discuss basic CFHTMLHEAD usage.

[More]

Debugging Javascript using Firebug in Browsers other than Firefox

Here is a neat Javascript tool that I recently discovered: Firebug Lite – a Javascript library that integrates Firebug into the DOM of any browser (like Internet Explorer, Chrome and Safari).

[More]

More Entries