Table of contents
Let’s take a made up slider jQuery plugin:
We load the files, and call the function. This is a rather pointless exercise I feel nowadays, and has no benefit - not to mention the drastic challenge of maintaining your plugins configuration, you’re never entirely sure what’s going on and every plugin is different!
So I’m proposing to drop this lame practice of ‘calling’ our functions/plugins, and getting more intelligent. Queue data-* attributes!
So what is data-init? It’s a way of calling your function when it exists, and also being able to configure a plugin should it have configurable options. Plugins are great for reusable code, ones that actually have purpose, but a good developer will bake this in whilst building their script(s).
Instead of this:
We do this:
If an element exists with a data-* attribute with the value of slides, it runs the function. You may think this is weird, but it’s really very sensible. I spend my days writing Object-Orientated front-end web software and this really makes a difference to productivity and reusable components.
This is great for a few reasons, we bake in the function calls to the scripts/plugins themselves so they only run when the elements required are there, which means the data-* calls are not bound to our HTML. Before, calling your plugin/script on a particular element was bound/restricting that plugin numerous times to one use, unless you called it multiple times (unproductive). Sometimes you’ll get Console errors saying things like Cannot set property X of null - which means the element probably doesn’t exist on the page. The beauty of this is that it will only fire when it exists (run the element check inside the plugin/script).
This is fine, but what about when the website scales, or you want to change your view (HTML)? If you add or change a class name, you’re going to have to add it to each, which is repetitive work and unnecessary. For a simple slider this is fine, but it’s not maintainable when you’re thinking big or HTML agnostic development.
Coming back to JSON now, let’s use HTML5 data-* attributes to define an array of images inside a JSON array. The beauty of JSON arrays/objects is that they can be manually typed (like I have below), or dynamically fed down from a server - perfect for so many use cases.
In comes JSON array of images inside an attribute (I’ve named this data-slides):
This one HTML element defines the plugins role, to initiate the slides (data-init=”slides”) and secondly define some more data to feed off, an array of images.
I can then setup a script to create an image for each item in the data-* array:
Which then outputs:
Extending JSON configurations
We could move an entire plugin’s configuration into a JSON data structure, for example, I can create a namespace for my plugin, dynamically add a class to each slide, and again loop through my array of images:
The choices are unlimited, and I don’t see why you wouldn’t do this. Alternatively, you could move the JSON configuration into the same file as the script itself too. But for ultimate reuse, we’ll be looping through the data-* attributes and running the identical function, so it’s good that the model data is bound to the view.
Real examples of why data-init
I’m currently writing some new open source projects that invoke this method of development, but here’s a real life use case. In the past I’ve used plugins that create ‘responsive type’ - aka shrink the browser and the text stays the width of the window - very nice. But here’s a huge use case for the popular FitText plugin, to be configured in the view rather than a pointless call script!
The redundant call (taken from FitText website):
I don’t know about you, but calling a plugin twice, is kiiiiinda poor development.
What they really should have done:
Immediately-Invoked-Data-Expression with data-init function calling. Remember, valid JSON contains double quotes “like” : “this”, which means you’ll want to use single quotes on your HTML.