Ultimately, I haven't actually used jQuery for anything serious in half a decade, and somehow I manage.
I don't understand that sentiment ... Of course you can "manage" without JQuery. JQuery itself doesn't use JQuery (D'oh) and somehow it can do all these things, so it is possible. The point of JQuery is that I don't have to think about the various (slightly) incompatible implementations of <whatever> in each browser version, but can just use one lib call and be done with it.
JQuery to me is like using a car instead of running to another city. Yes, I could run, but why would I do that ..?
Browser incompatibilities are basically a non-issue these days for 95% of projects. Animations etc are far better done with CSS than jQuery (particularly when it comes to hardware acceleration). The Fetch API works in every browser. So on and so forth.
I think the OP wasn't suggesting that "managing" without jQuery is difficult. Certainly, I can say that I haven't touched jQuery in years and haven't looked back once. There's nothing I miss.
Why even use wheels when you can reinvent them? I'm not saying there are no reasons to go "bare metal", but satisfying your developer ego is not one of them. Unless you need every inch of performance or control, jQuery (or alternatives) is probably the more reasonable choice.
jQuery wouldn't be created today in anything like its current form. It still lives on largely because of inertia. Using the APIs provided by the browser is in no way reinventing the wheel!
A lot of the commenters here have a very old school view of jQuery. They seem to believe that if you're using jQuery, then you must also be employing manual DOM manipulations, manual state management, etc.
You can implement modern component-ized front-end architecture while still using jQuery. My company built an in-house front-end framework heavily inspired by React and Vue. But instead of abstracting away from the DOM, we've embraced the DOM by utilizing DocumentFragments for highly performant rendering. When our components render, they return regular ole HTMLElements.
The components built using our framework work with or without jQuery. No manual DOM manipulations, one-way data binding, sane state management, templating, child components, state triggers, etc. A lot of us use jQuery simply because we prefer it's compact and expressive syntax.
As long as you're using recent versions. The whole point of jQuery is that you can write some code and be sure that it will run correctly in older versions of the browsers.
No it doesn't.
Sure when jQuery was released in 2006, but browsers have had 12 years to improve their compatibility, and they have. Javascript has also had 12 years to improve and simplify its api, and it has.
Your analogy was perfect for jQuery 2006 but in 2018 its more like buying a car to drive around the city or you can just take an Uber, you don't have to walk anymore.
I really wish we'd of just ditched it and moved to Chrome or Firefox :(
We have a portfolio of hundreds of applications, and needed to make sure every one worked OK on IE 11 before upgrading from IE 9.
(I wish I could remember what it was. Perhaps an array method).
> If you're developing a library on the other hand, please take a moment to consider if you actually need jQuery as a dependency. Maybe you can include a few lines of utility code, and forgo the requirement. If you're only targeting more modern browsers, you might not need anything more than what the browser ships with.
Back then, you were 100% correct that if you were writing a library that you intend to use in other places, having jQuery as a hard requirement was a bad idea. However, one developer managed to convince their PM's to completely strip out jQuery for an upcoming project, despite the fact that this website was for a major charity that had huge accessibility requirements AND required legacy browser support. The devs on that project learned a ton about vanilla JS, but that project was an absolute disaster.
We did get a solid library out of it, though, and at least that didn't have jQuery as a dependency!
Did that convincing developer have more influence than the rest of the team? Why the PM was involved in implementation minutiae?
From what I've seen people tend to complain about office politics usually when they don't grok them. The not grokking part is often a choice stemming from a conviction that code monkeys > managers because "engineering". Following your example, who then has more influence over technical decisions? (at least in your somewhat disfunctional org?)
At that company (small agency), at that particular time, the structure was flat, and this was isolated to a project he was leading. It was raised in a developer meeting, where I said the point was that libraries shouldn't have hard dependencies, not that (in 2014) we should be ditching jQuery and writing vanilla JS, especially on projects that needed legacy browser support. He ignored me, and the project ran over by months and causing the company to make a loss.
Company issues aside, he wasn't the only developer to not RTFM at the time, and the site was shared across the web by people calling for the death of jQuery when it still had a very legitimate use.
Sadly, a lot of people didn't actually read the site, and they decided that jQuery was evil and shouldn't be used on websites at all.
Point is:
$('#somediv').removeClass('class-to-be-removed')
is so much better than
document.querySelector("#somediv").className = document.querySelector("#somediv").className.replace(/\class-to-be-removed\b/,'');
document.getElementById('somediv').classList.remove('class-to-be-removed')
Where the native APIs fall down is that1. they tend not to be chainable/expression-oriented, you can't just `classList.add('foo').remove('bar').toggle('qux')` because the first two methods return `undefined` and the last one a boolean
2. they don't support set-oriented operations at all, it's a chore of manual iterations
The last thing I'd want to see is a codebase going from 40 lines of code to 400 lines, because "hey, we removed jQuery and writing verbose js is the new cool these days"
I'd be happy if there's a jquery like polyfill library for DOM manipulation, but again - why not just custom jQuery builds and sizzle.js instead of re-inventing jQuery?
P.S I'm not sure IE11 supports classList. Source: https://developer.mozilla.org/en-US/docs/Web/API/Element/cla...
It provides basic support for classlist, add/remove/toggle exist and work as you'd expect. It does not have complete supports of all bits of the API:
* it doesn't support the second argument to toggle so you have to use a conditional/ternary with add/remove
* it doesn't support passing multiple classes to add/remove
* it doesn't support replace
> The last thing I'd want to see is a codebase going from 40 lines of code to 400 lines, because "hey, we removed jQuery and writing verbose js is the new cool these days"
That will only happen if you're incompetent and will not write a few simple helper functions. And probably not even then. Plain DOM API is not that verbose over jQuery. Anyway, just look at what subset of jQuery you use the most and write helpers for that.
Your codebase is already grown by 1000s of lines by using jQuery, so you have quite a head start sizewise if you drop jQuery.
https://twitter.com/mislav/status/1022409388013834240
But this I'd say is very close to BS territory..
The claim is interesting, but isn't evident enough.
For example, how exactly is
var element = document.querySelectorAll('.container')
element.style.paddingTop = "50px";
element.className = element.className + 'header';
communicating intent better than: $('.container').css('padding-top','50').addClass('header')Instead, I'd use one of the various approaches where I can create a style = {} object and then apply it to the element, which would just fit better within the rest of my javascript.
(which particular approach to use, .cssText, looping through props, or Object.assign, I'm not sure, but my point is any approach that applies a POJO to the node instead of chaining strikes me as more idiomatic. this is not a hill I'd die on though...)
el.querySelectorAll('abc').map(el => ...)...
You may need to copy some methods you'd like to use from Array.prototype to NodeList.prototype though, or use .values() from NodeList everywhere.
Many of jQuery's operations implicitly apply to the entire nodeset regardless of the nodeset's arity.
so that I can tread my results as a normal array.
License is MIT.
Unfortunately it seems to be unmaintained.
What's with the trend "jQ is old, old is bad! We need something that does the same thing, and most importantly is not named jQuery"?
CSP is an incredibly useful tool, and it’s close to impossible to use it properly with jQuery.
>By design, any jQuery constructor or method that accepts an HTML string — jQuery(), .append(), .after(), etc. — can potentially execute code
This makes jQuery less safe in general, but I think the CSP restrictions this puts in place are probably a greater issue for most people. I’ve been involved in retro-fitting strict CSPs into a few projects, and more than once I’ve been thwarted by very minor use of jQuery in a couple of places.
But in this case (as in many others), code is written just a couple of times per month, and executed millions of times per day in millions of computers all around the world.
Therefore this kind of "low level JavaScript"* optimizations will have a net benefit much, much bigger than the convenience of reading shorter code for a relatively small group of people.
* Quite the contradiction, I know.
Writing code which just works on multiple browsers results in faster development and easier to maintain code and frees dev cycles to focus on performance.
Perhaps this is the case--jQuery saved them so much time that they've reached a point where they are free to optimize their frontend by removing jQuery.
I know I may be replacing jquery with stimulus or eventually vuejs but writing 5 lines of jquery code for my MVP is exactly the right balance today.
That argument sounds very postmodern. The main issue with perception is that it easily tricked and even more, it can be strongly influenced by bias.
The cumulative effect can surely be measured and reasoned about.
It is very different to program for your new startup idea where adding features faster than your competition is more important than anything else in order to grow your user base, compared to improving an established product already being used by millions of people.
Different needs, different approaches.
I agree that this is an issue, mainly with all kinds of manipulation in politics and product quality/quantity/health impacts but the 5ms vs 2ms execution time of JavaScript is not one of the problems.
I’d focus on humanity gleefully steering itself into a climate collapse and mass ecocide while focusing on all kinds of completely irrelevant bs.
async function printExampleCom() {
let response = await fetch("https://www.example.com/")
// NB: Response has other methods like json.
console.log(await response.text())
}
printExampleCom()
You need a polyfill for `Request` for Safari and Internet Explorer (but not Edge), but that's about it.Or stated differently, "jQuery is just a JS polyfill for browsers that don't support native jQuery yet."
I agree with JQuery for the most simple sites, but React+transpiler will give you much better compatibility
Our company built an in-house front-end framework heavily inspired by React and Vue. The components built using the framework work with or without jQuery. No manual DOM manipulations, one-way data binding, sane state management, templating, etc. Many of us prefer to use jQuery because of how compact and expressive the syntax is.
It really surprises me how many people think that jQuery === old school manual DOM manipulations. It definitely doesn't have to be that way.
React also let's you mark areas/divs within its domain as "don't touch this". So in those areas you can use things like that old map widget you love so much, without resorting to iframes
Angular is a huge fail in this regard. Zero support for mixing with "non angular" pages.
React's entry point is the `ReactDOM.render` function, which takes some React elements, and a root node. that root node can be _any_ DOM node (Actually no idea if you can mount React into a inline SVG, but at least any _HTML_ node you certainly can). You can also have multiple `ReactDOM.render` calls, no problem at all.
That initial React element can very well take values and callbacks from your Angular or whatever application.
It can get messy if you nest `ReactDOM.render` within roots that are managed by React, but so would nesting any other UI framework, but the use cases for that are... Exuberantly exotic, to say the least.
Usually, people have a single “mount point” very close to the <body> element, and a single script file whose primary purpose is to call ReactDOM.render to “mount” a React component representing their application at that point.
However, that doesn’t prevent you from having DOM outside that mount point, and it doesn’t prevent you from having code which does other things that don’t have anything to do with the React-managed part of the page. This is a great way to migrate a legacy application to React: you choose one small section of your page to replace with React, and then have the remainder of your page interact with it by 1.) choosing when to call ReactDOM.render again to ask it to update, and 2.) passing in callbacks so the React ”mini-app” can notify the rest of your application when something happens.
You can go the other way, too, although it’s a little less safe. If you have a React component which renders, say, a <div> with no children, you can get a handle to the DOM element itself and interact with it just like you would in a non-React application. The only constraint here is that you have to make sure to clean up e.g. event handlers and release references to those elements if something causes the “owner” React component to unmount. This is how people make wrapper libraries which let you use non-React-based libraries using React components. (I’ve done this in a side project where I had a huge number homogenous DOM elements to work with, and found that managing them myself was much more performant than trying to run them through React’s model.)
I'm sure experienced people know how to do that properly, but it's really difficult starting out.
Too much abstraction, too much magic. It's possible to do just about anything but the docs are sparse enough that you'll be crawling through github PR's and source to figure out how to achieve it sometimes
Having worked in complex interactive React/Angular apps as well as ones using JQuery, nobody would ever offer me enough to use JQuery again for this use case. They would have to double my pay for all the pain
If I want a fancy drop-down with accessibility support and theming etc, there's probably 50 different libraries with components I can pull in and use with little fuss. A few lines of code to import and register event listeners.
I was a huge user of jQuery for years, and it also has quite nice UI libraries. But the power of React is the standardized scaffold and lifecycle. I can pull in UI components from almost any library and use them intuitively. Mix and match them on the same page.
Trying to do that in jQuery will quickly drag you to hell.
Can you elaborate on this please ? I've used lots of libraries with jquery and haven't encountered problems.
In React you can "scope" a components CSS so none of the styling leaks out
If you want some specific code to criticise, there's dozens of dropdown menu widgets available: here's one I found in Google https://github.com/react-component/menu since I've never actually had reason to use a js/html drop down menu widget.
https://github.com/wisercoder/uibuilder/blob/master/SimpleDe...
For example, in vanilla JS, you might have something like:
const btn = document.createElement('button');
btn.className = 'btn red';
btn.onclick = function(event) {
if (this.classList.contains('red')) {
this.classList.remove('red');
this.classList.add('blue');
} else {
this.classList.remove('blue');
this.classList.add('red');
}
};
In React instead: class Button extends React.Component {
state = { color: 'red' }
handleChange = () => {
const color = this.state.color === 'red' ? 'blue' : 'red';
this.setState({ color });
}
render() {
return (<div>
<button
className=`btn ${this.state.color}`
onClick={this.handleChange}>
</button>
</div>);
}
}
I find it simpler to understand, because render, given its state, describes exactly how the UI should be.For "regular CRUD developers", the vast majority of us, I have zero concern about how big or crazy component code is until it's so huge it impacts page size. I'll use the easiest most feature complete library out there.
React does encapsulation like jQuery never could. I don't care if I have this vanta black box on my page as long as it's easy to mess with and gets the job done
The complexity is shifted to the library that hopefully has thousands of users so is mostly bug free. It simplifies my code at the expense of moving complexity to the shared project. Much preffered since my code will see orders of magnitude less usage than the library itself
jQuery is a DOM manipulation utility library. React is a view rendering library, favoring composition and isolated components.
Many of these can be polyfilled, Going the polyfill route IMHO is a bit better. I use this now : https://polyfill.io .
That polyfill relies on nothing since you can run your own custom 'polyfill' server, or just download the bundle and serve it from your website. It's completely open source.
https://github.com/Financial-Times/polyfill-service
You're complaining that a public CDN runs some analytics. But they all do that, and this project doesn't mandate that you use their CDN.
Huh? http://youmightnotneedjquery.com/#replace_from_html and http://youmightnotneedjquery.com/#before show solutions that work in IE8+ and Edge.
Here it is in the form of a basic polyfill that only supports Elements:
Element.prototype.replaceWith = function(replacement) {
if (typeof replacement === "string") {
replacement = this.ownerDocument.createTextNode(replacement);
}
this.parentNode.replaceChild(this, replacement);
}EDIT: Regarding the polyfill, now you are beginning to write your own little jQuery clone.
Why is that a worthwhile goal?
A polyfill is something that's not needed at all in modern browsers and thus can be considered pretty much final. jQuery is actually surprisingly stable compared to Angular/React/npm/rest-of-the-hipster-crap, but it has had its fair share of incompatibilities too.
Further, there are many better animation libraries.
And finally if you use any view framework you have very little need to be traversing the DOM.
fetch('/my/url').then((r) => r.json()).then((data) => {
})
And as an added bonus, fetch uses promises, so in an async function that's just: let data = await fetch('/my/url').then((r) => r.json()) let data = await (await fetch('/my/url')).json();
That's a one-liner, but you can split the request and json data as well (and you usually want to anyway because of error handling).But if you had a small site that just needed to perform a few DOM manipulations, this would be highly relevant. If I just need to pop a div open and closed when a button is clicked, I sure won't bring in jquery just for that.
The performance question becomes a bit more tricky too then, because instead of comparing direct DOM manipulation you're comparing 'rendering' as a more abstract concept.
$(document).on("click", "#foo", function(){...});
either
document.getElementById('foo').addEventListener('click', function() { ... });
? $(document).on("click", "#foo", function(){...});
is: document.addEventListener('click', function (ev) {
if (ev.target.matches('#foo')) {
}
});
The advantage is that #foo can come and go (after page load be injected and removed and injected again, but the event listener must be registered just once.Since the example is an ID (#foo) the advantage is less obvious. Something like a class (.foo) makes it clearer that there could be many, and it could get expensive to attach an event handler to each one --- though I'm guessing it takes hundreds before it becomes a big deal. But again, .foo's can come and go without having to worry about reattaching the event handler.
P. S. My library, https://github.com/combatentropy/listenup.js (31 lines)
The jquery example delegates #foo, so it can be injected in the page after load and the click event will still work.
But there are ways to mimic the behavior as another person has pointed out.
How so?
You have an instance. You're allowed to call methods or access properties of that instance. You're not supposed to call methods or access properties of properties.
So chaining is just:
$foo.something().somethingelse().blah();
At each point you're getting a new instance and accessing that. You're never reaching inside of a property of that instance.For me it has always been about performance. jQuery is slow. Even way back in the day before JavaScript got fast you could access the DOM quickly if you knew what you were doing. Likewise DOM access could easily make your code 5 times slower if you didn't know what you were doing.
Since 2012 JavaScript has been fast in every major browser and querySelectors are a standard feature. Since about that time accessing the DOM has always been 10s-100s of times faster than using the standard querySelectors. In Firefox it is 10s of thousands of times faster. The standard querySelectors are faster than using modern jQuery.
To me this is the difference between a junior developer and a competent developer. Some people NEED the extra help. I understand that. If product quality and achieving a superior user experience are important though you will simply figure out a better way of writing code, especially since writing code is probably your job.
I've worked with developers who completely ignored good libraries and instead created their own terrible implementations. They got nothing done and what they did was a buggy mess that often needed months of patching.
Finding a good middle ground is the best way to go and when the loading time increases by only a few milliseconds, but the development is a lot faster and cheaper, that's a good compromise in most cases.
In this case every call to the DOM goes from a slow baby crawl to rocket speed. In no other aspect of life do people make such empty excuses, using cliches no less, to intentionally remain in the stone age.
Totally depends on the situation.
And why the assumption that modern versions of jQuery don't make use of modern DOM APIs?
* querySelectors (standard or the home grown Sizzle engine)
* Method chaining for trivial tasks, in many cases to compute data that is already statically present or directly assignable.
Regardless of whether jQuery is using modern APIs or not there are old standards available, to JavaScript, that just about everything in jQuery eventually compiles down to. At the end of the day it becomes a matter of whether writing a couple of 3 line abstractions is far too hard of work or whether it is simply easier to push everything through 65k of jQuery purely for the sake of familiarity.
jQuery has many convenience features such as chaining, for example: item.addClass('selected').siblings().removeClass('selected'); and you don't have to check for nulls after each selection.
Many functions such as closest() and remove() have no equivalents in IE11, and other things such as replaceWith() and before() are not available even in Edge.
For simple sites it is easy enough to remove jQuery, but for more complex javascript applications, especially apps that have a lot of interactivity, removing jQuery will result in more code, or you will end up writing a lot of utility functions thereby creating your own little clone of jQuery.