Thursday, 12 October, 2017 UTC


Summary

Let me begin by saying that this is not yet another post about how you don't need jQuery. In case you haven't noticed, that's already been covered. Roughly 8 million times:
I don't want anyone to stop using jQuery. Use it. Love it. Be happy to keep on coding with it! However, as I've moved away from using it in my own code, I thought I'd share some details on how I've made that transition, specifically the "phases" of my move away and how I'm doing things now. I'll also talk a bit about what I still struggle with.
I will remind people that I don't do a lot of production work. Therefore, I'm not worried about older browsers typically. That makes my needs (probably) different from yours.
How I use jQuery
For me, a vast majority of my jQuery usage was:
  • Bootstrap code on page load
  • Listen for click or change events to things
  • Read values from form fields
  • Ajax stuff
  • Write HTML to the DOM
Certainly I did more than that, but in terms of what I was specifically using jQuery for, that probably covers 99% of it.
Page Load
Nearly every application I worked on started with this beauty:
$(document).ready(function() {
    // STUFF HERE
});
This was to the point where I had this as a snippet so I could drop it in files quickly. Heck, I even caught myself with this code in pages where I wasn't even doing any JavaScript.
I replaced this with an event listener on DOMContentLoaded:
document.addEventListener('DOMContentLoaded', function() {
    // STUFF HERE

}, false);
The MDN docs for this event says:
The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.
This is an easy change. It is a bit more typing, but snippets in your editor can make that a non-issue. However, note that this is not a perfect replacement for jQuery's document.ready functionality. Their docs mention this issue:
Most browsers provide similar functionality in the form of a DOMContentLoaded event. However, jQuery’s .ready() method differs in an important and useful way: If the DOM becomes ready and the browser fires DOMContentLoaded before the code calls .ready( handler ), the function handler will still be executed. In contrast, a DOMContentLoaded event listener added after the event fires is never executed.
The last sentence is the crucial one. I've never run into this issue myself, but it is something you will want to keep in mind.
Event Listeners
I already demonstrated it, but you simply use addEventListener and you're good to go. The general format is (the thing).addEventListener('name of event', function) and, as I said above, while it is a bit more typing then jQuery's version, it typically isn't a big deal.
The only real problem I've had with this was something that came up recently. Imagine you want to listen for click events on products. Now imagine the products are loaded after the initial page load. jQuery provides support for this by letting you listen for an event on the document object, but then specify that you only care if the target was some specific item inside it. That basic form is:
$("#listOfProducts").on("click", ".productThumb", function() { 
    // STUFF
});
I recently had to do this in another app and realized I wasn't sure how to get that done. This is what I ended up with:
document.addEventListener('click', function(e) {
    if(e.target.className !== 'editLink') return;
    e.preventDefault();

    // STUFF    
}, false);
Basically I just look at the event's target data and see if it makes sense for my logic. In the case above, I'm looking if a CSS class "editLink" was applied, and if so, I continue on.
Getting DOM Items
This one's the easiest. jQuery made it easy to get access to a DOM item with selectors: $(selector). Modern browsers provide similar support with querySelector and querySelectorAll. querySelector would be used when you know you are matching one item, like a form field or a div, and querySelectorAll would be used to match multiple items. I can't honestly remember every using querySelectorAll although I'm sure I will in the future.
I prefer to prefix variables created with this API with $. So for example:
let $field1 = document.querySelector('#field1');
let $field2 = document.querySelector('#field2');
This just reminds me that the variables are pointers to DOM items.
Reading and Writing DOM Items
So after I've got access to something in the DOM, I typically have to read from them and set them. For a form field this is fairly easy – you just use .value. The only issue I think you will run into would be working with checkboxes and radio fields. I haven't had to worry about that yet actually so therefore I've not had to deal with it.
Writing HTML inside a DOM element is also simple – instead of $something.html(string), you would use $something.innerHTML=string.
Again – jQuery definitely helps here with a simpler API and by covering edge cases, but I've been able to get by with the samples above.
Enter the Ajax
Ok, so you'll notice everything so far has involved basic DOM manipulation. I found that easy enough and when I didn't, I'd just hit up MDN and spend a few minutes reading. The main thing that held me from completely leaving jQuery was working with Ajax.
Doing Ajax "by hand" is not terribly difficult. You can read about it on (of course) MDN – AJAX – Getting Started. But I could never quite memorize the flow of working with the XMLHttpRequest object.
Luckily, the Fetch API came along, and while I'm still a bit shaky with it, I love the simplicity of the API. I've done a few blog posts already on it, but here is a quick example of how it looks:

fetch('/data.json')
.then(res => res.json())
.then(res => {
    // res is my data
});
You can do regular GET requests as well as POSTs with form data. Basically anything you could do with jQuery or vanilla XHR you can do with Fetch.
What's Left?
Now that I'm comfortable getting, reading from, and manipulating DOM items and doing Ajax, the one area I've run into trouble with is DOM traversal. So for example, finding something in the DOM but actually wanting the previous or next item. jQuery makes this trivial with things like .prev() or .next(). There is a good resource for this and it's one of those "you don't need jQuery" sites. The site? youmightnotneedjquery.com. Nicely named, right? It has specific examples of .prev() and .next() and other DOM traversal items I rarely need, but I'm glad to know I can lookup when I need it.
Another useful resource, and one with an easy to remember name, is plainjs.com. It too contains a "jQuery to not-jQuery" index of resources for translating your code.
I'd be curious to hear how others are doing on their move from jQuery, if, of course, that's what you're actually doing. If you have specifically decided to not move from jQuery then I'd like to hear about that as well. Just drop me a comment below!
The post How I’m (Not) Using jQuery appeared first on Telerik Developer Network.