You know what the DOM is, and if you don’t it’s easy enough to find out. What isn’t so easily discovered is the answer to this: how should your code communicate with the DOM API? Should it be treated as just another API? Is it no more deserving than, for example, a JSON web service or the web storage API?

What I’ve been seeing a lot of is the DOM becoming incredibly intertwined with the logic, i.e. the program becomes indifferentiable to the DOM. It all ends up being the same:

var counter = document.createElement('div');
counter.innerHTML = '0';
document.body.appendChild(counter);
 
function add() {
    counter.innerHTML++;
}

Where does the logic stop and the DOM representation of that logic begin?

This is a rudimentary example, and probably something that few of us would be caught doing, but I think similar things are done every day, and not just by beginners. This is normal code. It isn’t some beginner’s hack.

It wears a different mask wherever it rears its head. Here, for example, it’s under the guise of jQuery’s data API:

var alphabetList = {
    giveHigher: function(dom1, dom2) {
        return $(dom1).data('word') > $(dom2).data('word') ? dom1 : dom2;
    },
    //...
};

A shockingly high majority of jQuery.data uses seem to be making the mistake that I’ve demonstrated.

It’s subtle, not easily spotted. Right now, I’m wondering whether or not it’s acceptable.

For me, it goes against what I’ve picked up in programming thus far. I’m talking about best practices like separating your concerns and maintaining an OO approach, writing clean APIs to access your program’s logic (etc.). To me, the DOM is yet another representation of an object’s data. The data shouldn’t be in the DOM. This is how I would do it:

function Counter() {
    this.dom = document.createElement('div');
    this.n = 0;
}
 
Counter.prototype.add = function() {
    this.dom.innerHTML = ++this.n;
};

The thing is, the approach here is so ridiculously similar to foo.innerHTML++ that I really can’t tell what I’m making such a fuss over.

The feeling I get when I see foo.innerHTML++ is the same as when I see:

jQuery('div').click(function(){
 
    if ($(this).data('active')) {
        // do x
    } else {
        // do y
    }
 
    $(this).data('active', !$(this).data('active'));
 
});

… instead of:

jQuery('div').each(function(){
 
    var active = false;
 
    $(this).click(function(){
 
        if (active) {
            // do x
        } else {
            // do y
        }
 
        active = !active;
 
    });
 
});

Opinions welcome.

Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!