# cash-js

> Micro library for easing the pain of working with the DOM

Latest version **1.0.2** (published 2017-07-30) · MIT license · 0 weekly downloads

## Install

```sh
npm install cash-js
pnpm add cash-js
yarn add cash-js
bun add cash-js
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.2 |
| Published | 2017-07-30 |
| First published | 2014-10-10 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 130 |
| Author | Rob Robbins |
| Maintainers | rob.robb.ns |
| Keywords | DOM, micro, library, badass |

## Links

- npm: https://www.npmjs.com/package/cash-js
- Repository: https://github.com/sudo-js/cash
- Homepage: https://github.com/sudo-js/cash#readme
- Issues: https://github.com/sudo-js/cash/issues
- npm.io page: https://npm.io/package/cash-js

## Alternatives

- [babylon](https://npm.io/package/babylon.md) — 5.1M weekly downloads
- [csscolorparser](https://npm.io/package/csscolorparser.md) — 3.7M weekly downloads
- [expr-eval-fork](https://npm.io/package/expr-eval-fork.md) — 1.5M weekly downloads
- [@leeoniya/ufuzzy](https://npm.io/package/@leeoniya/ufuzzy.md) — 247.7K weekly downloads
- [xml-parser](https://npm.io/package/xml-parser.md) — 78.4K weekly downloads

## Recent versions

- 1.0.2 (latest) — 2017-07-30
- 1.0.0 — 2017-07-15
- 0.3.2 — 2014-10-11
- 0.3.1 — 2014-10-11
- 0.3.0 — 2014-10-10

## README

cash
====

### What Cash Is Not
Another replacement for jQuery. Cash does not attempt to be compatible with the
jQuery API.

### What Cash Is
A tiny library that absracts some pain points when working with native Javascript
and DOM.

#### Why?
Because if you are not supporting bad browsers you do not need the shims that
were created to support them.

###### Annotated Source
[Here](http://sudo-js.github.io/cash)

## I Can Haz $?
Cash **does** take the familaiar `$` name as it's global identifier. That's where
the similarity ends. The cash `$()` **function** will only accept a DOM node or
nodeList as an argument. We have standardized ways to search the DOM for elements
now, **cash** thinks you should use those.

    // as an example, you have a nodeList
    var things = document.querySelectorAll('.foo');

Passing the `things` nodeList as an arg to `$()` would result in **cash** storing
that list on the **cash** object as `q`, and here's the important part, **as an array**.

    $(things);
    // now there is a this.q that is an array of DOM elements with a class of foo

In a familar fashion, calling `$()` will return `$` itself so that chainable stuff
can happen. In an unfamiliar fashion however, what is returned **is not a unique instance**.
This is paramount to understand. Any call to `$()` simply sets the `q` and returns.
**That is All**.

Let's say that the `things` nodeList contained 3 `div` elements when it was passed to `$()`.
That means that there are 3 elements in the `$.q`.

    $(things);
    $.q //=> [div, div, div]
    Array.isArray($.q); //=> true

Since calling `$()` returns `$` though the `q` array is always available in a
chainable fashion, ready to be used.

    $(things).q.forEach(function(el) {el.classList.remove('foo');})

**NOTE**: Calling $(...) resets the `q` to what you pass in. Sometimes you may
want to re-use an existing `q`, but that's not the preferred pattern. All chainable methods
operate on, and possibly modify the `q`, **including event callbacks**.

It's not expensive to call `$()` so don't fear to simply reset the `q`.

### Why U No Pass In String?
It would not be expensive or bloat the codebase to allow `$()` to take a string then
perform a querySelectorAll with it, returning that back to `$()`. But I won't. Why?
One, it promotes `God Dollar` and that's bad. An 'unscoped' call to `$` is a
**code smell** and should be rather unwieldy. Two, it's a slippery slope for the
dollar function to start accepting other args. It accepts a node or a collection
of them and that's all.

## Chainable Methods
Functions that operate on the `q` are what **cash** is all about, which ones to implement will be the
ongoing debate that is the future development of **cash**.

### Call, Collect and Assign
In order to keep code creep at a minimum, We are introducing these three methods that allow
the invocation of native functionality on the elements in the `q`. What do I mean? Let's take
the *Attribute methods for an example. We _could_ write seperate methods for the getting, setting,
and removal of attributes:

    cash.setAttribute = function(foo, bar) {
      // set attribute 'foo' to 'bar' on each element in the q
    };

    cash.removeAttribute = function(foo) {
      // remove attribute 'foo' from each element in the q
    };

    cash.getAttribute = function(foo) {
      // collect and return attribute 'foo' from each element in the q
    };

Instead we can have a single method capable invoking any of these (or any native
method for that matter):

    // We use the call method, passing the method name we want to invoke
    // as well as the arguments for it
    $(foo).call('setAttribute', 'data-foo', 'bar'); // returns cash
    // the same method for remove
    $(foo).call('removeAttribute', 'data-foo');
    // It in worth noting that we will use collect for methods that we expect
    // to return a value
    $(foo).collect('getAttribute', 'data-foo'); // retruns an array

In the same way that we can consolidate the calling of methods on Elements we can
also for 'direct assignments' like `checked`, `value` etc...

    $(foo).assign('checked', true);

### Events
The familiar `on` and `off` methods are provided as, though event binding is standardized
now in all good browsers, unbinding can produce much boilerplate in a large project.
Particularly in a single-page-app where removing event listeners is paramount.

#### on(event, callback[,selector][, data][, cap])
Adds an event listener to each element in the `q`. Very similar to the jQuery `on`
method with the exception of the order of arguments:

+ **event** A DOM Event name
+ **callback** A function to be called when the event occurs
+ **selector** Optional CSS selector allowing delegatation of events to the target element.
+ **data** Optional object literal passed to the callback as `e.data`
+ **cap** Optional boolean that, if truthy, will force capture phase to be used.

###### delegateTarget
All events bound by cash will have a delegateTarget attribute. If a selector was used
(the event was delegated) the delegateTarget will match the provided selector.

#### off(event[, callback][, cap])
Removes all events bound to the `event` name, or just the passed in `callback`
(if present), for each element in the `q`. Maintaining the correct reference to
a `callback` can be ugly so if you are looking to remove a specific `callback` on
an element for an event which may have many listeners, using a `namespaced event`
may be a better choice.

You may use a `*` event name to capture sets of events. For instance, `*.ns` would
remove all events which were bound to the `ns` namespace. Similarly `*` would
remove all events, regardless of event name or namespace.

###### Cap'n
The `cap` argument will need to be passed for the event to be unbound **if you
passed the argument when binding it**.

It is worth nothing that the `blur` and `focus` DOM events do not bubble and therefore
do not (normally) work correctly with delegation. You can however use the capture phase
to remedy this. Cash, if it sees that `on` is being used with either `focus` or
`blur` **and** there is a `sel` (delegation being used) it will force the `cap` arg
to true (therefore using capture phase). If `off` is called on either `focus` or
`blur` and you had used delegation you **do not need to pass the cap** argument.
Cash will know to use it for you.

##### Event Namespacing
Similar in practice to the jQuery event namespace, you can append a value to an
event name (or many of them) as a dot-delimited string:

    $(things).on('click.foo', callback);

This makes it much simpler to remove a specific callback, say another click event
listener had already been added:

    $(things).on('click', anotherCallback);

Simply removing `click` from `things` via `off` would remove both listeners. In a
case where you only wanted to remove `callback` and not `anotherCallback` you would
pass the namespaced event name to `off`:

    $(things).off('click.foo');

There is no need to pass the second argument.

##### Baby You're A *
The '*' character has a special meaning for the `off()` method. Passed with a namespace
it will remove all listeners that share the namespace.

    $(things).off('*.foo');

In a more drastic move you can remove all listeners simply by passing the *.

    $(things).off('*');

###### Caveat
Cash does not override the native event passed to your listeners. This means that
the `trigger` method cannot be used to fire **only** a namespaced event.

    $(things).on('click', callback).on('click.foo', fooCallback);

Calling `trigger('click')` on `things` here would call both `callback` and `fooCallback`.
The latter would recieve the namespace attached to the event passed to it however, as
`event.namespace` (it would be 'foo'). The former would not, `event.namespace` would be
falsey.

### Traversal
Methods that alter the `q` based on some DOM related criteria.

#### closest(selector)
For each element in the `q` traverse upwards to find the first element that matches
the given CSS selector. The `q` will be accordingly rehydrated with the found elements.

    $(someInput).closest('form');

#### find(selector)
Given a CSS selector query each element in the `q` for all matches to that selector.
Rehdrate the `q` with any and all of those matches.

    $(someUl).find('li');

#### contains(element)
Qeury each element in the `q` for which contains the passed in element. Reset
the `q` with that container if found.

    $(things).contains(someElement);

### Styles
Methods for the getting or setting of styles.

#### offset()
Calling this method will return a hash of key:value pairs that represent the
position in the document of the 'zeroth' element in the `q`. Note that the
`top` and `left` properties will take into account page[X|Y]Offset and the
`width` and `height` properties will be rounded.

    $(someElement).offset();
    // => {top: xx, left: xx, width: xx, left: xx}

Note: `offset` is a getter only.

#### style(key|obj[, value])
Set one, or multiple, style properties on each element in the `q`.

Though you could interact with the `element.style` object directly there are a
few reasons that having this method available is advantageous. One, you can pass it
numbers and 'px' will be added when appropriate. Two, by passing a hash of key:value
pairs the setting of multiple styles at once is possible.

##### itGoesLikeThis, not-like-this
when passing arguments to the `style` method camel case the keys, do not pass them
'dasherized`. This applies to both the single key and val case and the hash one.

    // the single style case
    $(things).style('paddingTop', 10);
    // multiple
    $(things).style({paddingTop: 10, marginLeft: 5});

