tinyJS - a tiny JS toolkit

tinyJS is a JS Toolkit reduced to the essentials of common perrenial tasks. It is smaller than 5kb in a debuggable minified gzip'ped version, so it can be deployed in environments where a small size and memory footprint is of importance.

Download

tiny.js [20788b] - tiny-min.js.gz [3816b]

Cheat Sheet

For the busy developer, a Cheat Sheet is always useful.

Compatibility

The following Browsers should be supported out of the box:

It is possible to put the support of additional older Browsers into a Plugin. Newer Browsers should usually be supported out of the Box. Later Versions are planned to support Mobile Browsers explicitly, since the mobile deployment of tiny.js may be of increased interest.

IE's Quirks Mode is consciously not supported by tiny.js. For once, the abandonment of support saves space, secondly the usage of Quirks Mode is rather anachronistic - a failure of the toolkit is too mild a punishment for such a misbehavior.

Alphabetical List of Methods

DOM

t - DOM Selection

tinyJS supports out of the box CSS-Selectors compliant to CSS2.1-Standard.

nach oben

  1. es war einmal
  2. und ist nicht mehr
  3. ein ausgestopfter
  4. Teddybär

Normaler Text. Ein Link nach oben

Select DOM Nodes:

t([selector:String], [base:Node, optional], [methodless:Boolean(true), optional])

returns Object with Node selection and very interesting methods (unless "methodless" is true, in this case, just an Array of nodes is returned).

t('#testfeld li', document)

t.cf - CSS-Filters

This instance holds all the CSS Filters, which can easily be extended with further Pseudoattributes. The available CSS-Filters are mostly CSS2.1 compatible, as well with few reductions as with non-standard extensions. Every filter consists of a name and a function which takes at least the selection array as argument, but can take an optional value (in brackets within the selector) as a second argument.

t.cf[name]([node, node2, ...], value[, value2])

Basic Types

body (Tagname)

Filters nodes after their tagname (e.g. 'body'):

document.body === t.cf['']([document.body], 'body')[0] t.cf['']([document.body], 'li').length===0
.class

Filters nodes after one of their Classnames. If getElementsByClassName is available, it will be used to speed things up:

t.cf['.']([document.getElementById('testfeld')], 'test').length === 1 t.cf['.']([document.body], 'test').length === 0
#id

Filters nodes after their unique ID:

t.cf['#']([document.getElementById('testfeld')], 'testfeld').length === 1 t.cf['#']([document.getElementById('testfeld')], 'test').length === 0

Traversing

* (Everything)

Searches recursively all Child nodes with getElementByTagName('*'):

t.cf['*']([document.getElementById('testfeld')]).length === 25 t.cf['*']([document.getElementById('tcfall')]).length === 0
> (Direct Childs)

Searches all direct Child nodes:

t.cf['>']([document.getElementById('testfeld')]).length === 3 t.cf['>']([document.getElementById('tcfall')]).length === 0
~ (Siblings)

Returns all Siblings on the same level after the element:

t.cf['~'](document.getElementById('testfeld').getElementsByTagName('h1')).length === 2 t.cf['~'](document.getElementById('top').getElementsByTagName('span')).length === 0
+ (Next)

Returns the next Element on the same level, if available:

t.cf['+'](document.getElementById('testfeld').getElementsByTagName('h1')).length === 1 t.cf['+']([document.getElementById('copyright')]).length === 0
< (Parent)

This filter does not conform to the CSS Standards, yet it is extremely useful. It returns the parent node:

t.cf['<'](document.getElementById('testfeld').getElementsByTagName('h1'))[0] === document.getElementById('testfeld') t.cf['<']([document]).length === 0
<< (Parents)

This filter is nonstandard, too, yet it returns all parents including document:

t.cf['<<']([document.getElementById('testfeld')]).length === 3 t.cf['<<']([document]).length === 0

Attributes

[key], [key=value] (Present/Equals)

This selection filter filters the existence or value of an attribute. For * [name=...] there is a faster shortcut using getElementsByName.

t.cf['='](document.getElementsByTagName('*'), 'name').length === 8 t.cf['='](document.getElementsByTagName('*'), 'title', 'wurl') === 0
[key!=value] (Not Equals)

Returns a collection of nodes that have the attribute, but with another value:

t.cf['!='](document.getElementById('testfeld').getElementsByTagName('*'), 'name', 'hidden1').length === 7 t.cf['!=']([document.getElementById('testfeld')], 'name', 'xyz').length === 0
[key^=value] (Starts with)

Leaves only nodes which have their attribute beginning with the given value:

t.cf['^='](document.getElementById('testfeld').getElementsByTagName('input'), 'name', 'radio').length === 2 t.cf['^='](document.getElementById('testfeld').getElementsByTagName('input'), 'value', 'xyz').length === 0
[key$=value] (Ends with)

Returns an array of nodes which attributes end with the given value:

