Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dolox/fallback

JavaScript library for dynamically loading CSS and JS files. Also provides the ability to load multiple files from a CDN with multiple fallback options and shimming!
https://github.com/dolox/fallback

Last synced: 29 days ago
JSON representation

JavaScript library for dynamically loading CSS and JS files. Also provides the ability to load multiple files from a CDN with multiple fallback options and shimming!

Awesome Lists containing this project

README

        

Fallback JS
Fallback JS
========

**WORKS IN LEGACY AND MODERN BROWSERS!**

*Tested and working in Chrome, Firefox, Safari and IE 6 - 10!*

**Fallback JS** is a tiny library that allows you to load both your JavaScript and CSS libraries after your page has already loaded. The library also allows you to specify **"failovers"** or **"fallbacks"** for each of your libraries, this way in case one of those external libraries you're using happens to fail, you won't be leaving your users with a dysfunctional website. Just because someone else's website breaks, it doesn't mean that yours should!

* Official Homepage
* GitHub Repository

# Downloads

* Production (v1.1.9) *Compressed 3.58 KB*
* Development (v1.1.9) *Uncompressed 12.47 KB*

**SEE WORKING DEMOS WITH SOURCE CODE AT http://plnkr.co/tags/fallbackjs**

# Introduction
## Getting Started
### Quick and easy demonstration.

To let you dive right in, we're going to provide you with a sample of code below. If you want to learn more you can read through the rest of this page for all of the technical details. This quick and easy demonstration should be enough for you to understand how to use the library and implement it in your code.

```html
// Include the Fallback JS library.

// Script block to execute Fallback JS

// Here we actually invoke Fallback JS to retrieve the following libraries for the page.
fallback.load({
// Include your stylesheets, this can be an array of stylesheets or a string!
page_css: 'index.css',
global_css: ['public.css', 'members.css'],

// JavaScript library. THE KEY MUST BE THE LIBRARIES WINDOW VARIABLE!
JSON: '//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.min.js',

// Here goes a failover example. The first will fail, therefore Fallback JS will load the second!
jQuery: [
'//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.FAIL_ON_PURPOSE.min.js',
'//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js',
'//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js'
],

'jQuery.ui': [
'//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'//js/loader.js?i=vendor/jquery-ui.min.js'
]
}, {
// Shim jQuery UI so that it will only load after jQuery has completed!
shim: {
'jQuery.ui': ['jQuery']
},

callback: function(success, failed) {
// success - object containing all libraries that loaded successfully.
// failed - object containing all libraries that failed to load.

// All of my libraries have finished loading!

// Execute my code that applies to all of my libraries here!
}
});

fallback.ready(['jQuery'], function() {
// jQuery Finished Loading

// Execute my jQuery dependent code here!
});

fallback.ready(['jQuery', 'JSON'], function() {
// jQuery and JSON Finished Loading

// Execute my jQuery + JSON dependent code here!
});

fallback.ready(function() {
// All of my libraries have finished loading!

// Execute my code that applies to all of my libraries here!
});

```

## Why Fallback JS?
### Unlimited failovers, and size that does matter!

The sole purpose of Fallback JS is to make it extremely easy for you as a developer to load as many external JavaScript and/or CSS libraries that you want with the ability to have as many failovers as you want without you having to write custom code or run through extra loops to achieve this goal.

Along with this premise, the filesize the extremely small, the main purpose of loading JavaScript files after your website has already loaded is to decrease your page load time (see below). You want your users to load as little as possible so you website can load as fast as it possibly can. Think outside the box. All of your users won't always be on high speed internet connections, and we all know how slow surfing the web can sometimes be on mobile devices.

## Improving Page Load Times
### Speed is important!

An extremely common way of coding websites throughout the internet for years has been to put your javascript and stylesheet references in the <head> of your HTML. By doing this you're forcing the browser to wait for those libraries to load before it actually displays the page to the user.

Alternatively there are a few ways around this. First you can put your references at the bottom of the page before closing the tag. This alone will boost the speed of your page loads.
To boost the page load speed even further, you simply don't reference those libraries at all in the HTML and instead you can let JavaScript load those libraries for you after the page load. This is exactly what Fallback JS does for you!

## Failovers For Your Libraries
### So that your website doesn't break!

So you found all of these great CDNs that host popular libraries such as jQuery, Dojo and Underscore.js just to name a few. You don't want to waste bandwidth on libraries that you can include for free on your website, that's understandable. But what happens when one of those CDNs you're using goes down for maintenance? Or mysteriously stops working out of the blue? Your website breaks! That's what happens!

Don't get stuck leaving your users with a dysfunctional website because of someone else's mistakes. You should always have multiple failovers for any external library you decide to bundle for your website.

Fallback JS makes this extremely easy for you to integrate into your website. Not only can you have as many failovers as you want for each of your libraries, but you can also implement shimming as well. Shimming for example is the ability to load certain libraries if other libraries have finished loading. Case by example jQuery UI depends on jQuery. You simply cannot load jQuery UI before jQuery has finished loading. In this instance you would shim jQuery UI to load after jQuery has completed.

