I understand the desire for people to make pages like this (this isn't the first), but the examples are not completely honest with themselves, in my opinion.
One of the biggest benefits jQuery introduces is the concept of treating single selections and multiple selections identically. While using jQuery, I can emit a $(".class").hide() call, which will apply to all elements with the matching class. Simple and elegant.
However, using native JS as the page suggests, I will need to construct a loop within my function, especially if I'm using the DOM supported getElementsByClassName method, returns a pseudo-array of DOM nodes which don't have the style method available on them. You'll notice the examples already assume a selected element and leave much of this heavy lifting out.
Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.
So yes, if you're addressing the absolute simplest form of selection, this works, but otherwise I don't think it's really presenting the situation honestly.
You're certainly right. Did you see that the page specifically targets people who make javascript libraries? The page is arguing that when possible, libraries shouldn't depend on jquery, and shows how to do that for a few common idioms.
Since a library is written once and used in many different places, it's worth going to a little more effort to make it more flexible.
That sounds more like an argument for picking a canonical version of jQuery that can be cached aggressively, rather than everybody shipping a probably-buggy re-implementation of the 25% of jQuery they need.
IE9 and later also support a native each. You are correct however that you'd have to use Array.prototype.each.call, because the NodeList is not a real array.
querySelector and querySelectorAll could have been pretty great, but they suffer from some serious problems as they ended up spec'd.
The one I hate most is that qSA returns Yet Another JavaScript Collection That Is A Lot Like An Array But Isn't An Array And Therefore Doesn't Have Any Of The Nice Methods(TM). Yes, you're going to have to iterate over the thing using an index in a loop.
And now you are on the way to rewriting jQuery from scratch.
Add a few more helper functions, separate it all out to its own js file, reuse the js file in other projects, and soon people will complain about the bloated js file you keep using in your projects.
Man, I really do enjoy my chosen line of work. It creates such fun things to debate over.
> However, using native JS as the page suggests, I will need to construct a loop within my function, especially if I'm using the DOM supported getElementsByClassName method, returns a pseudo-array of DOM nodes which don't have the style method available on them. You'll notice the examples already assume a selected element and leave much of this heavy lifting out.
You don't really need jQuery for that, though. You just need a forEach-like function that works with NodeLists. This is easily implemented in three lines of JavaScript.
> Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.
Not since IE8. These days, you can just do document.querySelectorAll('#div .container .item'). For most common selectors like the one you showed, Sizzle ends up delegating to this method anyway. You only need Sizzle for selectors that cannot be expressed in CSS (e.g. "select a UL with only one child", which would require the CSS4 ! marker).
In practice a better approach would be to build up a micro-library of functions to just implement the small subset of features you do need.
// Using underscore/lo-dash and ES6.
_.forEach(document.querySelectorAll('.class'), elem => elem.hidden = true);
// Building reusable utility functions
function forEachSelector(sel, cb) { _.forEach(document.querySelectorAll(sel), cb); }
function hideElement(el) { el.hidden = true; }
forEachSelector('.class', hideElement);
Of course, there is the danger of ending up with homegrown jQuery that is less well tested and less well thought out. Perhaps there is a place for a small JS library that works with native DOM elements, in the same non-invasive way lo-dash and underscore work with data structures.
The problem with jQuery is that it's an all-or-nothing approach. The way it wraps native DOM nodes means it keeps trying to pull you back to using its inbuilt utility methods.
> The problem with jQuery is that it's an all-or-nothing approach. The way it wraps native DOM nodes means it keeps trying to pull you back to using its inbuilt utility methods.
Not true at all. You can do a custom build and leave out things you don't need. You can even leave out stuff you DO need and replace with your own simpler shim. See the README file.
Sure, it's technically possible. But not common from the projects I've seen.
The APIs seem to be designed with the assumption that all your code will be using jQuery. For example converting a wrapped node to a native DOM node requires an extra call that, in my opinion, is ugly: $('.something').get(0); and could be considered to be an anti-pattern.
I don't think this is a bad thing. jQuery does a good job at providing a DSL that replaces native DOM access. But if you want a library instead of a framework its strongly opinionated style can be off-putting.
> The APIs seem to be designed with the assumption that all your code will be using jQuery.
Again, not true. For example, the `this` in an event handler is the actual DOM element, not a jQuery object. Whether you handle that directly with DOM methods or wrap it with `$(this)` is up to you. Many people prefer the latter but the former is often smaller and prettier.
> For example converting a wrapped node to a native DOM node requires an extra call that, in my opinion, is ugly: $('.something').get(0); and could be considered to be an anti-pattern.
How common is that, really? Your example assumes a single element with that class name. Why not chain a jQuery method behind it and handle the 0 or N cases as well?
Or even better, if you're only selecting one DOM element that doesn't need the jQuery wrapper, then don't use jQuery for that one case. There's nothing that prevents doing that even if jQuery is being used for other elements in the project.
Just because jQuery is loaded doesn't mean you have to use it for everything on the page.
One of the biggest benefits jQuery introduces is the concept of treating single selections and multiple selections identically. While using jQuery, I can emit a $(".class").hide() call, which will apply to all elements with the matching class. Simple and elegant.
However, using native JS as the page suggests, I will need to construct a loop within my function, especially if I'm using the DOM supported getElementsByClassName method, returns a pseudo-array of DOM nodes which don't have the style method available on them. You'll notice the examples already assume a selected element and leave much of this heavy lifting out.
Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.
So yes, if you're addressing the absolute simplest form of selection, this works, but otherwise I don't think it's really presenting the situation honestly.