Getting Started With DOMmy.js
DOMmy.js is a super-lightweight, standalone Javascript library, designed to work easily with the DOM and produce powerful CSS3 animations via JS.
Full disclosure: I developed DOMmy.js. And in this tutorial I want to demonstrate how it can be used to keep your webpages nice and light.
DOMmy.js has a very shallow learning curve; it’s even shallower if you have ever used an old-generation style framework such as jQuery or Prototype.
DOMmy.js isn’t a next-generation framework like Vue.js, React, or Angular; these are tools which use new technologies such as the virtual DOM, dynamic templating, and data binding; you use next-generation tools to build asyncronous applications.
DOMmy.js is a Javascript frame work for writing “classic” Javascript code, working with the DOM at the core level. A Javascript framework like jQuery does a similar task, with three big differences:
- jQuery uses a proprietary, internal engine to work with selectors and to produce animations. This engine is entirely Javascript-based. Conversely, DOMmy.js allows you to select any element in the DOM and create powerful animations, by using the modern and super-powerful specifics of both Javascript and CSS3. I didn’t need to write a Javascript engine to work with DOM and animations. The cross-browser, flexible and powerful tools that allow you to do it are already available. I just wanted a Javascript structure that would assists developers in writing DOM controls and CSS3 animations using the Javascript language.
- DOMmy.js is a Javascript structure that looks at the future. It is written to be compatible with some of the latest versions of the major browsers, but I don’t want my code to be compatible with very old software like IE6/7 and similar.
- jQuery and Prototype both have complete APIs based on an internal engine, DOMmy.js provides controls for just two main things: DOM operations and animations; other tasks can easily be accomplished with vanilla Javascript or by extending the DOMmy.js central structure.
So, DOMmy.js is a cross-browser, super-lightweight (the minified version weights only 4kb), super-easy to learn, super-fast to execute, Javascript library. In a nutshell, with DOMmy.js you can:
- navigate throughout the DOM, by selecting and working with HTML elements and collections of elements;
- create powerful CSS3 animations and collections of animations;
- add (multiple) events, CSS properties and attributes to elements;
- use an element storage to store and retrieve specific content;
- work with a coherent this structure;
- have a cross-browser DOMReady fashion, with which you do not need to wait for resources (like images and videos) to completely load in order to work with DOM.
Installing DOMmy.js
Implementing DOMmy.js into your web page is simple. You only need to include the script through the script tag, and you’ll be ready to start. You can download the script and use it locally or load it through the project’s website:
<script src="https://www.riccardodegni.com/projects/dommy/dommy-min.js"></script> <script> // use dommy.js $$$(function() { // ... }); </script>
The DOM is Ready!
Like I said on before, with DOMmy.js we don’t need to wait for the resources of the page to load in order to work with DOM. To do this, we use the $$$ function. The content placed inside this handy function will be executed when the DOM structure (and not the “page”) is ready. Writing code with DOMmy.js is super-fast. I wanted to create a snippet that allowed me to write as less code as possible, so I guess that nothing is faster than writing:
$$$(function() { // when DOM is ready do this });
…in a standalone fashion. Of course, you can use as many DOMReady blocks as you want or need:
// block 1 $$$(function() { // when DOM is ready do this }); // block 2 $$$(function() { // when DOM is ready do this }); // block 3 $$$(function() { // when DOM is ready do this });
Select DOM Elements
So now we can start to work with our DOM structure. You can select the element you want by using an HTML “id”. This is done with the $ function:
// select an element by ID. // In this case you select the element with ID "myElement" $('myElement');
And you can select the collection/list of elements you want by using a CSS selector. This is done with the $$ function:
// select a collection of elements by CSS selector $$('#myid div.myclass p')
Of course you can select multiple elements by using multiple selectors, too:
// a selection of HTML elements $$('#myfirstelement, #mysecondelement') // another selection of HTML elements $$('#myfirstelement div.myclass a, #mysecondelement span')
There are no limits to DOM selection. The elements will be included in the final collection with which you can work with the DOMmy.js methods.
Adding Events
Adding events to elements (in a cross-browser fashion) is very simple. Just use to the on method on the collection of element you want to attach the event(s) to with the specific event:
// add an event to an element that fires when you click the element $('myElement').on('click', function() { log('Hey! You clicked on me!'); });
Note: the function log is a built-in function that works as a global-cross-browser shortcut for console.log. If the browser does not support the console object the result will be printed in a global alert box.
You can add multiple events at once, of course:
// add a events to an element $$('#myElement p').on({ // CLICK event 'click': function() { log('Hey, you clicked here!'); }, // MOUSEOUT event 'mouseout': function() { log('Hey you mouseovered here!'); } });
As you can see, you don’t need to apply the DOMmy.js methods to each element. You apply the methods directly to the result of the DOM selection and the internal engine will properly iterate through the HTML elements.
You can access the “current” element in the iteration simpy by using the this keyword:
$('demo').on({ 'click': function() { this.css({'width': '300px'}) .html('Done!'); } });
Working With Attributes
In the same way, you can add, edit and retrieve the values of HTML attributes:
// get an attribute var title = $('myElement').attr('title'); // set an attribute $('myElement').attr('title', 'my title'); // set multiple attributes $('myElement').attr({'title': 'my title', 'alt': 'alternate text'});
The attr method works in three different ways:
- it returns the value of the specified attribute if the argument you provided is a string;
- it sets an HTML attribute to a new value if you pass two arguments;
- it sets a collection of HTML attributes if you pass an object of key/value pairs representing the element’s attributes.
Setting CSS Styles
Just like HTML attributes, you can set and get CSS values by means of the css method:
// set single CSS $('myElement').css('display', 'block'); // set multiple CSS $('myElement').css({'display': 'block', 'color': 'white'}); // get single CSS $('myElement').css('display'); // get multiple CSS $('myElement').css(['display', 'color']);
As you can see, with the powerful css method you can:
- set a single CSS property to a new value, if you pass two strings;
- get the value of a CSS property, if you pass one string;
- set multiple CSS properties, if you pass an object of key/value pairs;
- get an array of values, if you pass an array of strings representing CSS properties.
Getting and Setting HTML Content
With the html method you can set and get the element’s HTML value:
// set html $('myElement').html('new content'); // get html var content = $('myElement').html(); // logs 'new content' log ( content );
Iteration
If you select more than one element, you can apply a DOMmy.js method to every element just in one call.
However, when you want to work with each element manually, like when you are getting contents (i.e. HTML content or stored content). In this case, you can use the handy forEach function in the following way:
// get all divs var myels = $$('div'); // set a stored content myels.set('val', 10); // ITERATE through each single div and print its attributes myels.forEach(function(el, i) { log(el.attr('id') + el.get('val') + ' \n'); });
The forEach funtion is the preferred way to iterate through HTML collections of elements using DOMmy.js. When applied on a DOMmy.js element, it uses two parameters:
- element: the DOMmy.js element you are selecting. You can apply every DOMmy.js method to it;
- index: an index representing the position of the element in the collections of elements.
Storage
The storage is a place, that belongs to elements, where you can store as many values as you want and retrieve them at the desired moment. You can work with the storage by using the set and get methods:
// set storage var myVal = "hello"; $('myElement').set('myVal', myVal); // multiple storage var mySecondVal = "everybody"; $('myElement').set({'myVal': myVal, 'mySecondVal': mySecondVal}); // get $('myElement').get('myVal') + $('myel').get('mySecondVal'); // "hello everybody"
As you can see, you can store single item or multple items at once. The items you store belong to the element that you are selecting.
Note: remember that if you are selecting multiple elements, the item will be stored in each of these elements, even if the CSS is slightly different, because DOMmy.js recognizes each specific element:
// set an item to div#a and div#b $$('div#a, div#b').set('myStoredValue', 10); // get from #a, that of course is the same as div#a $('a').get('myStoredValue'); // 10
Of course DOMmy.js internal mechanics identify “div#a” and “a” / “#a” as the same pointer to the same element, so you can safely work with storage and others DOMmy.js methods in a coherent way.
If you store the DOM element in a single variable, which is the best way to work with HTML elements, you can bypass concurrent calls and earn memory space:
const myEl = $("div#a div"); // store data myEl.set('myStoredValue', 10); // get data myEl.get('myStoredValue'); // 10
CSS3 Animations
The crown jewel of DOMmy.js is its animation engine. This is based on CSS3 animations engine, so it works with all the major browsers. Animations are generated through the fx method, that accepts the following arguments:
- an object, representing the CSS property to animate;
- a number, representing the duration of the animation, in seconds. Default value is 5 seconds;
- a function, representing a callback that will be called once the animation is done;
- a boolean, representing whether to chain concurrent animations or not. Default is false.
Let’s see how to use the fx method, by creating two simple animations.
// simple animation $('myel').fx({'width': '300px', 'height': '300px'}, 2);
Here we simply alter the CSS properties width and height of #myel in 2 seconds. In the following example we create the same animation with a duration of 1 second and with a callback function that will edit the HTML content of the element with the “Completed!” string.
You can access the current element by using the this keyword:
// simple animation with callback $('myel').fx({'width': '300px', 'height': '300px'}, 1, function() { this.html('Completed!'); });
Chaining
You can create magic with “animation chaining”: by using true as a value of the fourth parameter, you can chain as many animation as you want. To do this, simple use the fx method more than once on a specific selector. In the following example we change the width of all HTML elements that match the “.myel” selector on multiple times:
var callBack = function() { // do something cool }; // queue animations $$('.myel').fx({'width': '400px'}, 2, callBack, true); .fx({'width': '100px'}, 4, callBack, true); .fx({'width': '50px'}, 6, callBack, true); .fx({'width': '600px'}, 8, callBack, true);
Of course you can chain everything. DOMmy.js’s structure allows you to set concurrent calls to elements:
// multiple calls $$('div#e, #d') .fx({'font-size': '40px', 'color': 'yellow'}, 1) .fx({'font-size': '10px', 'color': 'red'}, 1) .attr('title', 'thediv') .attr('class', 'thediv') .attr({'lang': 'en', 'dir': 'ltr'});
Remember that the chained calls will be executed immediately. If you want to chain something at the end of a specific animation you have to set a callback for that animation.
Create an Event Handler That Fires Animations
Now, we want to set up a snippet that produces an animation on a specific element. This animation will fire when the user moves the mouse over the element itself and when he leaves back the mouse. At the end of each step, a proper HTML content will be set:
$('myElement').on({ 'mouseover': function() { this.fx({'width': '300px'}, 1, function() { this.html('Completed!'); }); }, 'mouseout': function() { this.fx({'width': '100px'}, 1, function() { this.html('Back again!'); }); } });
As you can see, with DOMmy.js is super-easy to work with CSS3 animations. Always remember that this refers to the current element.
Now, we want to produce a chained animation that alters the CSS style of an element in four different steps, using four different callbacks and fire this animation when the user clicks the element:
var clicked = false; $('myElement').on({ 'click': function() { if( !clicked ) { clicked = true; this.fx({'width': '300px', 'height': '300px', 'background-color': 'red', 'border-width': '10px'}, 1, function() { this.html('1'); }, true) .fx({'height': '50px', 'background-color': 'yellow', 'border-width': '4px'}, 1, function() { this.html('2'); }, true) .fx({'width': '100px', 'background-color': 'blue', 'border-width': '10px'}, 1, function() { this.html('3'); }, true) .fx({'height': '100px', 'background-color': '#3dac5f', 'border-width': '2px'}, 1, function() { this.html('4'); clicked = false; }, true); } } });
You can see these snippets in action directly in the Demo section of the DOMmy.js project.
Riccardo Degni
DOMmy.js is written by Riccardo Degni, an Italian Web Developer who lives in Milan, Italy, and released under the MIT-style license.