Table of contents
- Reuse and the problem scenario
- Behavioural [data-js] binding
- Creating a Module and public API
- jQuery and selector vomit
- Data attributes and performance
- [data-js] JSON/Obj literals
- Data-binding JSON (highly experimental, for reading only!)
- Food for thought
A while ago I wrote about
data-* selector and not targeting an element. I’d experimented with it a few times and it often got a bit sticky when it came to modularity - I was repeating a lot of code and the implementation was 90% there, until now. I’ve finally began to see the clearer picture on the behavioural-binding and feel like it’s worth sharing.
I’m going to show you how to:
- Drop selectors for behavioural-binding in the DOM
- Rant a little about jQuery
- Go away feeling modular
The behavioural-binding concept is binding repeating behaviours to DOM elements, instead of selecting elements and manipulating them. In a sense, it’s what you’re not used to doing. Probably:
Previously; you targeted an element, wrapped it in a function and did some DOM wizardry.
data-* attributes. The implementation is quite similar, but the thinking behind it is the separation key and how you’ll need to think ahead for all future elements and not tie your JS so closely to your HTML. Behavioural-binding doesn’t care what element it is, it’ll just do its thing (if it’s a valid method).
Reuse and the problem scenario
I want to autoselect the text inside the input as soon as my cursor is focussed on the input, very simple.
But uh oh, I’ve got three different classes, s**t.
Now any (hypothetical) code is ruined because it only took into account
autoselect class to each of them?’. No. Just no. Classes are for styling, we’ve established this previously - I want to bind behaviour, not classes. So…
Behavioural [data-js] binding
So how do we tackle the problem with applying the same logic to multiple elements without modifying our scripts everytime we extend them? I just want to write logic once and let it do the same work regardless of the element’s identifier.
You can then use a selector like so to target these inputs:
This returns a NodeList of the exact inputs I need. Now I can do the following to bind a click event:
Perfect! And we’re all done.
Wouldn’t it be better to make the
data-js value dynamic for ultimate reuse? Yes! Here goes:
Now we are thinking dynamically, that’s the first step. This means we can pass in more arguments to get other
data-js attributes, for example:
Creating a Module and public API
data-js modularity even further.
I’d like to be able to write a bunch of code that is fully dynamic, that doesn’t rely on selectors inside it, but gets the data from outside the scope. In true module fashion, we could do this:
And that’s it. This is the type of stuff that would be called on DOM Ready inside a pair of
<script> tags or whatever your setup allows. I’ve created a Module that has a ‘select’ method, in which I pass in the ‘select’ attribute (ignoring the
data-js part) of the selector as this is already setup.
Here’s the example module setup I’ve created (notice there is nothing DOM related in here, awesomely agnostic!):
You’ll see I’ve got my
datajs selector wrapper, a function called select (
var select) which handles the NodeList looping and event binding. This is a Module Pattern with a revealed API, often named the Revealing Module Pattern. In short:
Why do I like this? For starters it creates a consistent namespace for all
data-js modules, of course I can rename my
Module to whatever I like though. It also promotes exposing only functions you need which keep private functions safe, but most importantly, you don’t have a single selector in the script at all - just the
data-js prefix that we’ve established is well needed.
jQuery and selector vomit
I’ll call it selector vomit, because I’ve seen this so many times:
Let’s aim for a cleaner future.
Data attributes and performance
‘But getting an element by ID is faster’. Getting by ID is old and not modular. Some 1970s cars are faster than today’s ones but I know which one I’d rather drive - faster isn’t better. Data attributes were added to the HTML5 specification for a reason and they should be used powerfully - a.k.a by writing as less code as possible to do some awesome stuff.
[data-js] JSON/Obj literals
How about passing in object data into our module? Here’s how we could fully extend the DOM with no selectors inside our core script:
Data-binding JSON (highly experimental, for reading only!)
I also have experimented with thrashing a few ideas out with JSON inside
data-* attributes to fully configure the DOM and do crazy stuff with, it can be classed as a little close for comfort with regards to the separation of concern - but I think it’s got some possible use cases and potential grounding for the future and dynamically creating elements and setups, here’s an example:
Food for thought
I hope you’ve been a little intrigued at least from this article and what it presents, if so, here’s some things to remember for future coding to aim for:
data-jsattributes and appropriate values for DOM selectors
- Start to structure functions a little better using the (Revealing) Module Pattern where necessary
- Separate behaviour from style