UsefulJS is a JavaScript library whose purpose is twofold:
Every JavaScript programmer has probably written a function to pad strings to a fixed width, a function to determine whether this year is a leap year, functions to manipulate class names of document elements, functions to do something better with Date objects than call toString on them, functions to work around the inadequacies of Number.toFixed and so on.
The major browser vendors have recognized that JavaScript programmers routinely and repeatedly solve the same problems, so we now have support for things like:
However, if we use them, our code is liable to break. Therefore, we're stuck with stuff like this:
var arrayIndexOf = function(arr, item) { for (var i = 0; i < arr.length; i++) { if (arr[i] === item) { return i; } } return -1; };
Or, if we're aware that indexOf
is now an Array.prototype
method in many browsers, we might write:
var arrayIndexOf = function(arr, item) { if ("indexOf" in arr) { return arr.indexOf(item); } for (var i = 0; i < arr.length; i++) { if (arr[i] === item) { return i; } } return -1; };
Worse, we may have filled in the perceived inadequacy in Array by blindly patching in the missing functionality with something that doesn't quite work according to spec:
Array.prototype.indexOf = function(item) { for (var i = 0; i < this.length; i++) { if (this[i] === item) { return i; } } return -1; };
The basic problem in all cases is the same: we can't rely on the JavaScript programming environment that our code is running in.
With UsefulJS that isn't true. We can optimistically write:
// Basic stuff [1, 2, 3, 4].indexOf(2); "Three score years".startsWith("Three"); var startTime = Date.now(); document.body.classList.add("myClass"); // Bleeding-edge var fmtObj = new Intl.DateTimeFormat("zh-TW-u-nu-fullwide-ca-roc"), dateStr = fmtObj.format(new Date()), // "民國102年11月13日" uLiterals = Array.from(dateStr, function(c, idx) { return '\\u' + c.charCodeAt(idx).toString(16).padLeft(4, '0'); });
and expect everything to just work.
Besides providing missing JavaScript functionality, UsefulJS provides a wide range of additional functionality, including:
In a nutshell, this is what UsefulJS does:
Makes the runtime environment sane then makes it better
If you downloaded the dev bundle, you'll need a version of make
. Windows users can
get one by installing Cygwin. Start off by unpacking the dev bundle to your
working directory then edit minjs.mk
which defines the function
for minifying JavaScript files. I use Google Closure Compiler. Even if you use this, you probably
don't have it installed in the same place as me. If you don't have any minification
tool, you can change the definition to this:
define minjs cp $1 $2 endef
With that done, you just need to type:
$ make all
For a clean build, type:
$ make clean all
Include UsefulJS somwhere in your list of JavaScript includes:
... <script src="UsefulJS-min-latest.js"></script> ...
If you want the extensions, use this:
... <script src="UsefulJS-min-full-latest.js"></script> ...
UsefulJS has no dependencies on any other libraries so load order is irrelevant.
If you are using the development libraries, load order is important: you need to load the core module first. All other modules are independent and can be loaded in any order:
... <script src="src/core.js"></script> <script src="src/string.js"></script> <script src="src/locale_en.js"></script> <script src="etc."></script> ...
Any required extensions should be loaded after the core modules
Having loaded the library, you have a number of more-or-less useful
functions under a number of different namespaces. To realize the full
potential, call the fix
method:
window.onload = function() { var fixed = UsefulJS.fix(); ... };
Or, if you're loading the library in the head:
<script type="text/javascript"> var g_fixed = UsefulJS.fix(); </script>
fix
method takes an optional opts
paramter that controls which fixes are applied. Some
fixes have to be explicitly disabled while others have to be
explicitly enabled. See the core module
documentation and documentation for individual modules for
more information.
The core provides basic properties and functions used by the rest of the library, and provides the framework for internationalization and localization.
The Array module adds missing methods to the Array class where they are not implemented natively.
The ClassList module provides a DOMTokenList interface to an element's className that works in all browsers. Where possible it makes classList a property on elements in legacy browsers that do not natively support it.
The Date module provides powerful, locale-aware date formatting and parsing functionality using strftime format strings. It provides a complete implementation of the Intl.DateTimeFormat API.
The Event module provides a simple, cross-browser interface to DOM events. It also provides functionality for dispatching and catching custom events.
Basic locale support is hosted in the UsefulJS core. A number of additional modules provide support for date and number formatting targeting a large number of languages and locales.
The Math module provides useful functionality missing from the standard Math library: logarithms to any base, conversion between radians and degrees, minutes and seconds and floating point error correction.
The Number module provides powerful, locale-aware number formatting and parsing functionality, including currency, percentage and scientific notation. It provides a complete implementation of the Intl.NumberFormat API.
The Query module provides support for parsing and building query strings. It can parse location.search and make the parsed values available to your web application.
The Storage module provides a DOMStorage interface to document.cookie. It also provides localStorage and sessionStorage implementations for browsers that lack them.
The String module provides a variety of methods for formatting, escaping and converting strings along with implementations of String methods that may not have been implemented natively.
Extensions are not part of the core library. They offer specialist functionality that will only be useful in certain applications. Be aware that they are not independent modules; for example, the UsefulJS.DnD extension needs UsefulJS.Event.
The Browser extension determines browser and engine versions from the navigator.userAgent string. It can make the engine version available through classes added to the <html> element, allowing you to fix browser display issues through CSS.
The Currency extension provides a simple conversion API.
The DnD extension provides a simple framework to support dragging and dropping elements.
The Skin extension provides a simple interface to using alternate stylesheets for skinning applications.
UsefulJS has been tested on the following browsers:
Browser | Versions |
---|---|
Mozilla Firefox | 24+ |
Google Chrome | 25, 30+ |
Internet Explorer | 7, 8, 9, 10 |
Safari | 6.0+ |
Mobile Safari | 9.0+ |
Opera | 11.0, 17.0+ |
Konqueror | 4.6 |
Maxthon | 4.1 |
UsefulJS is released under the Apache 2.0 License and is copyright 2013-2015 Christopher Williams.
The licence terms basically boil down to: use, modify and redistribute freely, but acknowledge use and respect my copyright. Oh, and let me know if you find it useful - contact details below.
This site uses Twitter Bootstrap
Microsoft's excellent style guides were used as the primary sources for localization information.
The JQuery Globalize project was used as a secondary source.
Contact me with any questions, suggestions or bugs
For bug reports, please start the subject with "BUG". For localization issues, please start the subject with "L10N"