README
dom
A convenience library for common DOM methods.
dom uses UMD, so it will work with globals, AMD, or Node-style module exports.
Getting Started
To install using bower:
bower install @clubajax/dom --save
Or npm:
npm install @clubajax/dom --save
You can clone the repository with your generic clone commands as a standalone repository or submodule.
git clone git://github.com/clubajax/dom.git
With AMD, it is recommended that you set the config.path of RequireJS to make dom
accessible as an
absolute path.
dom
has no dependencies.
Description
The primary function is to make it more finger-friendly to create, modify, and delete DOM nodes, and to add and remove styles and attributes. There is some extended functionality as noted in the API docs below.
Support
dom
supports modern browsers, IE9 and up. Some modern DOM methods like classList
are expected.
This library uses UMD, meaning it can be consumed with RequireJS, Browserify (CommonJS), or a standard browser global.
dom
function
The dom
is the main function, and has several more functions attached to that function. So you can
create a node with the main function like:
dom('div');
And you could access nodes with the byId
attached function, like:
var node = dom.byId('my-node');
API
dom()
Creates and returns a node.
if the first argument is a string and starts with '<', it is assumed to use be an HTML string, and creates a node using innerHTML. Optional second arg is a parentNode.
var node = dom('<div>my dome node</div>', parentNode);
The previous can be more explicitly done by using dom.toDom()
if the first argument is a string and does not start with '<', it is assumed to be a nodeName,
and a node is created via document.createElement()
.
var node = dom('div');
Additional parameters (all optional):
The second parameter is options
which is an object that can contain properties or other objects:
id
: sets the node IDclass
orclassName
: Sets the node classhtml
orinnerHTML
: Sets the content of the node, Possible values:- string: will be added as innerHTML
- object (HtmlElement): Will be be added via appendChild
- array: HtmlElements will be appended and strings will be converted into dom nodes and appended
style
: An object of CSS key-value styles. This object is passed to dom.style()- All other keys are expected to be attributes.
- (The
attr
object has been deprecated from 1.x)
- (The
The third parameter is an node or a node id, where the newly created node will be appended
The fourth parameter is a boolean. If true, the newly created node will be prepended, not appended.
The html
can accept
dom.fromDom() Converts a dom node and its children into a JavaScript object. Example:
<div id="option-div" class="foo" value="bar" selected="a" disabled="true" is-prop="">
<option value="a">A</option>
<option value="b" selected="">B</option>
<option value="c">C</option>
</div>
result = {
children:[{
text: 'A',
value: 'a'
},{
text: 'A',
value: 'b'
},{
text: 'C',
value: 'c'
}],
class:"foo",
disabled:true,
id:"option-div",
'is-prop':true,
selected:"a",
text:"",
value:"bar"
}
dom.style()
dom.style
is a getter or a setter, depending on the parameters passed.
To use as a getter, the parameters should be a node, and a string property (only one property can be
accessed at a time). If the result is in the node.style object, that is returned. If not, the
property is acquired through the window global getComputedStyle
.
To use as a setter, add a third parameter as a value:
dom.style(node, 'width', 100);
Note that like jQuery, the value did not need to be a string appended with 'px'. If the style is a dimensional property, this is done automatically. The dimensional properties are:
width
height
top
left
right
bottom
maxWidth
max-width
maxHeight
max-height
A more common way to use as a setter is to make the second parameter an object:
dom.style(node, {
width: 100,
height: '10em',
top: '50%',
position: 'absolute',
zIndex: 1
});
dom.attr()
Similar to dom.style
, dom.attr
is a getter/setter to get and set attributes on nodes.
As a getter:
var dataItem = dom.attr(node, 'data-item');
As a setter:
dom.attr(node, 'data-item', dataItem);
Or multiple attributes:
dom.attr(node, {
'data-item': dataItem,
scrollTop: 100,
contentEditable: true
});
Complex objects can be passed while creating custom-element nodes, via attr
as a convenience:
dom('my-custom', {
myObject:{
a:1,
bool:tru
}
});
You could also use dom.attr() to pass a node, but that wouldn't make much sense.
Events can be added to a node. Is is expected that the value will be a function and the key will be an event name, prepended with on
and a capital, such as in the example:
dom('button', {
onClick: function () {
console.log('The button has been clicked');
}
});
A MutationObserver is used to disconnect the event when the node is destroyed or removed from the document.
If the key is not appended with on
, it is treated as an object and assigned to the node (which can then be called as a method).
dom.byId('nodeId')
If the parameter is a string, it finds a node with document.getElementByid(). If not found, returns null. If the parameter is an object, it is assumed to already be a node and is returned.
Bonus: if it is detected to be a jQuery $element, it "de-jQuery-ifies" it, and returns a node.
dom.box(node)
Returns the dimensions of the passed node. Mainly an alias for getBoundingClientRect()
. If the
passed item in the window object, returns its width and height.
dom.relBox(node, ?parent)
Returns the dimensions of the passed node and it's position relative to its parent node. Returns simple {x,y,w,h}
. Assumes to compare position to immediate parent unless second node is passed.
dom.size(node, type)
Returns the width and height of the passed node. If the position is not needed, this is faster than dom.box
. The type
parameter indicates:
client
: returns the inner height/width of an element in pixels, including padding but not the scrollbar height, border, or margin.scroll
: is a measurement of the height/width of an element's content including content not visible on the screen due to overflow.offset
(default): is a measurement which includes the element borders, the element padding, the element scrollbar (if present, if rendered) and the element CSS height/width.
dom.query([?node], 'div.myClass')
An alias for document.querySelector
, so the parameter should conform to that.
dom.queryAll([?node]'div.myClass')
An alias for document.querySelectorAll
, so the parameter should conform to that. Returns an Array, not a
NodeList.
dom.insertAfter(refNode, node)
Inserts a node after the reference sibling.
dom.place(parentNode, node, position)
Inserts a node at the child position of the parentNode. Handles bad positions (null, > children.length, etc).
dom.destroy(node)
Destroys a node completely.
dom.clean(node)
Removes (but does not destroy) all child nodes.
dom.classList
dom.classList
is essentially a passthrough for node.classList methods, add
, remove
, toggle
, and
contains
.
There is extended functionality in add
and remove
: standard functionality doesn't allow for Arrays or
strings with spaces (ergo, two classes at once). dom.classList
allows for this.
toggle
works around an IE bug.
Examples:
dom.classList.toggle(node, 'selected', !!this.isSelected);
dom.classList.add(node, 'foo bar baz');
dom.classList.remove(node, 'foo baz');
dom.normalize()
Returns a normalized value from the passed string. Conversions look like:
'true' => true
'false' => false
'null' => null
'1.5' => 1.5
dom.frag()
Pass in an array of nodes and it returns a document fragment:
var frag = dom.frag([
dom('header', { html: `Custom ${item.label}` }),
dom('h1', { html: `Value: ${item.value}` })
]);
node.appendChild(frag);
Comes with Stub Included!
The benefit of using dom
exclusively in your code, is it comes complete with a "dom stub",
which can be substituted in Node.js unit tests.
The stub is as described, a stub, meaning most of the functions are NOOPs. But there are a few
functions that work as mocks, meaning they are functional with dummy/partial data. Simple objects
are returned as dom nodes, which should result to truthy in tests. These simple objects have an
innerHTML
getter/setter so text comparisons can also be done. They also keep track of their
children and parent nodes, so some DOM manipulation can be simulated.
It is recommended that the stub/dom.js should be looked over to learn of its full functionality.
License
This uses the MIT license. Feel free to use, and redistribute at will.