0.2.3 • Published 8 years ago

safdom v0.2.3

Weekly downloads
3
License
MIT
Repository
github
Last release
8 years ago

SAFDOM

Simple as $uck DOM API shorthands. Fast as hell. Mainly to use with latest Chromium (24+). All other browsers compatibility notes in code are JUST FOR REFERENCE, and not all features have such notes. It is not intended to be totally cross-browser, although tries to use only general, well-known and compatible calls.

API IS ABOUT TO CHANGE in future releases, so use at your own risk, or use fixed version

I'm using it with my nw.js projects to get totally rid of jQuery (which is VERY SLOW and bloated for such use), while having convinient tool for querying CSS selectors, DOM traversal and manipulations.

It does not have tests (yet?) and had been published only for demonstration purposes. Can have some dirty comments and untested code and does not ready for production use.

About tests: having the code not being very complicated, it still requires some unit testing. If you can/want to help writing them (and for any other contribution or sugestions) -- use offshore@aopdg.com to contact me.

P.S. I know that extending core objects' prototypes is far not a 'best practice' and have some side effects, but hey. Accept it or leave it. It's a specific thing for a specific case. And bear in mind that unlike other browsers, Chromium is immune to performance impact introduced by such approach.

Dive in

Just

npm install safdom

or

git clone https://github.com/offshore/safdom.git

SAFDOM default behavior depends on include method. The detection based on variable module tested to be in surrounding context. See below.

Compatibility

That's a shallow compatibility table for major features; some of browsers' lower versions are not mentioned.

BrowserVersionFeatureDependency
Chrome24+.$class* fullElement.classList: several arguments in the add/remove/toggle
Chrome8+.$class* basicElement.classList
FF26+.$class* fullElement.classList: several arguments in the add/remove/toggle
FF13+.$clone(true)Node.cloneNode(true)
FF9+.$hasNode.contains
FF3.6+.$class* basicElement.classList
IE10+.$class* fullElement.classList: several arguments in the add/remove/toggle
IE9+Too many things became available only with IE 9+
Opera11.5+, 15.0+.$isElement.matches
Safari5.0+.$isElement.matches

Browsers / simple

<script type="text/javascript" src="path/to/dist/safdom.min.js"></script>

or CDN:

<script type="text/javascript" src="//npmcdn.com/safdom@0.2.3/dist/safdom.min.js"></script>

This just loads SAFDOM and do prototype extension automatically.

NW.js / advanced

If your nw.js project is simple single-window application, you can use the browser method already described above. But there is one more interesting option available, especially if you open (possibly many) windows dynamically. In background context you can do something like this:

var $SAF = require('safdom');
// when you open new window, do magic:
nw.Window.open('someWindow.html', {}, function(someWindow) {
    $SAF(someWindow.window);
});

And then, someWindow's DOM objects got extended.

API Reference

A note on forEach, NodeList and HTMLCollection

The only unprefixed thing in SAFDOM is a forEach method for NodeList and HTMLCollection; however its done to achieve the same behavior and interface as seen on (Array|Map|Set|...).forEach(); the only difference is that it returns list on which it was called -- for chaining purposes.

  • list.forEach(callback, thisArg): wrapper to Array.prototype.forEach.call(list, callback, thisArg || list), returns list; callback's this is pointing to thisArg; and arguments are:
    • v: (currentValue), the current thing being processed in the list
    • k: (index), the index of the current element being processed in the list
    • list: (array), The array that forEach is being applied to

Another method for NodeList and HTMLCollection is $slice, which acts exactly as Array.slice and can be used to flatten LIVE lists.

  • list.$slice(begin, end): same as Array.prototype.slice.call(list, begin, end), returns shallow copied list transformed to plain array

Maybe it's worth switching from forEach to map, because latter is more suitable for chaining. Anyway, I think NodeList and HTMLCollection deserve their own map and reduce methods.

Node comparison

  • x.$has(y): same as x.contains(y)
  • x.$eq(y): check x identity (===) to y
  • x.$lt(y) and x.$gt(y): determine that x is somewhere before or after y in DOM tree, respectively. Uses Node.compareDocumentPosition, returns 0 or non-0 (see Node.DOCUMENT_POSITION_*).

Node manipulation

All of those methods do the same things as their jQuery cousins; except that x and y can only be Node instances (no strings, selectors, arrays or other magic handling). However you may be interested in $(html|text)(Before|Prepend|Append|After) -- see below. They all return x (except $clone, which returns (optionally deep) detached copy of x), so can be easily chained with each other or other manipulation shorthands.

  • x.$after(y) * x must have parent
  • x.$append(y)
  • x.$appendTo(y)
  • x.$before(y) * x must have parent
  • x.$clone(deep): same as x.cloneNode(deep); returns detached copy of x
  • x.$detach()
  • x.$insertAfter(y) * y must have parent
  • x.$insertBefore(y) * y must have parent
  • x.$prepend(y)
  • x.$prependTo(y)
  • x.$replace(y) * x must have parent; remember that replaceChild is destructive
  • x.$clear(): same as jQuery.empty() -- wipes children

Element extensions