## What is shimming?

```
shim
verb (used with object)

"to fill out or bring to a level by inserting a shim or shims."

"to modify a load, clearance, or magnetic field by the use of shims"

Source: http://dictionary.reference.com/browse/shim/
```

When we refer to **shims** or **shimming** we are referring to modifying the load context of your libraries that you specify. For instance there will be cases where you cannot load certain libraries until other libraries have first loaded. One of the main cases by example that is pointed out is jQuery UI. jQuery UI cannot be loaded until jQuery has loaded, therefore jQuery must load first, and we must **shim** jQuery UI to load only after jQuery has finished.

# API
## ready
### fallback.ready([libraries], callback)

`[libraries]` **array** *optional*

`callback` **function** *optional*

Executes your function provided to the `callback` as soon as your libraries have finished loading. The `[libraries]` array parameter is **optional**, if an array is not passed in the code will assume that the first parameter passed is the `callback` and in turn will only execute once all of your libraries have finished loading. If you provide the `[libraries]` array, the `callback` will only trigger your callback when those libraries provided have finished loading. You may define the `ready` function multiple times throughout your code.

```javascript
fallback.ready(function() {
// All of my libraries are loaded. Execute my code here!
});

fallback.ready(['jQuery', 'jQuery.ui'], function() {
// jQuery and jQuery UI are finished. Spin up my animation code here!
});
```

## load
### fallback.load({libraries}, {options})

`{libraries}` **object** *optional*

Expects to be an *object* containing a key value pair where the **key** is the library's window variable, and the value is the **url** to fetch the library from. The **keys** must be the window variable name of the library you're loading if it's a JavaScript library. This is only relevant for JavaScript libraries and **not StyleSheets**, for StyleSheets you can name them however you please. For example jQuery's key would be **jQuery** since **window.jQuery** exists after jQuery has finished loading. This is required to provide support for legacy browsers.

The values of your keys can be either a **string**, an **array** or an **object**. If you happen to pass an **array** as the **value** Fallback JS will iterate through each of items in the **order provided** until one of them has loaded successfully. This provides the *failover functionality* so that if your first request *fails*, it will try the next item in the array to load for the library in question. If you pass an **object** as the **value** then the object must have a `urls` property representing the failover URLs. Passing an **object** gives you the added benefit of being able to specify `integrity` and `crossorigin` properties to ensure [subresource integrity](https://www.w3.org/TR/SRI/) when loading from a CDN. A subresource integrity check failure is treated the same way as any other failure to load the library, meaning Fallback JS will attempt to load the library using the next URL in the array. This protects you from compromised CDNs where the contents of the library have been altered for potentially malicious reasons.

```javascript
{
// The key for stylesheets **doesn't matter**, name them however you like.
css: 'index.css',

// You have the option to pass a string as your value
JSON: '//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.min.js',

// You have the option to pass an array as your value
jQuery: [
'//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.**FAILONPURPOSE** .min.js',
'//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js',
'//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js',
'//localhost/js/jquery.min.js'
],

// You have the option to pass an object as your value so that you can specify additional properties such as
// `integrity` and `crossorigin` values to ensure [subresource integrity](https://www.w3.org/TR/SRI/) when loading files from a CDN.
// Note that the **key** correlates to jQuery UI's window variable.
'jQuery.ui': {
urls: [
'//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'//js/loader.js?i=vendor/jquery-ui.min.js',
'//localhost/js/jquery-ui.min.js'
],
integrity: 'sha384-O4jIYc8wiFPNf25AwmeP5qRInqzSLJuM9t+u843Al1M/OO67y4JsVjlJGaUl4N7J',
crossorigin: 'anonymous'
}
}
```

`options` **object** *optional*

Expects to be an *object* containing a key value pair where the **key** is either `shim` or `callback`.

`>` `shim` **object** *optional*

Expects its value to be an **object** containing a key value pair where the **key** is the library you want to **shim**, and the **value** is an **array** of libraries you want to finish loading first before attempting to actually load the library specified as the **key**.

`>` `callback` **function** *optional*

Expects to be a function and will accept 2 parameters `success` and `failed` which will be returned as objects. The first parameter will be `success` which is an **object** of all the libraries that were successfully loaded. The second parameter will be `failed` which is an **object** of all the libraries that failed to load.

```javascript
{
// Shimming example. We only want to load jQuery UI after jQuery has loaded!
// Otherwise if jQuery UI loads before jQuery we will get JavaScript errors.
shim: {
'jQuery.ui': ['jQuery']
},

// Here you have the ability to place callback within the object.
// This is the equivalent of calling fallback.ready()
callback: function(success, failed) {
// Inline Callback
}
}
```

# About
## License
### The MIT License (MIT)

Copyright (c) 2013 Dolox Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

## Support
### We use GitHub!
Any questions, suggestions or bugs should all be submitted to the issues section of the project's GitHub repository.