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.
The premise of the examples list seems a bit disingenuous.
Very few of these things take into account the full convenience of jQuery. It's much more than saving a couple lines of code or knowing the native way to accomplish the most basic version of a task. jQuery's real benefit is preserving simplicity as your needs grow more complex.
Right off the bat I feel like the getJSON[1] example is a bit simplistic. Almost anyone using ajax needs to serialize data, handle errors, prevent caching, etc. jQuery has thought about all this[2].
Don't get me wrong -- most of my work has been without jQuery, but that means I know exactly how much work it is.
The Good:
The format is a nice way to show people (who really don't know otherwise) the native JS plumbing.
"The number of people who don't know that jQuery != Javascript is too damn high". So to help combat that, I really appreciate the idea behind this site.
It's great to show side-by-side how jQuery isn't "magic", since many people seem to learn jQuery these days without even knowing the first thing about Javascript, but I just think it should be presented with a slightly different premise.
[1]: http://youmightnotneedjquery.com/#json -- side note, why did they set the handler after the `send`? It seems like that could cause problems if the result was returnable quickly, such as from cache, though I haven't tested it.
That's a great point - this is really awesome as a "learn the essence of what jQuery is doing for you!" and a little annoying as a "you don't need jQuery!".
I took the tone as being directed to people publishing plugins that use jQuery for 1% of its functionality, forcing people not using jQuery to either not use that plugin, rewrite the plugin or include jQuery.
Edit: it actually literally says it's for library developers.
For 1, I was wondering about that too - it seems like such an odd thing to do. Who knows what the latest JIT-y stuff and cached responses could do to how fast things run? Just set it before you send, like any normal developer would, and get rid of the need to worry about it.
No, quirks mode is triggered by the developer not including a doctype. If you include a properly formatted doctype, you will have JSON support in IE 8.
>post-IE8, browsers are pretty easy to deal with on their own.
False:
- CSS browser prefixes are automatically inserted by jQuery
- Many jQuery selectors don't exist in the CSS selector specification
- Looks really really ugly and that makes it hard to read for you and other coders.
var pairs = $(".form").not(".old").serialize();
/* without jQuery */
var pairs = [].slice.call(document.querySelectorAll(".form"));
var data = forms.filter(function(ele){
return /\bold\b/.test(ele.className);
}).map(function(ele){
var form = ele.querySelectorAll("select, input, textarea");
var pairs = [].slice.call(form).map(function(subele){
// maybe if subele.type === "select"
// but I got tired of writing this example
// but that's the point anyway
return subele.name + ":" + (subele.value || "") + ";";
});
return pairs
}).join("").replace(/;$/, "");
So be kind with your co-workers, use jQuery. Even my 5 year old android can run jQuery without freezing the built-in browser.
> Looks really really ugly and that makes it hard to read for you and other coders.
This point might have been better made if you hadn't intentionally structured it to be as unreadable as possible, and also shoved in a few lines of comments to pad it out and make it look bigger than it needs to be. Not a very honest example at all, considering native JS can be as readable as you want to make it.
> So be kind with your co-workers, use jQuery. Even my 5 year old android can run jQuery without freezing the built-in browser.
My co-workers can read and write native JS with or without jQuery as it is, why is it being _kind_ to avoid writing in the style of the native language?
Expressiveness means you waste less of people's time and mental effort.
$(".enemy").after('<div class="crash">').remove()
Without jQuery:
var enemies = document.querySelectorAll(".enemy")
for (var i = 0; i < enemies.length; i++) {
var div = document.createElement("div");
div.className = "crash";
enemies[i].parentNode.insertBefore(div, enemies[i]);
enemies[i].parentNode.removeChild(enemies[i]);
}
Here the last one is comprehensible but even then, it takes longer for a programmer who just found it to figure out what it is doing; and, caring about other peoples time (and future yours) can be referred as 'kind'.
First off, when using jQuery you are still coding in the native language.
Second, the many debates that have happened on HN it is quite clear there is no set "style" in coding Javascript. My style of coding in the native language may be quite different than your style. Therefore, if you use your style in a verbose manner because you choose to not use jQuery and I use my style in a more concise manner because I am using jQuery, it could be said the more concise method is kinder to someone following behind.
But like all things considered a style, opinions vary.
No, please no. If size is an issue for some reason or you want to have no dependencies you can use something like http://zeptojs.com/ and just embed everything in one minified file. If you do things right only the functions you are actually using will get placed in there as well.
Do not reinvent the wheel to solve problems that can't be solved in much cleaner and nicer ways. Managing dependencies can be annoying, but we all bite the bullet for a very good reason, because reusing solid well tested code is a good thing.
I believe the point is that many libraries use about 1% of jQuery. That hardly justifies pulling in the entire thing.
A personal anecdote: I recently un-jQueried a little piece of code and ended up with only a couple lines of extra code.
Certain parts of jQuery are heavenly and well worth it, but really basic usage doesn't actually save that much. $("#something") instead of document.getElementById("something") is not really buying you much in the way of cross platform-ness or thoroughly debugged code and is hardly reinventing the wheel.
Considering XMLHttpRequest is what other browsers used before IE caught up, I assume it does work the way you'd expect across modern browsers. I'd have to check the standard and IE8+'s conformance to the standard to be sure. That's what this post is really about for me, reminding that modern browsers follow a standard that allows for getting rid of most of jQuery. Reading it also made me recall a post from 2005 by PHP's creator: http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX... (Note IE uses ActiveXObject.)
As I recall, they specifically implemented it in order to facilitate Outlook’s web interface – their collective regret may be tempered by the satisfaction they got from all those high-margin site license sales to which that feature contributed.
For me jquery is all about events. Making sure I get the event tree bubbling in the correct way across the entire universe of browsers and all its data being normalized is such a time saver. Even their support isn't perfect, but I'm sure its way better than any other event library out there in terms of breadth and depth of testing. The selectors bit is a nice to have, but that is getting easier since its inclusion in dom itself.
Since I code mostly in clojurescript in my home hours any functional idioms from jQuery I no longer use. A long time ago jresig joked about making an oo form of jQuery. It's not that funny now, as it might be slightly easier to wrap an object based lib for all the various compile down to js languages (typescript, coffeescript, clojurescript, scalajs, etc)
About one year ago, I developed a shared widget. Some fraction of my clients refused to load jQuery, as they still preferred older, less popular DOM libraries.
Starting with jQuery's battle-tested event handling code, I trimmed features unnecessary for my widget: event.data, IE7 support, consistent focus events. I replaced jQuery's indispensable descendant selector feature, formerly jQuery.delegate, with a simple conditional in my event handlers. (e.g. Walk parentNode references from event.target, looking for a class name.)
I was left with about 75 lines of code in my DOM abstraction library. I preserved jQuery's tricks for Microsoft's attachEvent and Safari's text nodes. About 15 lines were dedicated to normalizing attributes. My polyfills for preventDefault and stopPropagation were about 10 lines each.
It's amazing how far native DOM has come in recent years.
If you are looking for a standalone event (delegation) library check out one I wrote http://craig.is/riding/gators. The syntax is very similar to jQuery.
1) The minified jquery script is ~100kb, for a script that is loaded once per website that's pretty tiny. Especially when you consider the fact that the latency involved with opening the network connection to fetch the file will likely exceed the time required to pull the file down. Once you've initiated the download the difference between pulling down 20kb and 100kb isn't all that much.
2) You can use the google jquery file reference. That means a big % of your site visitors will already have the cached script in memory, and for those that don't the download will be pretty speedy given that it can be fetched from the google domain in the background (while the rest of your site assets are being fetched by the browser).
You think that a page that loads jQuery but doesn't use most of it incurs a performance penalty? I'll grant there are a few initializations and dom checks that jQuery does, but it probably blocks for all of 20ms.
Most modern browsers are able to paint while loading script files, especially if you put your script files at the bottom of the page, where they belong. So, no, 20ms of parsing, compiling, and a small amount of execution is not a lot of time. Period.
> I believe the point is that many libraries use about 1% of jQuery. That hardly justifies pulling in the entire thing.
Sure, but if you use a few libraries that all use a couple features of jQuery you still only need to load jQuery one time and everything just works. You may not care if it only works on the most modern browsers, but someone who uses your library probably will.
In practice, especially for javascript usage, the old CSS selectors cover all the bases.
The new-stuff, while great for styling, isn't all that relevant for scripting. nth-child, say, is often (though not always) simply an indexing operation on the return value of querySelectorAll; and in general you don't even want that since usually you have a specific element in mind and have labelled that element with a class to find it.
I don't support IE8 anymore, and use CSS3 liberally in the actual css, yet I can't think of more than a handful of cases I used the selectors from javascript, certainly none of them critical. Do you actually use this?
You lose some browser compatibility with qSA, whereas gEBId works everywhere. You need IE8+ for qSA, and you need to ensure the page isn't in quirks mode. If you're OK with that then you can also do: var $ = document.querySelectorAll.
Probably best to do this within a closure so that you're not hijacking any jQuery instances that may be on the page.
1) Zepto is POS. It offers the illusion of jQuery compatibility while delivering only maybe 80% of it. You simply cannot reverse-engineer something 100% without doing everything the original does, so you might as well use jQuery.
2) In 2014, jQuery feels like it is the wheel reinvented. I'm looking at the jQuery API modules now and here's what I consider jQuery is still useful (as in nontrivial to replicate):
- AJAX (Too many cross-browser differences in XHR/XDR implementations)
- Event delegation (Too many cross-browser differences in what gets triggered/bubble/cancelable)
Most things in jQuery may only save you a couple of keystrokes to a few lines of code. For everything else, you can drop in a small library / polyfill when needed to get back something like $.Deferred or the $.fn.serialize() or $.fn.val(). In fact, there are already many small libraries that aim to do just one thing only and do it well.
3) You never need all of jQuery. If you need all of jQuery, you are doing it wrong. I don't even want to look at your giant pile of procedural, chained-20-times-for-every-element hourglass-shaped callback pasta.
4) The plugin ecosystem is horrible. This might have to do with the fact that jQuery doesn't give you any help other than a namespace. Most plugins come with ginormous pile of options and/or very rigid and opaque HTML/CSS structures. Most of them don't come with tests, are extremely buggy and very very hard to tweak.
5) jQuery is extremely slow. Its slowest parts are creating the context because of Sizzle and event delegation. My recent PR for Backbone to make jQuery optional in its View is around 70% faster using all native DOM methods.
6) jQuery was born in 2006, when IE6 still had 70% of market share. jQuery's many layers of smooth-overs come at a very high performance cost, and it doesn't even smooth things over that well. There are still many edge cases in event handling such as triggering a click that bubbles on a detached element on Webkit that jQuery just can't do for you. Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?
> jQuery was born in 2006, when IE6 still had 70% of market share. jQuery's many layers of smooth-overs come at a very high performance cost, and it doesn't even smooth things over that well. There are still many edge cases in event handling such as triggering a click that bubbles on a detached element on Webkit that jQuery just can't do for you. Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?
Ignoring the Webkit example and focusing on IE, isn't that what jQuery 2 is for?
Nope. jQuery 2 just removed code for IE 6/7/8. Nothing was added. Code sized reduced, but almost the same performance. My benchmark shows only 10-15% improvement. That's nothing compared to using the DOM API straight up.
Hmm, I'm wary of a test that involves another framework to test the underlying jQ v. Native DOM performance difference. I'd be much more comfortable eliminating Backbone from the equation.
Also, this is just one test - wyuenho's claim was for jQ vs. the DOM in general, which is a much broader claim than an unknown subset of functionality.
I don't doubt that native DOM methods are faster than jQ, but I like claims to be backed up by evidence.
See my previous comment[0]. That perf test is testing Backbone's use of jQ vs. native DOM, not jQ v. DOM in isolation. I don't trust that there aren't side effects and interactions in the test.
>> Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?
In my experience, this decision is not as cut and dried as you make it seem. But I don't work for a startup, so take that for what it's worth.
I love the idea of removing Backbone's jQuery dependency. If I could use Backbone without jQuery, I would gladly leave jQuery behind.
For my use case, Backbone would also have to lose it's jQuery dependency for RESTful model persistence, but maybe that means I should get to work on it and submit a PR :-)
jquery is really just an abstraction for dom, it is not an api for application building. When I have to use the dom, I definitely turn to it. I'm not sure why people object to having additional helper functions in jquery for a measely 100k or so.
You don't have to use plugins you know, its not a law.
Whether 100k is huge or not depends on the project's requirements. In some cases it's perfectly fine, in other cases it's a problem. Such a broad statement cannot be supported.
Much the same; even if jQuery is that much slower it can sometimes provide something that overcomes the slowness factor. It varies from project to project. Especially if the project scope practically requires you to rewrite jQuery from scratch, you might as well use it.
100k is huge, period. Whether or not a huge dependency is acceptable depends on the project. Yes, we know it depends on the project, that was the point of the site. The whole point is "if you are making a library, and don't really need jquery, please don't force that extra dependency on users of your library".
Fantastic point. Abstractions can be dangerous because they often aren't developed right.
But that isn't the case here. When something like jQuery comes along, hiding so many gory details, and has been tested to death both in development and in production use all over the world, we are all better off because we remove so much failure surface area from our code.
As near as I can tell, browsers are already at least sometimes caching compiled representations of JS; the win from shipping specific versions of jQuery would be minimal, and not work unless you used specific CDNs anyhow.
are you serious ? thats actually a good example on why you should use jquery.
First of all the dev needs to know exactly on which platforms he will run into problems and how to solve them...And what if you need not one but several polyfills ? That gets messy pretty quickly.
Ah no. First of all, you should always know which platform you target and what works and what don't work on those platforms, even if you are using jQuery. jQuery is not perfect. Platform specific corner cases are still exposed to you.
What if you need several polyfills? Drop them in too. You should always know what browser feature you are using. The same argument goes for using libraries. What if you need more than jQuery? Bring them in too. There are asset pipelines and/or pure front end packaging solutions like AMD to help you. What's the problem?
> You should always know what browser feature you are using.
Why? If I just drop jQuery in and treat that as my API baseline, what do I lose? A little performance, a few hundred kilobytes' download (almost certainly cached from a CDN anyway). And it frees me up from remembering a bunch of corner cases and keeping track of a bunch of implementation details, letting me focus my attention on more important things.
You can certainly use JQuery as your API base if you're willing to take the hit on performance and a few hundred KB download, and are willing to take that hit on every project you write.
The problem is that this shuts you out of a lot of hot, emerging markets that can be quite lucrative. You will never work for Google (as a front-end engineer) if you only know JQuery and not the native DOM APIs. Your mobile HTML5 apps will suck and will lose out to native counterparts in the app store. You're at a disadvantage in any competitive web market where people bounce from the website if it's too slow (there are more of these than you think).
If you're willing to limit yourself in this way, sure, go for JQuery. There is still a pretty booming market for Intranet apps or progressive-enhancement mostly-static sites where JQuery is just fine, and it provides a nice productivity boost for those use-cases.
The advantage of polyfills is that they give you flexibility and let you push the edge of technology today, and then they don't become obsolete tomorrow. As the web evolves you just get rid of the polyfill and you already know the latest & greatest of tomorrow. That lets you push into the emerging new markets that can be quite lucrative, at the expense of actually learning the (sometimes hard-to-use) APIs on the bleeding edge.
That makes a lot of sense especially in areas where you are competing for people's attention. If you aspire to being a front-end engineer it'd be silly not to know the DOM APIs inside and out, especially now that browsers have such nice dev tooling.
But for those aspiring to create big things another approach is to find a niche where you can offer something exclusive that people want. Thefacebook offered something that students would have put up with > 1s load times to see that they couldn't reliably get anywhere else. http://en.wikipedia.org/wiki/File:Thefacebook.png
The point is, jQuery doesn't free you up from remembering lower level details, they are still there in your face all the time, especially when it comes to event delegation and handling. jQuery also doesn't help you with CSS, which is even more of a pain than DOM inconsistencies. The whole point of polyfills is to patch browser incompatibilities, often times without losing any performance to newer browsers, so you can provide the best experience to half the people in the world on newer browsers and a mediocre experience to the rest, instead of a mediocre experience for everyone. If you care about attention to details, you should understand what your browser is doing. Polyfills are things that you only have to learn once and drop in once. Isn't providing a good experience one of the more important things?
Actually, jQuery can help with CSS inconsistencies, much the same way vanilla Javascript can, if you have the mind to use it that way.
You seem to be laying much of the "mediocre experience" on jQuery in this case. I would like to know why you feel this way. Seems to me that loading in polyfills for every browser inconsistency can lead you to the same problems you feel exist with jQuery.
I don't just care what my browser is doing, I care what all of them are doing; which often leads to using jQuery. Depends on the project and the number of expected browsers involved.
Polyfills are things you learn once and drop in once? So is jQuery.
What if the best experience to be provided suggests using jQuery? Would you use it?
All in all, to use or not use jQuery often depends on the project. If it fits, use it; if it doesn't, don't use it.
And style.display='block' for jQuery.show() does not work with <tr>'s (which need 'inline-block') and rules which have an !important clause in the CSS (which need to first set the display to empty string and then set it again).
Size really is issue when dealing with mobile devices. Even from disk cache each KB increases startuptime by about 1ms (and jquery 2 is ~32kb minified, for < 2.0 lot more). Over cellular connection you can nicely multiply each KB by 100ms. This is even worse when you minify and concat your JS library dependencies, as most likely your cache headers expire way too fast for them. If you have bothered to set them at all.
Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy*". This might not be issue with desktop machines, but you will probably lose most of your mobile users because of that. Jquery does also exposes very dangearous things from the API. For example: most of the time use of css modifying from JS just implies that your UI logic is fundamentally flawed (also, incredibly slow as poking CSS from JS will force full relayout which will make your mobile users throw their devices to wall or leave your site).
Jquery lets people cut corners which will give short term benefits, true. But in long term you are just killing your user experience. And like others said, people mostly use like 1% of the API, which has as easy native browser support.
The speed difference between querySelectorAll and getElementsBy* is entirely because of the difference between live nodelists and static nodelists. getElementsBy* returns a nodelist that reflects changes in the DOM in real time - this means that it's just returning a pointer. querySelectorAll copies the full result set into an array-like object at method-call time.
The flip side of this is that iterating over a querySelectorAll nodelist is significantly faster than iterating over a getElementsBy* nodelist. You really don't want to call .length on a getElementsBy* nodelist, because it's O(N) and has to traverse the full nodelist. .length on a querySelectorAll nodelist is just a field lookup. That means that when you combine the original call with one iteration, you're usually about breaking even with querySelectorAll.
Also, setting CSS properties doesn't for a full relayout; it just sets a dirty bit and the property. Setting CSS properties and then querying the DOM causes a full relayout. Unfortunately JQuery often does the latter in .css, which makes it slow as molasses. You can do direct .style manipulations all you want with very little performance penalty though.
> Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy*".
Not true, and has never been true; maybe you confused jQuery with Zepto? "#id" uses getElementById, ".class" uses getElementsByClassName, more complex selectors go through querySelectorAll, and custom selectors through Sizzle.
> And like others said, people mostly use like 1% of the API, which has as easy native browser support.
Hard to argue with that statistic since it's made up!
> Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy".
I seriously doubt you ever "checked". You would know that jQuery's selector engine (Sizzle) is optimized and uses getElementBy* when it can. You would also know that every browser has bugs in querySelectorAll, and jQuery's selector engine detects the bugs and routes around the browser bugs.
How complicated your query have to be to run into these QSA bugs? Don't forget that you are paying a very high performance cost for compatibility. I mean, how many people are still on Chrome 21 and Firefox 3.5?
jQuery might use querySelectorAll for its selector, but also looks for basic patterns and optimizes them by using things like getElementBy* eg. $("#test") will use getElementById behind the scenes, not querySelectorAll.
In most cases where you have any level of complexity, you are better off using jQuery or some other already tested out libraries. That being said, blanket statements about technology choices are suspect because every project has different needs and requirements. You should evaluate things on a case by case basis.
If you're creating a simple brochure website for a small business and literally just need to show one hidden element on a click or do something else very simple, there's a legitimate argument to avoid jQuery. It depends on the level of complexity you need.
The web is filled with unnecessary bloat and I'd like to get rid of some of that.
It's better if libraries don't just assume jQuery is everywhere, because I suspect those days are ending. Apps built on newer front-end frameworks like Angular and React might not need it, for example.
As a library author it's becoming more important to think case-by-case -- use raw JS if you just have some simple selections or XHRs, or use Zepto/etc if that covers you, and only depend on jQuery if you really need its richness in your lib.
If it's just a general library to use anywhere, then sure build it with no dependencies.
But if it's a library intended for Angular then the library would be built with Angular as a dependency, much like it would be with jQuery.
I don't see a negative with a library being built that has dependencies if it is intended to be used in conjunction with the thing it is depending upon, since in most likelihood a like-minded developer is already using it.
You do realise zepto works in IE10+ only, and even then you need an additional module for support. I wouldn't say it's worthwhile. It is not a viable alternative.
I'm working on a widget that other people will embed on their page. I cannot make assumptions about jQuery being available and I cannot afford to add jQuery as a dependency. Assuming the widget was valuable to you, would you want to add my widget to your page if it included 94kb (jQuery 1.10.2 minified) of JS before my code was even added on top? If you cared about performance, it's highly unlikely you would.
So for that reason I've been working with plain JS for months now. We have browser support back to IE9 (maybe even 8), and our entire codebase is around 25kb minified (gzipped < 6kb). We have one or two collections of utilities, but most of it is application code that would still be there even if we had jQuery as a dependency. All I can say is it is not that big a problem. If you're not sure how to get something to work across browsers, look at the source of jQuery (this website [0] is fantastic for this purpose) or any other library that is well regarded.
But you know what? Most of the time it isn't even a problem. And with modern tools [1][2] and a good test suite, it's not difficult testing across multiple browsers to quickly find issues.
Before even working on this project I decided to go on a self-administered "jQuery diet". I haven't used jQuery in any personal projects [3][4] for at least a year and it's great. It took a little adjusting, but not much. If anything it was a little shocking. I thought I was a good JS dev, but it really opened my eyes to how little I knew about the DOM and other native browser APIs and, honestly, I felt a little ashamed.
Conclusion: sometimes going it alone is the right decision. jQuery is absolutely the right choice in some environments, but it doesn't make it the right choice absolutely
No thanks, I'll take something that I'm sure 99% of web developer know by heart and works cross browser. I don't want/need to spend hours upon hours writing "clean" code that doesn't use jQuery. I have business problems to solve.
Abstractions are meant to, well, abstract an implementation. You might very well want to abstract a native operation for a bunch of different reasons. You don't need to, but maybe you should.
For example,
$(el).hide()
is quite more readable than
el.style.display = 'none'
. And I'm not even talking about the other advantages.
" it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar"
You wont have $.contains, instead $(el).children(child) returns a chainable filtered list of the first level of child nodes, or $(el).find(child) will go down recursively.
jQuery rarely dumbly duplicates some native functionnality, as for the example above, most of the time it will diverge in meaningful ways.
These two new functions you mentioned are both in the article linked to above. 'el.children' and 'el.querySelectorAll(selector)' are given as alternates. It is true they aren't 100% the same but JQuery isn't different enough in my opinion for there to be any clear reason to use it instead of what is already available.
As a side note, I know this is totally a matter of taste but "chainable" in the JQuery sense reads to me as "spaghetti generator".
> As a side note, I know this is totally a matter of taste but "chainable" in the JQuery sense reads to me as "spaghetti generator".
I think this is more important than a side note. The reason jQuery's 'children' or 'find' is way better in my eyes is because of the support for arrays as target and argument, and the possibility to pass the resulting collection to the next command as is.
Going the native route, filtering the children will need an extra loop, doing so on an array of parent elements will also bring an other loop. And we'd have to deal with a Nodelist instead of an array. A 2 command jQuery line would be 5 to 10 lines in native code, every time there is some node tree to filter.
Manipulating collections of DOM elements is such a common case that having to deal with loops every time is just tiring, less readable and more prone to basic errors.
In a way I see it as an anti-spaghetti feature. Less boilerplate, shorter, more concise code with clearer intents.
My side note would be that el.querySelectorAll(selector) is versatile, but not as much as the jQuery find. Telling which cases for which browsers would not work with the native function could be some interview question, but that's not the kind of thing I'd like to remember.
It's not, but then you fall on IE9+ land, and you'll have to check if querySelectorAll returns anything first.
The sibling comment points out how a function silently failing when given empty value can be deceiptive. I guess your way of seeing it would be also in line with checking valid values before using them.
It's a very sane approach, and it requires more care and attention for each step. I'm not against it, but usually I'm not sure to see a real payoff for very conservative programming in front end DOM manipulation, I tend to prefer taking some performance hit and ignore the nitty gritty details as well as the small errors, as long as it can be recovered at a higher level.
> Do not reinvent the wheel to solve problems that can't be solved in much cleaner and nicer ways. Managing dependencies can be annoying, but we all bite the bullet for a very good reason, because reusing solid well tested code is a good thing.
This.
A thing that the examples on that site did not address is the power of jQuery("element.selector") selects a "bucket"/array of elements and functions are executed on each element in that bucket.
So now you may have to add that functionality into your library.
Then there is always a non-logical browser inconsistency that needs to be taken care of. Then you need to write tests.
Time used for managing the library piles up very fast.
We have a challenge in that so many of our web applications are built in a way that prevents us from performing analysis across technologies. For example, a modern rails app will possibly include haml, sass, coffeescript, and ruby along with the usual html, Javascript, css, etc., that are included in the various gems and plugins.
There are a lot of ways to skin this poor cat, but at this time they are generally manual and therefore unused. As a result, we try to solve dead code problems as if it is an entirely new challenge.
Dynamic code, and especially code with insufficient test coverage, poses a particular challenge, but again, it is generally possible to instrument code to see if it is ever called by the application.
Its not about reinventing the wheel. Its about being open minded. jQuery is great, and if you are going to use zepto, you might as well use jquery 2.0
But it doesnt hurt to understand how basic stuff works under the hood of jquery and to know native dom operations. The world is not black and white. Good developers know that, they dont get stuck in discussions whatever jQuery should be used everywhere or nowhere.
This response is quite strange in my eyes, because the website doesn't invent anything new, it actually says to use less bloat, which is always a good thing. Why use a well tested function if you can completely get rid of it?
And yes, less code, less abstraction, and less requirements are damn good reasons not to do something.
You're right in principle, but Zepto is a horrible recommendation because it gives the middle finger to anyone on IE < 10. I was originally designed explicitly for mobile browsers, so it makes sense, but it means it's rather unfit for the majority of businesses.
What would be awesome is if jQuery had the same kind of download builder as jQuery UI, so that you could only include the parts of it that you actually need for a library.
Greenspun's Tenth, updated for 2014: "Any sufficiently complicated website contains an ad-hoc, informally-specified bug-ridden slow implementation of half of jQuery"
I understand the visceral opposition, but once you start writing a fallback to support some browser (something to support IE or FF or Safari or Chrome ...) you might as well use the battle-tested solution (and write your own thing if you find performance to be unacceptable and trace the bottleneck to jQuery)
And the followup is, when do you remove fallbacks from your code? Every time I think I should remove something I end up thinking, "well, it still works just fine, does it really matter if it stays for a little longer?"
The cost is in latency and complexity for users of your head browsers. How much do you want to reduce the user experience of your users on modern browsers to support users on old ones?
There isn't a one-size-fits-all answer for this, but you should have some idea of what your traffic breakdown by browser is, and ideally what your cost in conversion rate is for each additional ms of latency (this varies by industry). I don't remember offhand what the cost per byte in latency is, but IIRC we measured something like 1ms per 1K bytes at Google (this would work out to a 1 MBps = 10Mbps connection, which seems around right for typical cable/residential fiber households these days).
I'm not sure what you mean about "complexity for users of your head browsers". The idea of the fallback/polyfill is that it doesn't even come into effect for the modern browsers.
As far as latency is concerned, I hear you and that makes sense, but the things I'm talking about are not very big, so the latency gain isn't going to matter much for our purposes.
Yeah, we definitely look at the analytics. But even if it the old browser users are sub 1 percentage point, I see the number and think, "I could take this 5 line polyfill out, but then these 1000 uniques wouldn't work."
Polyfills are generally a good idea - they cost basically nothing for users of modern browsers, and they go away.
I thought that the issue in this thread is JQuery, which is a layer on top of the modern browser API (probably because the modern browser API didn't exist when it was created, and is in a large part a native implementation of JQuery functionality), and so incurs the cost of all its legacy compatibility support even if you don't need it.
Rarely that easy. Oftentimes a performance issue can be traced back to an implementation that must support a dizzying array of use cases. You may not need all of that, but you certainly cannot just tear it out and push it back up.
I will lose a beautiful API with a simple, terse and familiar syntax. I will have to work with an ugly, inconsistent and loquacious API, which has no guarantee of being cross-browser (or accounting for various browser quirks).
And for what? I doubt 81 KB would make much difference to 99.9% of my visitors.
As for performance -- it makes sense to rewrite bottlenecks in pure highly-optimized JS. But to write vanilla JS from scratch, without even knowing whether you'd need that performance boost is a pure waste of time.
UPD: it has been pointed out that this webpage is directed at developers of JS libraries. In this case, all these points are valid, but the title, then, seems to be either misleading (as in "link-bait" misleading) or a plain truism.
You lose dependency on a monolithic library which creates vertically-stacking dependencies and library conflicts. By ditching it, you gain the ability to construct your app out of loosely-bound components supported by independent developers.
Obviously, you cannot have dependency conflicts if you only have a single dependency! We need a slightly more complicated example to understand the problem. Let's say I'm making the new customer checkout page for my startup.
I decide to call an e-mail address verification as a service API, their library uses jquery 1.8
I decide to call an address verification as a service API, their library uses jquery 1.11
I decide to call a credit card validation as a service API, their library uses jquery 2.0
You go to the e-mail address verification company and say "Do you have a version that supports a newer version of jquery" and they say "yes, also we redesigned our library's interface so if you upgrade you'll have to change all your code..."
You had me convinced until I scrolled down to read the code examples and realized why I actually do need jQuery. If its between adding yet another collection of utility functions to approximate the functionality jQuery would give me vs just adding jQuery. I'd rather go with jQuery.
The first example alone is reason enough to use jQuery - why would I want to use four statements instead one? Why would I want to have to remember to call `send`? Why do I have to remember the last boolean parameter of `open`?
Totally valid, but just to say, jQuery's API is just as arbitrary, you just happen to know it better. If you use the native XHR a couple times, you know what open's parameters are.
It is just as arbitrary, but I feel jQuery's API is also easier to grok at a glance. Using either a couple times may instill the parameters in your memory, but what about coming back to it after six months?
I think the question is, does your library need every function on that page? If so, just use jQuery. But do you just need one thing? Then maybe it's better to just make the one utility function rather than pull in all of jQuery.
I had exactly such a collection of DOM utility functions and was glad to give it up. For example, rooting around in element.className was never very enjoyable. Also, the site does not show handling null cases which adds more code.
It used to be that the first thing I'd reach for when building a prototype was JQuery off a CDN, but now I find that more and more of what I use JQuery for is built into the browser, and in my last few prototypes I've just stopped including it at all because I don't need it.
Nope, I didn't hear anything further on it. Still seems like an interesting event to me, though finding time might be hard. (FWIW, we do similar things within my employer all the time.)
One way of looking at it is that if you already have underscore to give you _.extend and the like, you can get pretty far with just what the browser gives you.
I would like to add a thought about the dispute about the need of using jQuery.
Let's say we know a consultant, let's call him Bob, who works on client projects. He needs to implement new features fast, and does not want to worry about low level stuff. Once he's done with a project, he moves on to another.
Then, we meet a JS-framework developer, let's call her Alice. She has to weight every line of code she writes because her decision can have have a huge impact on thousand of developers using her stuff. She needs to understand a lot of low-level details in order to make good decisions and ship rock solid stuff.
Now, both Bob and Alice have to decide whether they need to include jQuery in their projects or not. Heck, they need to justify their decisions to their teams / managers.
What's Bob going to say? He will start thinking about what will happen if he does not include jQuery to his project. Well, he will have to implement some of the low-level stuff by himself, and later maintain the code. Probably, in a month he's going to be working on another project and will have to copy & paste the same stuff over. And if there was a bug? Is he going to update all the previous projects he is not getting paid for anymore? If he's smart, he's going to say: we'll take jQuery, as it provides a nice, stable, robust and battle-hardened API. We're going to move faster if we use it, as we don't want to reinvent the wheel.
What about Alice? She will probably have to consider introducing a new dependency to her framework. Is it OK to add those additional hundreds of lines of jQuery code to an already large codebase? Is she going to be able to provide a consistent experience between different (and future) versions of jQuery? Is the core of her application going to rely on an external tool, even if it is rock-solid and lose the potential to make low-level optimizations and have full control? Maybe, she's going to say: well, I'm going to identify the elements that need some of jQuery's stuff and implement it by myself. She will be taking the time and effort needed to test it well and be sure that it works across different platforms.
At the end of the day, both will have made the right decision, even if in absolute terms they took the exact opposite action.
Software engineering is about making decisions, in a given context and moment, for a given purpose. As software engineers, we should not generalize about some of the decisions people have to make. There is no one single truth, it all depends on a variety of variables and factors. Let's be Bob and Alice, be smart and make the best decisions for our projects.
Thank you. Its astounding how much of this thread does not seem to be catching this.
My project currently depends on libraries which in turn have dependencies on mutually exclusive versions of jQuery, so we conditionally load a whole second copy some of the time. I've been meaning to fix the libraries that require older jQuery so we can fix this, but the bugs run deep, the libraries are pretty unmaintainable, and I'm under pressure to keep shipping features.
I recently did a project that didn't use jQuery in order to keep my code smaller. It was an embedded 3rd-party widget, so keeping the code as small as possible was a key requirement. The code I wrote supports down to IE7, but IE7 wasn't really the biggest issue.
The real problem with not using jQuery is that all of the collective knowledge we have about browser inconsistencies is encapsulated in jQuery. When you run into this, and Google it, you'll find a million StackOverflow answers telling you to use jQuery, and if you get lucky a blog post from 2007 that actually answers your question. The result is that you end up spending time reverse-engineering jQuery to get your thing working.
To be clear, in my case the tradeoff was worth it (the code for my entire widget including the bits of library I had to write is smaller than jQuery), but it's not a tradeoff I would make unless I had a good reason.
Not sure what you're getting at. Feature support doesn't mean there aren't inconsistencies in implementation, and caniuse's documentation on that delta are very much surface-level.
The native versions also usually run several times faster than the JQuery versions, which is the main reason to use them. This meme that you can't build performant, jank-free HTML5 mobile apps? It's largely because of JS libraries and developers that don't know which operations are fast and which are slow.
I'll also plug my colleague's autogenerated index of the HTML5 APIs:
Are you animating the transform/opacity properties and only those? That's the general secret to smooth animations on web - they're GPU accelerated, everything else requires a call into the browser's layout engine on every frame.
This be right on a purist level, but on every practical level there is little reason not to use [library of your choice]. If you're loading from the google/jQuery CDN (with suitable fallback, obvs.) you've got a good chance of a cache hit, and even if it misses it's a tiny one-off penalty.
And ultimately, why not? jQuery works, has a wide base of users, etc. Sure your trivial Js might not need jQuery features now, but as you add more dynamic behaviour, at some point you'll wish you had just used it to begin with.
A better message might be: make sure you know what the underlying javascript looks like, because there are a lot of people helpless without jQuery.
PLUG: if you're bored of jQuery, try Dojo. Far more power, in a less intrusive form, IMO.
i do Enterprise work & if we have jQuery in a page IBM dismisses our PMRs when we submit issues. So yeah I regularly include some simple cross-browser-normalizing js functions to use with the vendor-approved libs.
Also, jQuery is not trival to use in conjunction with other js libs (Dojo) as namespacing proponents claim. It's not like you just include both & they don't interfere. You have to follow a specific initialization pattern.
I don't understand this comment - I'm not suggesting you should use jQuery or nothing, or jQuery and Dojo. My point is the reasons given in the post for not using a DOM library of some sort are not valid.
o ok i was taking your comment within the context of the post -- more like "why not allow jQuery as a dependency for an open source lib". sorry for misread
I trust Google more than most websites small enough not to have their own CDN, it's probably much easier and more likely to compromise them than Google's CDN even if of course Google is a more attractive attack surface. I guess theoretically it is, but practically I doubt it's anywhere near the most practical attack vector.
It isn't that these rebuttals are unsound, it's the sheer volume of them. A tidal wave of irritation and defensiveness always seems to accompany posts that dare question jQuery.
Unless the headline was changed by the mods, there's no hyperbole or sensationalism here. You might not need jQuery. Obviously. But many of these reactions don't belong here, they belong in a post titled You don't need jQuery, which would of course deserve to be downvoted to hell.
Obviously you don't need to pull in jQuery for every little twenty-line gizmo you publish on github. But don't you dare brag about this or you'll offend the sensibilities of those who've invested all their mental energy into learning jQuery and therefore remained ignorant of how browsers actually work.
"You might not need jQuery" -- But you have to cope with ugly syntax, browser compatibility hacks, and disconnected pieces of code. By the time you re-factor all of this, make it user friendly and lower the cognitive load, you're already re-inventing the wheel by building your own jQuery replacement, with the parts that you need.
The beauty of jQuery is working with the DOM as collections. I don't see how it's better to have all these helpers like `nextSibling`, `matches`, or `filter` thrown in the global scope or having to remember is this a real array? jQuery already built solutions for these common problems and exposes a nice API.
If all I need is querying the DOM and I don't have to support IE8 then I may consider using vanilla JavaScript, or building my own simple jQuery-esque library. But you'd start with some structure, and expose your own API. I re-invented the DOM wheel many times, and from my experience, although the code is smaller, I end up going back to jQuery because it covers some edge case or provides something else I need, like AJAX, or nice events, etc.
But building your own DOM library is a good educational challenge. Querying the DOM is all about collections, and if you don't need IE8 then you can use all the ES5 arrays methods, like map and filter. It all boils down to four functions to work with collections: toArray, unique, flatten and query. And four functions to work with the DOM: compose, join, dot, loop. See here for an example http://jsbin.com/EgIkega/1/edit. The article is more about techniques to build your own jQuery-like library; I wouldn't use "el.nextElementSibling || nextElementSibling(el)" when I can use "$(el).next()". C'mon!
Conclusion, you are probably going to use jQuery anyway.
Indeed you don't need jQuery. Though, there are standards and there are market/industry standards. jQuery has become a market standard wrapper. If jQuery isn't used, developers will still write a wrapper to ease some of these methods. It is better if that is a common market standard like jQuery than everyone doing it.
The amazing part of jQuery still to this day, beyond the selectors (which can now be replaced yes), is the plugin system. Just like Python, there is a plugin for everything and if you don't like them or there isn't one, developers can easily make one and share it with the world and it just works (tm). It is the most easily pluggable javascript library. It creates a baseplane that developers can be more efficient in. Everybody tries to replace the jQuery selectors, animation etc but they miss that jQuery is a platform and a pluggable one at that. It is responsible for tons of productivity.
People don't use Ruby because C's standard library works differently across different platforms.
This isn't about "rewriting jQuery methods with vanilla js". It's about using the built-in, native, vastly more performant methods that come standard on modern browsers.
This is exactly what we're trying to combat. For modern browsers, in many cases, it's just not true. There are a few utility methods that are tricky to replace, but you really shouldn't be including jQuery only for it's utility methods.
jQuery provides a uniform API that is guaranteed to work on supported browsers. The jQuery team does all the work to back that guarantee. If I rely on raw JS, then I'm one glitchy browser implementation away from being broken.
Even worse: suppose you build a product with the approach you recommend, it's very successful, and then your sales team makes a major sale to a stodgy old bank that still uses IE7. Or maybe you just never make the sale because you don't support the browser they use.
OK, let's say we should all turn away money from IE7 users because it's insecure and old. For OP's strategy to work, we have to assume all browsers we care about will be compatible going forward. I think this is a very unsafe assumption to make. While one small incompatibility would only be a minor annoyance, once you have more than a handful of these, a compatibility layer like jQuery again looks very nice.
And none of this even speaks to the fact that the jQuery implementation in the source article is generally at least as short and readable as the alternative, or that most people are more familiar with the jQuery version.
The only reason I can think of for dumping jQuery is maybe speed optimization, and even in that case, well-implemented jQuery should be no slower than the native speed plus the cost of a function call. If it's slow and you want to optimize something, why not optimize/bug-fix jQuery itself and help everyone, not just your one project?
I think your analogy is flawed because it seems like you're essentially taking an extreme on the opposite end from what you are sarcastically mocking.
I wouldn't call myself "old school," "hard core" or anything like it, but I just don't see what's so difficult about--or wrong with--replacing any library with "ad hoc" code that accomplishes a small subset of the library's functionality if the majority of the library's purpose is to provide that small subset. "Small", of course, is relative and context dependent.
I don't understand why so many comments here seem to have skipped over the word "might" and the entire introduction. The point isn't stop using jQuery. The point isn't even don't ever use jQuery for plugins. It's simply that if you're only using a couple features of jQuery, consider eliminating the dependency. Why is there so much backlash to that?
It's hard to tell if this site is advocating for ditching this type of js library altogether and writing all those replacements inline (ick for some of those) or simply replacing jQuery with a thinner (and narrower) library.
I could be convinced of the latter but not the former.
One of the main things we're advocating is to consider not depending on jQuery when building an open-source project.
For Offline, PACE, Odometer, Tether, and many of our other OS projects (http://github.hubspot.com), we chose not to depend on jQuery because it means our libraries can be smaller and more people can use them.
We're happy and proud to use jQuery when building an application. As many other commenters have noticed, it can be extremely useful at reducing code complexity—and let's just say it: it can make it more enjoyable to write front-end code!
I think that what it's saying is that you can write yourself a microlibrary that just includes the ten or fifteen lines of adapter code you actually need for the thing you're building, and that you should use native browser constructs whenever possible.
I use jQuery because the DOM API for javascript sucks, and writing jQuery is fun.
You're average web app perhaps doesn't need the latest Ruby/Python/PHP framework, or perhaps it you can write it without the framework. Or perhaps you can a compiled as opposed to interpreted language because that would be faster. OR maybe you can use something that is even faster, like perhaps Assembler! Fuck it write machine code if speed is the most important thing.
Do you know why you don't? Cause writing Assembler or machine code sucks. You lose very little in load time by including a minified version of jQuery, while you gain an enormous amount of ease of use and readability. Also it'll be more fun.
DOM selectors and events are critical, maybe ajax. Perhaps you could pare it down a bit - I don't need the animation stuff. I have no idea what the size using only what I might need when I needed it.
But then that becomes a whole another endeavor - how much load time will be saved by only using the parts you need, and how long will it take to figure out what you need and what you dont? It's all about return on investment. What do I need now, what won't I ever use, and what might I use later. It becomes more work to save, what, 1/4 second? Maybe a bit more on mobile. It isn't worth the trouble.
The whole obsession over the load time of jquery feels like an exercise in OCD.
It's odd, but after reading everything and the examples at the end, I feel we need jQuery more than ever. Kind the opposite of the OP is stating. Great post though.
My colleagues and I learnt that lesson the hard way. We are working on a WYSIWYG editor (Aloha-Editor) and the first version did depend on jQuery (and jQuery UI for that matter). That caused a lot of trouble for people integrating the editor in their websites, especially if they were already using jQuery. For our particular case we really didn't need it, as it's just as easy to say .getAttribute() instead of .attr(), and we didn't use selectors much, if at all. Effort is underway to get rid of the dependency from the core library in the next major release.
This is fascinating to me since I'm already moving away from jQuery. I'm always looking for other ways to do what many people use jQuery for. For example, I'm now using CSS3 animations and transitions instead of jQuery.
I've also started using Angular.js quite a bit and have found most of the time, it requires less code than jQuery. It also has its own subset of jQuery "jqLite" which has a much smaller footprint so your app doesn't need to rely on that jQuery dependency.
querySelector and querySelectorAll have bugs in IE8. Checkout the jQuery source code and search for these functions and see the comments and workarounds if you want to be sure:
Recently, I have developed a small page where I wanted not to use jQuery on purpose and code against the DOM APIs instead. For IE8 compatibility I have used [1] (so I could use addEventListener and DOMContentLoaded for example), and also shims for ES5 [2] (e.g. Array.prototype.forEach) and classList [3].
While I did not run in any troubles, I don't think it is worth the effort, alone just because jQuery has a much nicer and shorter API (cp. ".on()" vs. ".addEventListener()").
But I still support the case that not every plugin/library developer should depend on jQuery by default, even if it is not necessary.
In my opinion jquery is a hell. Because jquery is only abstraction for browser features level (events, styles, dom), but it's ugly for writen complete code, for this need some like prototype.js or mootools, because it's have oop-style level for browser.
I implore all developers to learn native Javascript methods, because I strongly believe jQuery has created a generation of developers who know the library but not the language. You'd be surprised how many developers I've come across think iterating over an object or array requires Javascript and how many people don't know how to write a simple for or while loop in Javascript. jQuery is a fantastic library, but it is by no means a cure-all for Javascript problems.
Now about this site itself. This is a great idea getting people to use and understand native methods, but please also understand that native methods aren't always necessarily the most efficient choice. There are a few of parts of this site I think send the wrong message. Don't get me wrong, I think this is great, but sometimes native methods are no better than jQuery's.
The first one being jQuery's each method. It is a known fact that jQuery's each method is extremely slow, it works, but from a optimisation perspective native ways of looping an array are always the fastest and most efficient.
The alternative given for a jQuery.each statement is the IE9+ supported Array.prototype.forEach — now you'd think this would be faster right? It's actually still not as performant as it could be. As this jsPerf set of benchmarks shows is that a for loop is the most performant option: http://jsperf.com/foreach-vs-jquery-each/38 — it might not be as pretty as jQuery.each or Array.prototype.forEach, but heck, it's a whole lot faster than the alternatives.
The second being the use of querySelectorAll (which is awesome btw). It has similar capabilities to that of jQuery's native wrapper for querying, it looks just as nice, but once again the performance isn't all that great. Looking through multiple jsPerf benchmarks, querySelectorAll is rarely the best option to use in most cases. This is an example of one: http://jsperf.com/queryselectorall-vs-getelementsbytagname/4... — if your selector is extremely complicated, think to yourself, how can I make this easier to write? Do I need to query a chain of five classes and use CSS3 selectors, or can I just add an ID to the element I want and query it using document.getElementById instead.
Sometimes jQuery is needed though. It saves considerable amounts of time, especially when the budget of a project is tight and timeline is even tighter and you just need to get something out the door as soon as possible. If you have the time to properly build whatever it is you are building, consider spending that extra 15 seconds writing a for loop to iterate over that array or object.
And to those who understand and have taken a look into the internals of how some jQuery methods work like document.ready, you'll appreciate and know just how many different browser quirks the jQuery team have solved for us. There are quite a few methods where jQuery hides the gory details of a sometimes difficult to get right across all browsers feature.
Personally my favourite thing about Javascript is the power of documentFragment: https://developer.mozilla.org/en/docs/Web/API/DocumentFragme... — this is something all developers who use Javascript need to know about. It helps prevent reflowing and redrawing as well as being extremely efficient and fast for modifying and inserting elements into a page.
Over all of this I think we all need to reflect on the state of Javascript. It's a whole lot more powerful and better than it was 10 years ago, but I think because of the likes of jQuery and others, people have become obsessed with pretty code and methods. I know for loops and prototype methods might not be as nice as your one line of jQuery code, but don't take the easy way out, because you'll soon find the longer your Javascript grows in your app/site, the slower it will become.
> I strongly believe jQuery has created a generation of developers who know the library but not the language
i think you mean "know the library but not the DOM and additional HTML5 APIs" - they are after all just native libraries. ES5/6 would be the "language"
JavaScript is a dynamic language, and it is arguably the case that many of the frameworks that exist for it hide or transform enough of the "native" implementation details as to be different languages. Or supersets of it, if you like. I don't think it's at all unreasonable to suggest that a developer who uses jQuery (or any other framework) doesn't have to have more than a vague, fleeting understanding of the "native" language under it.
except "many of the frameworks that exist for it hide or transform enough of the "native" implementation details as to be different languages. Or supersets of it"
is wrong. It's all still javascript. Just.. plain.. javascript. with a different api/library.
> The alternative given for a jQuery.each statement is the IE9+ supported Array.prototype.forEach — now you'd think this would be faster right? It's actually still not as performant as it could be. As this jsPerf set of benchmarks shows is that a for loop is the most performant option: http://jsperf.com/foreach-vs-jquery-each/38 — it might not be as pretty as jQuery.each or Array.prototype.forEach, but heck, it's a whole lot faster than the alternatives.
So I'm by no means a compilers or js engine expert, and this really is an honest to god question and not an attempt at sideways criticism.
When I use each, forEach, map, or something like that, I'm usually optimizing for my own readability and to try to create more concise and understandable code (admittedly only for folks comfortable with those paradigms) and not actual raw performance.
Is it the case that Array.prototype.forEach is faster than a for loop for all modern browsers, and could that change with engine optimizations? My wonder there is that it smells like premature optimization while sacrificing readability (again, assuming you think map/forEach/etc is more readable, which might be a huge assumption).
I think you make a very valid point. One poorly optimised loop using jQuery.each or Array.prototype.forEach unless you're writing a heavily JS intensive application isn't really going to make a noticable difference to performance. The average Joe developing a Wordpress theme with a slideshow and a few other little pieces of JS probably won't see any lag nor benchmark said theme. However, it does all add up the more you use Javascript for, you eventually get to a point where the milliseconds of delays and spikes in RAM usage add up and cause delays/lag.
I think it's just important to be aware of the alternatives and trade-offs using certain methods and knowing when to a 3 line method in place of a one-liner piece of jQuery. On a site I am currently working on I am using jQuery.each, I am modifying elements in the page using jQuery.width and all kinds of other things I normally would advise against in a large application. But the site I am building which is a Wordpress theme uses such little amounts of Javascript that using a more optimal method wouldn't really make much of a different interaction and latency wise.
My point was more-so that there are developers out there using poorer methods even in large-scale applications because that's the only way they know how to do it. Just being aware of what you can do in Javascript can be a beautiful thing and even save your hide in a situation where the page is freezing up when you scroll (an event I recently witnessed occur and had to fix).
In time I do believe native methods and certain implementations will get better. Javascript has evolved quite a lot in the last few years and shows no signs of slowing down.
Got it. That makes sense, and I definitely agree with the point of knowing the language features and being aware of the trade offs you're making by choosing one technique over the other.
jsperf benchmarks of small highly optimizable loops are no better than random numbers. they aren't accurate.
It is true, however, that array.forEach can theoretically be worse than a hand-written loop - and I think in some cases it currently is. This is due to the fact that a call through Array.forEach might have to enter and exit C++ code, instead of remaining entirely in JS, which prevents optimizations like inlining and invariant code motion.
However, these problems will go away over time as most JS builtins are moved to pure JS implementations (which enables full optimizations).
If you are trying to determine things like 'what's the fastest way to iterate a sequence', the ONLY REALISTIC WAY to do this is to benchmark your actual use case, in context and see which approach is faster. Microbenchmarks applied to a language like JavaScript are, 99% of the time, complete horseshit.
jQuery is a library where rails is a framework. but I will agree, a lot of developers are likely to use it as a crutch in lieu of fully understanding cost vs benefit in your app. if this is the case, then you very might well need jquery.
I would still stick with jQuery because it lets me achieve more by writing less. Out of many things, just see triggering custom events. It'd be horrible if I'll have to write that piece of code again and again and make sure it's bug-free. And if I contain that long logic into a function for re-use, and use this approach for everything listed on the page, I'll end up writing my own library that I'll be including in each of my projects. Wait, why don't I use jQuery instead which is battle proven and better tested than my library ever will be?
I think many commenters are misunderstanding the main idea here. This page makes a strong case if you're just using jQuery for a few things in your site. I can see people complaining "why would I write all that code again? if jQuery offers a beautiful API?" if you're just using jQuery to do a few simple things (Which I've seen all over the place among peers) then why not just write the native version? it's only a few lines and you're saving a whole library in your load process
jQuery or <jQuery-compatible substitute> is one of the few things I don't have to think twice about before including in EVERY WEB PROJECT I EVER WORK ON before doing anything else.
Next up: you might not need <insert abstraction>.
Really?! What does "need" mean? Go write assembly.
It's plain stupid. Your code may work for IE8+, but there is no warranty that M$ will not do something stupid in IE16, and your code will be broken. jQuery is unified bridge between all major browsers, so you don't need to support all of them by yourself. "Support for all" is why we shift from compiled to VM languages, even though at the begin they were slower.
I'm psyched by the idea that you don't need a bloated framework, but between using Zepto as an alternative, as well as the fact that some of this information is just plain wrong (e.g. they claim that the classList API is supported by IE8+, when in fact it is only supported by IE10+), this won't get you too far.
1) The fact that some people don't realize that JavaScript != jQuery scares me.
2) jQuery born when cross-browser compatibility was a mess and today it still carries that weight. I think nowadays it needs to be more modular and less monolithic.
I'm a little sad to see that nowadays there's a strong sentiment of "just use the pre-packaged tool", whereas when jQuery was still in its infancy, there was a lot of lively hacker-minded chatter on the down-and-dirty of getting things to be cross browser.
It's as if there are now two "levels" of people - "regular developers" and "framework designers", and only the latter are really supposed to know about the nitty-gritty. The excitement of finding out about standard, cross-browser gems like insertAdjacentHtml is all but gone :(
I get it that people are focusing more on the entrepreneurial side of things now, but I miss the banter of aspiring tinkerers.
Although this is true, you don't really need any library. The problem comes when you start to need that library. You make a decision to not use it at the start of the project and then the dependency of lower level JS functions grow and it turns out you do need it. What do you do then? Go and get a copy of jQuery and start to rewrite all your functions?
Hindsight is the problem here, I'd rather make the decision to use the (relatively) low sized jQuery library and not have to worry about how the project grows.
As the old saying goes, "It's better to have it and not need it, than need it and not have it".
It seems to me that if you are making a library, and therefore do not want to make assumptions about the availability of jQuery, one potential solution would be to go the route of AngularJS[1] and have a 'soft' dependency on jQuery.
In this instance you would use jQuery if it was present, but fall back on the code found in this submission if it wasn't.
Are there potential downsides to this solution that I am missing?
Apart from size and many functions that translate 1:1, where it really doesn't make sense to use Jquery (time to learn ?) there are two extra factors:
1. the extra http call to load a library, that can be optimized
2. licensing, some company cares about that and avoid the the hassle of having yet another license to understand and manage, there are costs involved
I've seen thousands of js snippets using jquery just because the developer doesn't the pure js syntax, or because he is used to start from adding jquery.
very good page indeed, thanks for spreading the knowledge.
This is a great resource, even though it's not really about jQuery, it's about the success of HTML5. The fact that we have a working DOM, XHR, and a better understanding of polyfills in general does tip the balance away from depending on a "fix it" library.
I can see myself reaching for this page a lot. And the author has a point as the only reason I used Zepto on my last project was one of the libraries I needed used it.
If I am gonna use a fix it library today, it's more about nodejs/browser compatibility than worrying about browser issues.
I agree that you probably only want to use a small subset of jQuery (e.g., none of the UI, none of the transitions), and zeptojs is actually a really good alternative. But it really does provide some convenience.
I've never liked jQuery. I use it because I am forced to. However, I will not write my own animation library, selector engine, and other helper utilities it provides.
You don't have to. Browser manufacturers wrote an animation library (CSS3 transitions & animations), selector engine (querySelectorAll) and other helper utilities it provides.
Well... I don't like this trend. I saw project once where main frontend guy decided to do stuff without jquery and etc. He said that vanilla.js is nice and people just don't get it. After project was done it worked only in firefox properly. Lot of time was spend after that to implement fixes for different browsers. So don't do that. Don't use vanilla js. Size of jquery is issues? Well you are trying to solve problem that does not exist.
I wondered to myself, why did he create a custom website just to present this? It seems like a great way to position yourself as a skilled front-end developer and advertise your services to potential clients. I suppose it could also have been done out of some kind of altruism, but I'm guessing the former.
Either way, this is pretty neat, and I'll probably be bookmarking it. We're using ClojureScript now and migrating away from jQuery, so this may prove handy.
If you only care about IE such as inside corporate intranet, and never had to worry about cross browser compatibility, knock yourself out. On the other hand, the scalablity and performance on the intranet usually are not a high priority. Why not just learn jQuery rather than tight yourself up to vender specific, proprietary technology?
I may not need jquery for compatibility, I need it because it makes code in a language I find unesthetic and unconsitent more readable.
Yes I can do vanilla JS, but my productivity and readability in jquery is better.
And this site proves my claim: all their vanillaJS exemple are less expressive and more error prone.
DOMContentLoaded doesn't even get close to the jQuery counterpart $(document).ready. To start if the DOM is already loaded DOMContentLoaded won't fire and won't call the callback. On the other hand ready will notice that the DOM is loaded and fire the CB right away.
In my personal projects (and clients' too unless paid extra), I target for modern browsers + IE10 and haven't used jQuery for long time. Native APIs are good enough once you get used to them. Actually jQuery starts to feel cumbersome (this binding in .each() etc).
I don't get it. From the examples it seems that the jquery way of implementing things is much easier and more concise. Isn't that the entire point of a library?
jQuery still has it's uses... like when it's essential to have consistent support across browsers old & new. However I much prefer to tell users who insist on using out-of-date/poorly-built browsers to upgrade or fuck off, hopefully gently encouraging them to do so.
Since I've started using an MVC, I use chaining less and less. I tend to just use a variable the few times I need to do a bunch of manipulation to the same element. Beyond that, any chain using .end is nuts to me.
Yes, Angular can use jQuery if it's present in your app when the application is being bootstrapped. If jQuery is not present in your script path, Angular falls back to its own implementation of the subset of jQuery that we call jQLite.
Due to a change to use on()/off() rather than bind()/unbind(), Angular 1.2 only operates with jQuery 1.7.1 or above.
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.