In the previous post about jQuery we saw how this framework can be CPU consuming. In this post we’ll explore the programming model resulting from the jQuery API.
The jQuery API is simple to use:
- You first write a CSS selector. You get a set of DOM nodes matching this selector ;
- Then you apply functions to them (e.g. you attach them an event handler, or append an element) ;
- That’s all.
This way of programming is very concise and conciseness is generally good, so what’s wrong with that?
The first issue raised by this programming model is that, as every DOM elements are wrapped in a jQuery object, that’s not straightforward to use the native DOM API. Compare how the “Next” button is disabled with jQuery:
and in Vanilla:
In this case, the Vanilla code is even more readable! (Ok, I must admit that the native DOM API sometimes sucks, using very long method names such as document.findElementsByTagName
, so not using it is not always a big frustration).
The jQuery programming model allows to easily add complex features to a page (e.g. opening every link to an image in a nice Fancybox with a simple line of JavaScript). But this same programming model is kind of viral because once you have wrapped your nodes in a jQuery object you can’t use another API on them than jQuery. Actually you could still get the underlying DOM elements, and then use their native API, but by doing this you could not go back to the jQuery API (unless you re-wrap them in a jQuery object!). So in the end you have to make a exclusive choice: using either the jQuery API or the native DOM API (as well as any other API working on native DOM elements). Hopefully, jQuery partially reinvented the wheel (understand “jQuery partially reimplemented the DOM API”) so using it you can do almost all possible things you could do with the native DOM API.
But did jQuery need to adopt this programming model? Why is it not possible to simply mix native DOM API with jQuery API, like in the following imaginary snippet?
As you see jQuery could have offered a better API with no viral nature, thus not requiring to reimplement the native DOM API…
If you look carefully at the snippet, you’ll see that almost every jQuery call could be replaced with a (modern) native DOM API call. The $.find(element, selector)
function could be replaced with element.querySelector(selector)
and the $.click(element, callback)
function could be replaced with element.onclick = callback
. That’s another remark about jQuery: it was very useful (not to say essential) several years ago, when the DOM API was very poor. But nowadays this API has evolved into a very more usable shape (and is still being improved) and the value added by jQuery is lower and lower. Actually, jQuery is just useful to ensure compatibility with old browsers.
The second issue resulting from the jQuery programming model is that you are encouraged to scatter your selectors every line and again in your code. That’s a very bad thing because it tightly couples all your JavaScript code with the HTML structure and makes it very vulnerable to any markup change: if one day you decide to change something in your markup then you may have to adapt your selectors which may be located at different places in your code.
Well, what did this post point out?
- The jQuery programming model is viral and forces you to choose between plain old DOM elements and the wrapping jQuery object ;
- Most of jQuery features are now already covered by the native DOM API ;
- Scattering selectors anywhere in the code is difficult to avoid, making this one very vulnerable to markup changes.
In the next (and last) post, we’ll go deeper in the programming model and see why, as well as tightly coupling the JavaScript code with the markup structure, the jQuery programming model does not help to structure the code following a MVC-like architecture pattern.