t.cf['$='](document.getElementById('testfeld').getElementsByTagName('input'), 'value', 't').length === 2 t.cf['^='](document.getElementById('testfeld').getElementsByTagName('input'), 'value', 'xyz').length === 0
[key*=value] (Partly Equal)

Only nodes that have the given value anywhere within their attribute are returned:

t.cf['*='](document.getElementById('testfeld').getElementsByTagName('input'), 'name', 'i').length === 4 t.cf['*='](document.getElementById('testfeld').getElementsByTagName('input'), 'value', 'xyz123').length === 0
[key~=value] (Seperate Part Equals)

Returns only nodes that have the value as a seperate part within their attribute:

t.cf['~='](document.getElementsByTagName('h5'), 'title', 'nicht').length === 2 t.cf['~='](document.getElementById('testfeld').getElementsByTagName('input'), 'value', 'hidden').length === 0
[key|=value] (Subpart before "-" Equals)

Leaves only those nodes, which attribute contains the value before its end or a minus sign:

t.cf['|='](document.getElementsByTagName('*'), 'lang', 'de').length === 1 t.cf['|='](document.getElementById('testfeld').getElementsByTagName('input'), 'value', 'xyz123').length === 0

Pseudo Attributes

:odd

Reduces the Selection to the nodes with odd index (1, 3, 5, ...):

t.cf['odd'](document.getElementById('testfeld').getElementsByTagName('li')).length === 4 t.cf['odd'](document.getElementById('testfeld').getElementsByTagName('body')).length === 0
:even

Leaves only nodes with even index (2, 4, 6, ...) in the Selection:

t.cf['even'](document.getElementById('testfeld').getElementsByTagName('li')).length === 3 t.cf['even'](document.getElementById('testfeld').getElementsByTagName('body')).length === 0
:empty

Returns only empty nodes:

t.cf['empty'](document.getElementById('testfeld').getElementsByTagName('*')).length === 8 t.cf['empty'](document.getElementById('testfeld').getElementsByTagName('ul')).length === 0
:first-child

Checks whether each node is the first child of its parent node:

t.cf['first-child'](document.getElementById('testfeld').getElementsByTagName('*')).length === 9 t.cf['first-child'](document.getElementById('testfeld').getElementsByTagName('ul')).length === 0
:last-child

Filters all nodes to be the last child of their parent nodes:

t.cf['last-child'](document.getElementById('testfeld').getElementsByTagName('*')).length === 9 t.cf['last-child'](document.getElementById('testfeld').getElementsByTagName('ul')).length === 0
:only-child

Returns all nodes which are the only child of their parent nodes:

t.cf['only-child'](document.getElementById('testfeld').getElementsByTagName('*')).length === 9 t.cf['only-child'](document.getElementById('testfeld').getElementsByTagName('ul')).length === 0
:nth-child(index)

Selects those nodes which are the nth child node of their parent nodes:

t.cf['nth-child'](document.getElementById('testfeld').getElementsByTagName('li'), "3").length === 1 t.cf['nth-child'](document.getElementById('testfeld').getElementsByTagName('li'), "4").length === 0
:not(selector)

Removes such nodes from the selection on which the selector matches:

t.cf['not'](document.getElementById('testfeld').getElementsByTagName('li'), ".first").length === 5 t.cf['not']([document.getElementById('testfeld')], "div").length === 0
:has(selector)

Returns all nodes to be parents of the nodes selected with selector:

t.cf['has'](document.getElementById('testfeld').getElementsByTagName('*'), "li").length === 3 t.cf['has']([document.getElementById('testfeld')], "table").length === 0
:contains(text)

Selects all nodes whose text content contains the text:

t.cf['contains'](document.getElementById('testfeld').getElementsByTagName('*'), 'oben').length === 5 t.cf['contains']([document.getElementById('testfeld')], 'blargl').length === 0
:lang(language)

Checks whether the node matches the language definition:

t.cf['lang']([document.getElementById('testfeld')], 'de').length === 1 t.cf['lang']([document.getElementById('testfeld')], 'jp').length === 0

Extension of Selector Engine

The Object t.cf can be easily extended by further selectors. Additional pseudo attributes can be identified by their name without the preceding ":". Selector-functions have an array of nodes as their first argument and optional another argument, which would be written in brackets in the Selection.

t._ - Selection-Methods

Selected DOM-Nodes will be extended by the following methods:

t._.i - Iterate

Executes a function for each node within the selection; its first parameter will be the selection index, the second one the node and this will be the selection.

t('#testfeld, #top').i(function(i, n) { ... });

t._.f - Filter

Filters the selected nodes with a function, that gets the same parameters as iteration, yet if it returns undefined, the node will be ommitted from the selection.

t('#testfeld li').f(function(i, n) { return i===3||i===5?n:undef; })

t._.g - Get

Versatile method to get more from a selection. If an index (integer) is given, it will return the node in the selection, if a node is given, it will return its index and if a string is given, it will be used as a new selector starting from the current selection.