### API Summary

##### All Module
+ call(string[, *args])
+ collect(string[, *args])
+ assign(string, argument)

##### Core Module
+ $(node|nodeList) Note: Does not return a unique instance, simply returns `cash`.
+ get(number) Note: Can use negative numbers for RTL selection
+ isObect(argument)
+ noop

##### Style Module
+ style(string|object[, string])

##### Size Module
+ offSet() Note: Does not function as a setter.

##### Event Module
+ off(string[, function, bool]) Note: bool is capture phase support.
+ on(string, function[, string, object, bool]) Note: The order of arguments and the bool capture phase support.
+ trigger()

##### Is Not Module
+ is(string) Note: Accepts a string argument only.
+ not(string) Note: Accepts a string argument only.

##### Traversal Module
+ closest(string)
+ contains(node) Note: Returns `cash` not the container.
+ find(string)
+ parent()
+ parents()

### A Note On Modules
The package exports two constants you can use:
+ `$` The canonical dollar. This is what you pass some node list to and chain off of. Under
  the covers its just the `init` method on the cash instance bound to cash.
+ `$$` Cash itself, this is useful for when you don't want to reset the `q`.

See the specs for examples of both. __NOTE__ those specs are in es5, but in an es6
module you would use the nicer import syntax:

    import { $, $$ } from 'cash-js';

---
_Source: https://npm.io/package/cash-js · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