Attributes

  • x.$attrH(k): same as x.hasAttribute(k)
  • x.$attrG(k): same as x.getAttribute(k), pay attention to behavior notes in MDN related to return value and lowercasing
  • x.$attrS(k, v): same as x.setAttribute(k, v), but returns x for chaining
  • x.$attrD(k, k, ...): same as x.removeAttribute(k) for each argument, but returns x for chaining
  • x.$attrU(k, v): $attrD when v == null, $attrS otherwise
  • x.$attrU(kv): $attrU for each k and v in kv

Properties

  • x.$propG(k): just return xk
  • x.$propS(k, v): set xk to v, return x for chaining

Class names

Remember that IE10- does not support the second parameter for .toggle() and multiple params for .add or .remove; however it may be shimmed later. See docs for Element.classList / DOMTokenList.

  • x.$classA(v, v, ...): add each v to Element.classList
  • x.$classD(v, v, ...): remove each v from Element.classList
  • x.$classH(v): check that Element.classList contains v
  • x.$classT(v, state): toggle v in Element.classList when state == null, otherwise add/remove it for state is true/false, respectively

HTML content and manipulation

  • x.$htmlG(): just return x.innerHTML
  • x.$htmlS(v): set x.innerHTML to v, return x for chaining

Those are crafty. Allows you to update HTML content inside and around element without side effects (losing events or performance impact); so they act like x.$before, x.$prepend, x.$append and x.$after versions with html argument. See Element.insertAdjacentHTML for details.

  • x.$htmlBefore(v) * x must have parent
  • x.$htmlPrepend(v): like x.innerHTML = v + x.innerHTML
  • x.$htmlAppend(v): like x.innerHTML = x.innerHTML + v
  • x.$htmlAfter(v) * x must have parent

Text content

Note compatibility issues for *G and *S: see reference for Node.textContent.

  • x.$textG(k): just return x.textContent
  • x.$textS(k, v): set x.textContent to v, return x for chaining

Acts like x.$before, x.$prepend, x.$append and x.$after versions with text argument, automatically creating text Node with supplied argument and attaching it appropriately.

  • x.$textBefore(v): * x must have parent
  • x.$textPrepend(v)
  • x.$textAppend(v)
  • x.$textAfter(v): * x must have parent

Search/selection utilities

Note that results of methods for querying multiple things can return not only HTMLCollection, but NodeList as well, and both LIVE and NON-live versions; it can be tricky sometimes, so be sure to check documented behavior for appropriate shorthands.

Traversal utils related to Element (not Node!)

  • x.$idx(): obtain x index relative to its parent, or -1 if not found or detached
  • x.$idxOf(y): obtain y index relative to x, which should be it's parent, returns -1 if not found, detached, or y is not direct child of x
  • x.$up(): just return x.parentElement
  • x.$fc(): just return x.firstElementClild
  • x.$lc(): just return x.lastElementClild
  • x.$ps(): just return x.previousElementSibling
  • x.$ns(): just return x.nextElementSibling

Deprecated for now due to naming problem and tricky nature (uses css4 :scope and index detection, not mentioned in compatibility table). Most likely be renamed to $psa and $nsa, or even be completely cut:

  • x.$pss(): find all siblings between (and including if not null) x.parentElement.firstElementChild and x.previousElementSibling, returns NONlive list
  • x.$nss(): find all siblings between (and including if not null) x.nextElementSibling and x.parentElement.lastElementChild, returns NONlive list

More utils

See also $meta.px()/$meta.py().

EventTarget shorthands

Only minimal set of utilities for now Note that EventTarget.prototype is not consistently available, so fo browsers like IE, SAFDOM extends only window, window.document and Node.prototype with related methods, leaving other thing like XMLHttpRequest unmodified.

Globals

Selectors:

Minimal (for now) construction shorthands:

Utility:

It really hurts when you try to determine, which element is actually the main scrolling thing, html or body. Here, take this painkiller.

  • $meta.se(): utility to get document.scrollingElement. Includes cross-browser shim via https://github.com/mathiasbynens/document.scrollingElement, which is partially rewritten and optimized to be fully transparent in Chromium. This method caches it's return value, so the steps to detect scrollingElement are not performed once document.readyState is no more loading. I guess it's useful for weird setups only, but if you need to flush this cache, call $meta.seReread().
  • $meta.px(), $meta.py(): viewport pageXOffset/pageXOffset to use with Element.$rect/Element.$rects (in general, this is not the same as scrollLeft/scrollTop, but workaround included; see also https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY). Note that this functions are affected by scrollingElement cache (see $meta.se()).

Appendix: method name parts cheatsheet

The dictionary of method names is fairly simple, short and easy to remember; screw those who prefer WaitForMultipleObjects over poll.

  • attr: Attribute-related stuff
  • class: Element class names
  • html: HTML content manipulation
  • prop: Properties
  • text: Text content manipulation
  • f: Find all elements matching query
  • s: Single element that meets query
  • t: Search by tag name
  • c: Search by class name
  • A: Add
  • D: Delete
  • G: Get
  • H: Has
  • S: Set
  • T: Toggle
  • U: Update
0.2.3

8 years ago

0.2.2

8 years ago

0.2.1

8 years ago

0.2.0

8 years ago

0.1.1

8 years ago

0.1.0

8 years ago

0.0.1

8 years ago