t('#testfeld li').g(1), t('h1').g(t('#plugins')[0]), t('body').g('#testfeld')

t._.e - Events

Sets events on the selected nodes. See t.e, the first parameter must be ommitted, since the selection is used anyway.

t._.a - Attributes

Gets and sets attributes of the nodes. First parameter is attribute name or object, second parameter value. If no value is given, the attribute of the first object is returned, if a value is given, it is set for all selected nodes, same goes for an object containing multiple attributes. Normalisation is provided by the Normalisation-Filters.

t._.c - CSS Attributes

Gets and sets style-Attributes of the selected nodes. Everything else is just like attributes.

t('#top').c('backgroundColor')==='#000000'

t._.h - HTML

Gets or writes HTML content.

t('#testfeld h1 a').h() === 'nach oben' --value test: failed

t._.v - Values

Reads or writes the value of form fields. First parameter is a parameterization function (e.g. t.p), which then will parameterize all values of selected nodes, or a value to be set on all selected nodes. If .v() is called without parameters, it will return the value of the first selected node.

t('#testfeld input[type=hidden]').v() == 'versteckt'

t._.r - Remove Element

Removes all selected nodes from their parents.

t(node).r()

t._.nf - Normalisation filters

The normalisation filters are in the object t._.nf to be easily extendable. The necessity of normalisation will be solely determined by feature detection.

t.e - Events

Simple Event Engine:

t.e([node(s):DOM Node|Array], [eventname:String, optional], [callback:Function, this=node, arguments=[event object], optional]);

If the callback is ommitted, the events array of the named event (e.g. "click") is returned. If no name is given, too, the complete events object is returned.

t.e(document, 'ready', function() { t('#domready').a('class', 'passed')[0].innerHTML='passed'; }); -- passed after document.ready: failed

Events are normalized: every key code is in the property "key", the normalized mouse cursor position is in mouseX and mouseY and there is always a "target"-property.

Helpers

t.i - Iterate

Interates over Arrays and Objects:

t.i([object:Array|Object], [callback:Function, this=object, arguments=[key, value]]);
t.i([1, 2, 3], function(i, v) { console.log(v); });
t.i(window, function(k, v) { console.log(k); });

t.x - eXtend Object

Extends Objects and Arrays:

t.x([object:Object], [object2:Object], [object3:Object, optional], ...);

Extend Objects:

t.x({x:1}, {y:2}, {z:3}) => {x:1, y:2, z:3}

Extend Arrays:

Arrays will simply be merged:

t.x([1,2], [3,4,5], [6,7,8]); // -> [1,2,3,4,5,6,7,8]

t.f - Filters Arrays and Objects:

Returns a filtered Array or Object. If asArray is set to something that can be converted to true, an Object will be iterated as Array. The function will have this set to the Object and receives the key-value pairs as its two parameters. If it returns undefined, the instance will be ommitted. If only an Array without a function is given, it doubles as unique-function to filter multiple instances with the same value.

t.f([Object/Array], [Function], [optional: asArray])> t.f([1,1,1,2,1,1,3,1]) => [1,2,3]

t.w - Where in the Array is...?

Returns the index of an object within the Array or else -1

t.w([object], [array:Array]) t.w(3, [1,2,3,4,5]) === 2
t.w([object], [array:Array])

t.p - Parameterize Object

Converts an Object into an parameterized String (if no other options but the object are provided, it will be URL-encoded):

t.p([object:Object], [middle:String, optional], [connector:String, optional], [prefix:String, optional], [suffix:String, optional], [filter1:Function, optional], [filter2:Function, optional]) t.p({did:'work',all:'right'}) === 'did=work&all=right'

If t.p is used as sole argument to the Selection-Method v, all values of all selected Nodes will be returned as URL-parameterized String.

Network

t.a - Ajax

Versatile Ajax Request:

t.a({
    url:[url:String],
    method:[method:String,(GET|POST), optional],
    data:[postdata:String|Object, optional],
    async:[callback:Function, optional]
});

t.j - JavaScript, JSONp

Can load Scripts (e.g. Plugins) asynchronously or perform JSONp-Requests:

t.j([url:String], [callback:(name)String/Function], [timeout,Integer(ms, optional)]);

Plugins

Code-Styleguide and Minification

The end of size reduction is of highest priority, yet a certain style should not be amiss and Optimisations that can be gained by a few chars should not be ommitted. In such situations in which the size reduction destorts readability too much, readability is more important; otherwise, some well-placed comments should ensure maintainability for me and others. Such places prone to debugging whould be isolated by line breaks. Every line that does not comment itself should be graced by a comment (since all comments are filtered by the minification, use many of those).

The Minification should only remove those line breaks that are not important to debugging - if more than one problematical assignment share one line, the debugging developer has to guess, thus rendering the usability of the minified code remote for debugging purposes.