Brian Peacock

on3.js: A JavaScript Controller Suite

February 2014

on3.js is a set of interaction-level JavaScript controllers for common user interactions:

With the increasing amount of inconsistency between web browsing interfaces, standard event bindings (DOM level) are not sufficient for creating consistent user experiences across devices. Sure there are libraries like jQuery that abstract DOM APIs to provide API consistency, but their APIs correspond directly to DOM events (i.e. click, mousedown, mouseup, touchstart, touchend, etc.).

on3.js is designed to provide an interaction-level API for common browser IO. This allows developers to bind directly to specific user actions in a simple, intuitive way:

onClick({
    "#element1": function(e) {

    },
    ".elements": function(e) {

    }
});
onKey({
    'ctrl-a': function(e) {

    },
    'enter': function(e) {

    }
});
onRoute(/^post\/([^\/]+)\//, function(url, components*) {
    //Routes like /post/cars/ match & the first component argument will be 'cars'
});

By using interaction-level APIs, developers ensure that user interactions are consistent throughout the application and across platforms. For instance, onClick event binds the standard click handler, but on devices with touch it also uses touch events to prevent delays associated with mobile browsers.

Rather than lumping all of this functionality into one library, I’ve decided to keep on3.js very modular. This allows developers to mix and match different control modules as they please and also ensures that the scope of each of the controllers stays very tight. All of the modules are CommonJS & AMD compliant. In addition, on3.js is designed to be used with any other model and view libraries (though I’m working on a hierarchical view library called subview.js).

In the future, I plan to extend the suite to include additional common interactions:

There was some question of whether onDrag, onSwipe & onPinch should be part of the onClick module since it primarily handles mouse interactions. However, I think that I’m going to stick to the convention of one module per interaction. This keeps the modules extremely lightweight ~1kb each and ensures that they’re scope never creeps.

All the modules depend on jQuery, Zepto or something similar and are available via github and npm: