"It doesn't force you to program or organize your code in a certain way"
Yes it does. JQuery calls it "new wave JavaScript", but really it's just an anti-pattern. JQuery forces you to select all elements using $() before being able to use any of the methods. And you have to call $().get(0) to get the
selected element out. It is this unnecessary process that
gets very tiresome. Let's see if this makes it more clear:
$('#elm').color('red');
/* do some stuff here */
$('#elm').text('new text');
To simplify that (and not require a redundante DOM call) you'd use a local variable to store a reference to the element:
var d = $('#elm').get(0);
$(d).color('red');
/* do some stuff here */
$(d).text('new text');
I argue that this is unnecessary when you could just write conventional code instead:
var d = document.getElmentById('elm');
d.style.color = 'red';
/* do some stuff here */
d.innerHTML = 'new text';
The way the $() function operates just doesn't sit well with all coders, regardless of how solid JQuery is in other respects.
That's also an anti-pattern. JQuery was designed to hide iteration from designers who can't code. I'm floored that people that actually know how to program still think it's a good idea.
$('DIV').click(..).color()...border()...
It might look fancy, but all it's doing is obscuring the fact that iteration might be occurring on each command which for obvious reasons would be a bad idea. A designer might not care, but a programmer who knows JavaScript will probably write something like this instead:
When I use jQuery (MooTools is my lib of choice) I find myself using it in ways that is very unlike the majority of jQuery that is seen around the web.
I absolutely hate the plugin system simply because you cannot easily get the instance of the plugin an refer to it later. To answer this I use function constructors with the module pattern (its easy and doesnt require an extra lib to get going) to create my plugins. Another thing that I do is when I query for a collection of objects, create an array that represents every item in that collection already wrapped with the jQuery object. This may not seem like a big deal, but there is a difference between
var collection = jQuery('a');
collection.each(function(i, l){
var link = jQuery(l);
link.bind('click', function(){//do suff});
});
and
var collection = jQuery('a'),
collected = (function(){
var c = [];
$.each(collection, function(i, item){
c.push(jQuery(item));
});
return c;
})();
this second way allows you to select an item from collected without having to rewrap it with the jquery object. I dont have any data on it, but it seems like rerunning jQuery() with every mouseover/mouseleave/event etc seems like a waste of processing.
Anyway, that is just a few ways that I use jQuery to make javascript a bit easier. These little tricks have the people that I work with thinking that I'm some sort of genius.
"Useless" is subjective, but the jQuery object does a lot of extra work above the vanilla example.
$ isn't just a syntax layer on top of querySelectorAll. When you do $('p'), it first queries the DOM for everything that matches that selector, then it creates new jQuery objects to wrap each of the returned nodes as well as creating a jQuery object to contain them.
If all you're doing is setting the innerHTML of these objects, it's a non-trivial overhead.
These guys need to get over themselves. JQuery provided a really nice way for designers to copy/paste effects onto web elements. And then they took it way, way too far, to the point where whenever I see a "new JQuery plugin to do X" I just look the other way.
JQuery just gets in the way these days.
$("#element") is an anti-pattern. That code should just return the DOM node, not some silly object with unknown attributes. We're way past the point where you need to abstract the entire document object model, and I argue you should never have done that to begin with.
The given example of element.nextSibling is a great example of what jQuery gets wrong. In jQuery, that's going to be $(el).next();
On first encountering $(el).next(), you need to answer a bunch of questions. Next what? Why is this a function and not a property of the object? Why not call it getNextSibling? What the hell is $() doing?
element.nextSibling is very clear. It's the next sibling of the element. It's idiomatic javascript, and it follows a good naming convention, which is a skill that is language agnostic.
The author is also conflating their time learning as a pro for jQuery. Had they learned vanilla javascript first, their point about not knowing which nextSibling to use would be moot. What they are referring to here is an idiosyncrasy, and jQuery is jam packed with them. The difference is they have learned them already.
If you learn jQuery today, you're not learning core JavaScript, and considering the trajectory of web technologies you'll be doing yourself a disservice not to use that learning time on actual JavaScript that you could use in future tools. jQuery isn't a bad choice if you know it already, but if you are a new developer do yourself a favor and learn the foundation it's built on first.
The constant traversing of the DOM over and over and over again to re-select jQuery DOM objects. Sure you can write that correctly. But I rarely if ever saw anyone to the point that when I would, most developers who typically worked in jQuery would be confused.
I've seen jQuery code. It doesn't do anything particularly useful for me.
It solves problems I don't have. I don't need to lookup elements in the dom, because I put them there. I already know where they are.
I don't need a slow .bind() method - I know how to write closures.
Look at one of the top news items - jQuery plugin 'behavior'. It just doesn't make any sense.
Look at some of the source code. For example .addClass(). It's the most general you could imagine - can take a list of classes, or a function. Yet I'm betting most of the time it's being called with a single class to add. There's a lot of wasted checks and effort in there. It's checking the type, it's splitting the string on " ", it's checking to see the class isn't already listed etc etc
Also everything is assuming it's operating on a list of elements - cue wasteful for loops when they're not needed.
So, when you do the seemingly simple
$('#myelement').addClass("foo");
it'll be cycling through the array of elements of length 1, splitting 'foo' on spaces, checking if 'foo' is a function, etc etc etc etc
Those are precious wasted cycles. And for what? so you can write:
$('#myelement').addClass("foo");
instead of:
// I already have a js ref to myElement thanks,
// and know myElement doesn't already have 'foo' in className
myElement.className+=" foo";
nice. I don't 100% understand it or how you would use it and why you would use it and not just write jquery code and structure it logically,... but then again I'm constantly finding my jquery code to slowly becoming big and using global variables and stuff to encapsulte objects' behavior... but unfortunately, I don't really understand this enough...
> 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?
I'm really surprised you don't like it. It might sound strange but the first thing that got me hooked on jQuery was the syntax, and then the selector mechanism. It feels very clean, looks readable and is quite concise, especially compared to the plain old javascript that I used to write.
What is it you don't like? I'm not saying you're wrong for not liking it btw, each to their own! I'm just curious.
jQuery promotes bad practices. People assume $('something') is a cheap variable access, when in fact it could be pretty slowly executing several functions. So they don't bother caching anything.
This is written by someone who has never used jquery or forgot it.
The beauty of jquery was not being able to use CSS selectors to find elements, but in being able to work with multiple selected elements as if it was a single one.
instead of $('.foo .bar').css('backgroundColor', 'corn');
and it is clearly better because it does not use jQuery.
Don't get me wrong, jQuery has many issues that make it a very poor choice for big modern web applications, but please don't tell me that it can be replaced by querySelectorAll.
Uhh, no, you're incorrect (albeit in a sense, I'll admit).
The entire article was about jQuery and CoffeeScript, so my example was built using jQuery. This entails a .each method on DOM collections, and $(this) will properly scope being inside that $().each method.
M1573RMU74710N summed up what I aimed to do here, though, which was show that the resulting code isn't actually that bad. In my opinion the article in question is making a case that all Javascript looks horrible, when in reality that's simply not the case.
Edit: I see it noted in another comment on this thread that you're writing a book on this... and you couldn't tell I was using jQuery, when I pass in the results of the selector call as an argument? Tut tut...
This article is pretty ok, but some examples given struck me as a little weird.
Example for "live()":
var newDiv = document.createElement('div');
newDiv.appendChild(document.createTextNode('hello, world!'));
[...]
document.body.appendChild(newDiv);
jQuery simplifies DOM elements creation and insertion:
var newDiv = $('<div>hello, world!</div>').appendTo('body');
It is kind of funny to see plain old DOM createElement/createTextNode in article about intricacies of jQuery. All of DOM elements creation in article uses non-jQuery mechanisms. Only one commenter mentioned that jQuery support easy elements creation/insertion. That way, article promotes somewhat half-baked usage of jQuery.
I would agree with your comment, but the author is not claiming to be reimplementing jQuery in 10 lines of code. He's merely providing a way to benefit from the syntactic sugar ($) to avoid using the verbose vanilla JS API (document.querySelectorAll) and solve the issue of NodeList not supporting the functionality available on Arrays (forEach, map, etc), which doesn't make any sense in the first place.
Without the easy DOM manipulation, jQuery's not much more than a nice wrapper to deal with AJAX browser differences. There's some serious cognitive dissonance here.
Yes it does. JQuery calls it "new wave JavaScript", but really it's just an anti-pattern. JQuery forces you to select all elements using $() before being able to use any of the methods. And you have to call $().get(0) to get the selected element out. It is this unnecessary process that gets very tiresome. Let's see if this makes it more clear:
To simplify that (and not require a redundante DOM call) you'd use a local variable to store a reference to the element: I argue that this is unnecessary when you could just write conventional code instead: The way the $() function operates just doesn't sit well with all coders, regardless of how solid JQuery is in other respects.reply