A lightweight, simple DOM utility made to run on a tight budget.
Shoestring is part of the Southstreet workflow at Filament Group.
You can find more details in the API documentation.
Shoestring is a lightweight, modular DOM framework intended for developers who need their code to download and run as fast as possible. It is intended to be "just enough" of a tool to efficently write maintainable cross-browser JavaScript. The API is modeled after jQuery but we intentionally implement a tiny subset of the API to cover only the methods we commonly need in our projects. Each feature is built as an optional extension to a minimal core so each can be removed from the production build (dependencies between extensions are rare). The selector engine delegates to modern browsers' native document.querySelectorAll
(IE8) and addEventListener
(IE9), which means it requires browsers that support those features. For projects that require deeper compatibility or a richer set of features, it is simple to swap in jQuery instead. As a rule, anything that works with Shoestring should work with jQuery, but not the converse.
Our goal is to strike a good balance of code weight, runtime speed, browser support, and developer convenience.
Shoestring's API is inspired by jQuery.
Technically, shoestring.js is a very small, extendable core function. That core function doesn't come with much more than a means of finding and/or generating HTML elements, a DOM-ready handler, and a few essential element-traversal methods like each
, find
, children
. Using its shoestring.fn
API, its core is easy to extend further, and many extensions are available for you to include in your build – the default build includes all extensions, but it's still very small (~3kb compressed).
If you are concerned about compatibility issues/pitfalls consider using the development build releases (-dev
in the releases). We've endeavored to throw exceptions where a particular invocation pattern or feature isn't supported as a means to document the disparity. We recommend that you use the development version in development and the regular non--dev
version in production.
There are three sets of extensions to the Shoestring core: DOM manipulation, events, and ajax.
If you've used jQuery, the structure and behavior of the DOM manipulation methods will be immediately familiar:
shoestring( ".foo" ).addClass( "bar" ).attr( "data-baz", "bak" );
That is, construct a sequence of elements from the DOM and invoke each method on all the elements of the sequence in turn. You can find a full list of the supported DOM methods and their arguments in the API docs under the dom/*
subdirectory.
Shoestring supports most of the jQuery events API including: custom events that bubble, event namespaces, a normalized event object, event arguments, DOM Ready, a .one
method, comprehensive .unbind
, etc. The major difference here is that Shoestring does not support the event delegation helpers built into jQuery, like .delegate
or .on
with a selector argument.
shoestring( ".foo" ).bind( "click", function( event ) { ... });
Or with a custom event triggered on a child element:
shoestring( ".foo" ).bind( "bar", function( event, arg ) {
...
if(arg == 1) { ... }
...
});
// ...
shoestring( ".foo" ).children().first().trigger( "bar", 1 );
You can find a full list of the supported event methods and their arguments in the API docs under the events/*
subdirectory.
Shoestring supports a full shoestring.ajax
method as well as some shorthand helpers like shoestring.get
and shoestring.post
.
shoestring.ajax( "/foo", {
success: function(){ ... },
method: "GET",
...
});
Which could also be accomplished using shoestring.get
shoestring.get( "/foo", function(){ ... });
You can find a full list of the supported ajax methods and their arguments in the API docs under the ajax/*
subdirectory.
Extending Shoestring is done in nearly the same fashion as jQuery. There is an object on which you can define properties using functions and those functions will have access to the Shoestring DOM element sequence during invocation using this
. As an example the remove
method:
/**
* Remove the current set of elements from the DOM.
*
* @return shoestring
* @this shoestring
*/
shoestring.fn.remove = function(){
return this.each(function(){
if( this.parentNode ) {
this.parentNode.removeChild( this );
}
});
};
It uses the each
method to handle the DOM elements in the current sequence in turn.
NOTE these definitions must be made before a Shoestring object that depends on them is constructed. This is in contrast with jQuery where each object has access to new methods through the prototype chain.
Each extension to Shoestring included in the repository is defined as an AMD module, but only for build purposes. We don't support, or plan to support, loading the library as modules in the browser.
//>>excludeStart("exclude", pragmas.exclude);
define([ "shoestring", "dom/remove" ], function(){
//>>excludeEnd("exclude");
shoestring.fn.foo = function(){ ... };
//>>excludeStart("exclude", pragmas.exclude);
});
//>>excludeEnd("exclude");
Note that the AMD wrapper is removed during the process of the build and that the dependencies are defined from the src
subdirectory. More on custom builds below.
Browsing the modules in Shoestring you'll notice that very few have explicit dependencies in their module definitions. This is by design. We are interested in being able to select the minimum number of methods necessary for a given project to reduce load and parse times.
Shoestring releases include two different builds, one for development and one for production. The development build is larger. It is intended to help with jQuery compatibility issues and includes other development utilities like the method tracker. The production build is meant to be shipped in production and does not include the extra dev-time helpers.
This repository supports custom builds through creating a meta-module in the build/custom/
directory and running the default Grunt task. To get started building a custom production build, do the following:
- make sure the project dependencies are installed with
npm install
- copy
build/development.js
tobuild/custom/foo.js
- run
grunt
ornode node_modules/.bin/grunt
- use
dist/foo.js
Included in the development build is a method tracker. It works by proxying all calls to shoestring.fn
methods through a corresponding method that records the invocation in local storage. NOTE this does not include methods defined on shoestring
. Then the methods being used across pages by your application can be inspected.
JSON.parse( window.localStorage.getItem(shoestring.trackedMethodsKey) );
If the method tracker is included during a significant portion of development this list can be used to remove unused functions from your Shoestring build with a custom meta-module.
Please see the contribution guidelines.