5 ms·
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. O
by bitwarrior 13y ago
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.
- sfeng 13y agoThis is actually a great example of the purpose of the site. Since IE8, browsers have supported a native 'sizzle-style' element querying syntax: http://youmightnotneedjquery.com/#finding_elements http://youmightnotneedjquery.com/#finding_elements 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.
- exizt88 13y agoResig on document.querySelectorAll: http://ejohn.org/blog/thoughts-on-queryselectorall/ http://ejohn.org/blog/thoughts-on-queryselectorall/ Good SO discussion on this topic: http://stackoverflow.com/questions/11503534/jquery-vs-document-queryselectorall http://stackoverflow.com/questions/11503534/jquery-vs-docume...
- tghw 13y agoIt's still more complex, because you still have to iterate over it.
- ordinary 13y agoIt sounds like you're looking for the querySelector and querySelectorAll methods: https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelector https://developer.mozilla.org/en-US/docs/Web/API/Document.qu...
- wwweston 13y agoquerySelector 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. There's others: http://ejohn.org/blog/thoughts-on-queryselectorall/ http://ejohn.org/blog/thoughts-on-queryselectorall/ I'm really not sure how the standards-makers got this so terribly wrong given that the libraries had already started to solve the problem.
- nostrademons 13y agoElements is supposed to fix this: http://dom.spec.whatwg.org/#elements http://dom.spec.whatwg.org/#elements But AFAICT isn't implemented anywhere, which makes it not that useful. Perhaps a polyfill could be done.
- lowboy 13y agoArray.prototype.slice.call(document.querySelectorAll('.myClass'), 0); Or if you want to abstract that into a utility function: function qsa(sel) { return Array.prototype.slice.call(document.querySelectorAll(sel), 0); } qsa('.myClass'); // Returns array of elements
- talmand 13y agoAnd 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.
- oinksoft 13y agoThose sort of selections are not specific to jQuery. Most DOM libraries have had them for a while, and browsers (IE8+) have provided it for some time as well in QSA: https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll https://developer.mozilla.org/en-US/docs/Web/API/Document.qu...
- drhayes9 13y agoI agree with most of your points. However, your Sizzle example is covered by document.querySelectorAll: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment.querySelectorAll https://developer.mozilla.org/en-US/docs/Web/API/DocumentFra...
- jewel 13y agoYou'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.
- TylerE 13y agoThat 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.
- deleted 13y ago[deleted]
- debt 13y ago"You might not need jquery"
- chc 13y ago> 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).
- underwater 13y agoIn 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.
- dmethvin 13y ago> 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.
- underwater 13y agoSure, 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.
- dmethvin 13y ago> 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?