5 Things You Should Stop Doing With jQuery

stop_header

By Burke Holland

When I first started using jQuery, I was so excited. I was using vanilla JS and really struggling with understanding when elements on a page were ready and how I could access them. When I learned about jQuery, I think I did what many people do. With tears of joy running down my face, I opened up a document ready function and then just vomited up massive amounts of jQuery.

Some of the worst jQuery code ever written was written by me – I can assure you of that.

tumblr_inline_mm6t2vw1RX1qz4rgp

Since then, I’ve spent a few years at the Bayside of jQuery. I’ve had my heart broken a few times and learned a some things along the way. In doing so, I’d like to share 5 things in jQuery that I think you should think twice about doing.

1. Stop Using Document Ready

Back in the day of heavy server frameworks, knowing that your page was fully constructed before you tried to mutate it was a big deal. This was especially true if you were using partial views of some sort that were injected into the layout/master page by the server at runtime.

Nowadays, it’s considered best practice to include your scripts at the bottom of the page. The HTML5 async attribute notwithstanding, scripts are loaded and executed synchronously by the browser. That means that if you have a large script in the head of your page, it will delay loading of the DOM and make your page seem slower than it actually is. Loading all scripts last will at least make your application seem to load faster. It also gives you a chance to use a spinner or loading overlay if you are completely dependent on JavaScript for your UI.

If you are adhering to the “scripts at the bottom” best practice, then you have no need for jQuery’s document ready function as the HTML is already loaded by the time the script is run.

<p id="zack">This element is on the page <strong>BEFORE</strong> all the scripts. No document ready needed.</p>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

  <script type="text/javascript" charset="utf-8">

    // if you include your scripts at the very bottom, you don't need document ready
    (function($) {

      $("#zack").css("color", "green");
      $("#slator").css("color", "red");

    }(jQuery));

  </script>

<p id="slater">This element comes after the scripts and won't be available.</p>

2. Stop Using The Wrong Iterator

I’ve got no hard evidence to back this up, but I’d be willing to guess that the each function is the most used of the jQuery utility methods. I base this on how often I am tempted to use it and how often I see it in other people’s code. It’s incredibly convenient for looping over DOM elements and JavaScript collections. It’s also terse. There is nothing wrong with it, except that its not the only iteration function the jQuery provides. People use each like it’s Zack Morris, at which point every looping problem starts looking like Kelly Kapowski.

MAP

If you have an array of items and you want to loop through it and filter out some of the items, you might be tempted to use the each method like so:

(function($) {

  var allStarCast = [
    { firstName: "Zack", lastName: "Morris" },
    { firstName: "Kelly", lastName: "Kapowski" },
    { firstName: "Lisa", lastName: "Turtle" },
    { firstName: "Screech", lastName: "Powers" },
    { firstName: "A.C.", lastName: "Slater" },
    { firstName: "Jessie", lastName: "Spano" },
    { firstName: "Richard", lastName: "Belding" }
  ]

  // iterate through the cast and find zack and kelly
  var worldsCutestCouple = [];
  $.each(allStarCast, function(idx, actor) {
    if (actor.firstName === "Zack" || actor.firstName === "Kelly") {
      worldsCutestCouple.push(actor);
    }
  });

  console.log(worldsCutestCouple);

}(jQuery));

Try It

That works, but jQuery actually provides a method specifically for this scenario and it’s called map. What it does is takes any items that get returned and adds them to a new array. The looping code then looks like this…

(function($) {

  var allStarCast = [
    { firstName: "Zack", lastName: "Morris" },
    { firstName: "Kelly", lastName: "Kapowski" },
    { firstName: "Lisa", lastName: "Turtle" },
    { firstName: "Screech", lastName: "Powers" },
    { firstName: "A.C.", lastName: "Slater" },
    { firstName: "Jessie", lastName: "Spano" },
    { firstName: "Richard", lastName: "Belding" }
  ]

  // iterate through the cast and find zack and kelly

  var worldsCutestCouple = $.map(allStarCast, function(actor, idx) {
    if (actor.firstName === "Zack" || actor.firstName === "Kelly") {
      return actor;
    }
  });

  console.log(worldsCutestCouple);

}(jQuery));

Try It

Did you notice that the arguments for the .map() callback and the .each() callback are reversed? Watch out for that because it can bite you when you start using map.

The map function allows you to modify the items before they get slapped into the new array. I’m not currently doing that, so technically I’m still not using the “right” iterator. I should really be using grep.

GREP

If you spend most of your days on Windows, then this term might be foreign to you. The term is typically used for a Unix command line utility for searching files that contain text matching a given regular expression.

In jQuery, grep is a function whose purpose is to reduce a collection by removing elements that don’t pass the test in the callback. The provided callback returns a boolean value. Return true if you want the item to remain, and false(y) if you don’t. It will not affect the original array. You cannot modify the items as you reduce them.

(function($) {

  var allStarCast = [
      { firstName: "Zack", lastName: "Morris" },
      { firstName: "Kelly", lastName: "Kapowski" },
      { firstName: "Lisa", lastName: "Turtle" },
      { firstName: "Screech", lastName: "Powers" },
      { firstName: "A.C.", lastName: "Slater" },
      { firstName: "Jessie", lastName: "Spano" },
      { firstName: "Richard", lastName: "Belding" }
  ]

  // iterate through the cast and find zack and kelly

  var worldsCutestCouple = $.grep(allStarCast, function(actor) {
      return (actor.firstName === "Zack" || actor.firstName === "Kelly");
  });

  console.log(worldsCutestCouple);

}(jQuery));

Try It

3. Stop Using “this”

This isn’t a jQuery issue, but jQuery can definitely exacerbate the problem. The context of “this” is always changing. jQuery sometimes changes the context to something that you might not be expecting. In the each callback, this is the current item or element in the collection. In the map function, it’s the window object. You can see how you could get yourself confused pretty quickly.

Have a look at the following example and then we’ll talk about why it blows up.

(function($) {

  var sbtb = {
    log: function(message) {
      $("#log").append("").html(message);
    },
    cast: [
      { firstName: "Zack", lastName: "Morris", soExcited: false },
      { firstName: "Kelly", lastName: "Kapowski", soExcited: true },
      { firstName: "Lisa", lastName: "Turtle", soExcited: true },
      { firstName: "Screech", lastName: "Powers", soExcited: false },
      { firstName: "A.C.", lastName: "Slater", soExcited: false },
      { firstName: "Jessie", lastName: "Spano", soExcited: true },
      { firstName: "Richard", lastName: "Belding", soExcited: false }
    ],
    soExcited: function() {

    // use "this" to get a reference to the cast on this object
    $.each(this.cast, function(idx, actor) {

      // call the log function
      this.log(actor.firstName + " " + actor.lastName); // BOOM! Splosions.
      // "this" is now a cheesy actor, not the sbtb object anymore

    });

    }
  };

  sbtb.soExcited();

}(jQuery));

I wanted to log out everyone who was “so excited”. I’m in an object so I can get a reference to the object with this. Then I loop through the object and look for the “isExcited” flag. However, as soon as I enter the loop callback, the context of this has changed and I can’t access the object anymore.

Since jQuery is changing the scope for you in these loops, it’s a good idea to store the reference to this somewhere so that you know it’s not going to change on you.

(function($) {

  var sbtb = {
    log: function(message) {
      $("#log").append("

").append(message); }, cast: [ { firstName: "Zack", lastName: "Morris", isExcited: false }, { firstName: "Kelly", lastName: "Kapowski", isExcited: true }, { firstName: "Lisa", lastName: "Turtle", isExcited: true }, { firstName: "Screech", lastName: "Powers", isExcited: false }, { firstName: "A.C.", lastName: "Slater", isExcited: false }, { firstName: "Jessie", lastName: "Spano", isExcited: true }, { firstName: "Richard", lastName: "Belding", isExcited: false } ], soExcited: function() { // store this in that so we don't get confused later on when // our the context of "this" changes out from underneath us var that = this; // use "that" to get a reference to the cast on this object $.each(that.cast, function(idx, actor) { // call the log function if (actor.isExcited) { that.log(actor.firstName + " " + actor.lastName); // the value of "that" doesn't change - it's still the object } }); } }; sbtb.soExcited(); }(jQuery));

4. Stop Using ALL THE jQUERIES

jQuery has steadily kept increasing in size. This is only natural as new functionality is added. Even though the size has steadily been reduced since 1.8.3, It’s led to some decry from the community claiming it “unsuitable” for mobile development due to it’s sheer mass.

However, jQuery is not an all or nothing library anymore. jQuery now supports custom builds. I know it’s really tempting to use the jQuery CDN and just rock on, but it is important to think about all the code that you are asking your users to download that they might not even need. That’s no big deal on a desktop, but bits get precious on mobile devices, and there is no point in sending down a bunch of code to support legacy browsers if your app is a mobile one.

You have two choices here. You can head over to the GitHub site and create a custom build with Git. It’s actually really easy and I had no issues getting it to work. But, if pounding out node commands is not your thing, John Resig tweeted about a web UI for custom builds the other day.

5. Stop Using jQuery…

…when you don’t need to.

I got to a point in my development career where the first thing that I did with any project was add jQuery, even if I was just creating very simple projects and samples. I did this mainly so that I could just use the DOM selection utilities. Back in the day of older browsers, this was easier to justify, but modern browsers have this whole DOM selection thing already nailed down for you.

DOCUMENT.QUERYSELECTOR

If you are using at least IE version 8 and above, you can just map the $ to document.querySelector, which will return you the first matched element from the selector. You can pass any CSS selector to the function.

Note that IE 8 only supports CSS 2.1 selectors for querySelector.

<div class="container">
  <ul>
    <li id="pink">Pink</li>
    <li id="salmon">Salmon</li>
    <li id="blue">Blue</li>
    <li id="green">Green</li>
    <li id="red">Red</li>
  </ul>  
</div>

<script>

  // create a global '$' variable
  window.$ = function(selector) {
    return document.querySelector(selector);
  };

  (function() {
    // select item1 by id and change it's background color to salmon
    var item = $("#salmon").style.backgroundColor="salmon";
    console.log(item);
  }());  
</script>

Try It

Of course, there is no chaining when using the native “style” method, so item logs out “salmon” which is what the backgroundColor method returned.

Having a DOM node is sometimes more handy than having a jQuery wrapped one. For instance, let’s say we want to get a reference to an image and change it’s source. Have a look at how you would do it with jQuery as opposed to a straight up DOM node.

// the jQuery way
$("#picture").attr("src", "http://placekitten.com/200/200");

// Vanilla JS with $ mapped to querySelector
$("#picture").src = "http://placekitten.com/200/200";

The DOM object gives you direct access to the “src” property of the image because you have a node of type “image” that has access that property. In the case of jQuery, everything is a jQuery object, so you have to go through the attr function to set the image source.

The document.querySelector method only gets you one element. If you call that on a collection of elements, it will return you only the first matched node. You can use document.querySelectorAll to get the entire list.

DOCUMENT.QUERYSELECTORALL

A neat trick is to map $ to querySelector (1 result) and map $$ to querySelectorAll which will give you all matched DOM elements. The tricky part of this is that querySelectorAll returns a node list which isn’t terribly helpful. You are probably going to need this as an array which you can slice up. You can convert the node list to an array by using Array.prototype.slice.call(nodeList).

<div class="container">
  <ul>
    <li id="pink">Pink</li>
    <li id="salmon">Salmon</li>
    <li id="blue">Blue</li>
    <li id="green">Green</li>
    <li id="red">Red</li>
  </ul>  
</div>

<script>

  // custom lightweight selector implementation
  // nickname: dolla

  window.$ = function(selector) {
    return document.querySelector(selector);
  };

  window.$$ = function(selector) {
    var items = {},
    results = [],
    length = 0,
    i = 0;

    // this doesn't work on IE 8- and Blackberry Browser
    results = Array.prototype.slice.call(document.querySelectorAll(selector));

    length = results.length;

    // add the results to the items object
    for ( ; i < length; ) {
      items[i] = results[i];
      i++;
    }

    // add some additional properties to this items object to 
    // make it look like an array
    items.length = length;
    items.splice = [].splice();

    // add an 'each' method to the items
    items.each = function(callback) {
      var i = 0;
      for ( ; i < length; ) {
        callback.call(items[i]);
        i++;
      }
    }

    return items;
  };

  // end custom selector API

  (function() {

    // select the green item and crank up the font size
    $("#green").style.fontSize = "2em";

    // select item1 by id and change it's background color to salmon
    $$("li").each(function() {
      this.style.backgroundColor = this.id;
    });
  }());

</script>

Try It

Note that converting a nodeList to an array is not supported on IE 8 and below.

At this point you may think to yourself, “That’s a lot of JavaScript to write when I can just include jQuery bro,” and that’s fair. This could be reduced no doubt, but jQuery puts so much convenience on objects and collections that when you start rolling without it, you see what sort of code it takes to recreate just a small piece of it – and this implementation doesn’t even support IE 8 and below or Blackberry browser. Depending on what your application needs to do though, it could be far less code than including jQuery.

Leland Richardson and Jonathan Sampson helped me add a few more features to and clean up the above code. We created a repo called “Dolla“. It’s not meant to be a replacement for jQuery in any way whatsoever, but rather a chance for us to learn what it’s like to say “I don’t need jQuery”. It’s a fair bit more code than you might anticipate.

Stop Reading Articles That Tell You To Stop Doing Something

Seriously though. This is just to underscore the point that these are suggestions, not absolute rules of law. There are a thousand ways that you can argue and or justify any of these items. This is merely to get you thinking about how you use jQuery and how you might be able to do it better than you do now.

So enjoy jQuery, be happy, and stay in school.

74 Comments

  1. Robb said:

    The following:
    (function($) {
    }(jQuery));
    is a short cut for document ready.

    • Joel Kallman said:

      Robb, actually that is not a shortcut for document ready. That is a self-executing anonymous function. It just scopes the variable jQuery as the $ symbol. This would allow you to safely use another library that overwrites the value of the $ variable.

      $(function() {}); is the same as document ready. Notice that you are invoking the jQuery function constructor and passing a function callback as opposed to a selector, like you normally do.

    • Dennis said:

      Robb, your example is not a shortcut for document ready. Your example illustrates a self executing function with jQuery passed as the argument. This will not wait for document to be ready before executing. It only gives you a way to alias jQuery as $. The shortcut for doc ready:

      jQuery(function($){
      // code here
      });

      This also allows you to alias jQuery.

    • sebastian said:

      Nop… you are thinking in $(function (){}); that’s the shortcut. This is just an annonymous self invoking function.

    • Anton said:

      Robb, don’t say that on a javascript job interview – you will be immediately rejected.

    • camainc said:

      Wow, this site must have a time machine function or something. Robb’s comment was posted 33 minutes ago, but the first comment by Joel was posted 14 hours ago. That’s some pretty awesome sauce.

      • remotesynth said:

        @camainc – yeah, a quirk in the template that I need to get fixed.

    • ryan said:

      Actually that isn’t. That is just an immediate function passing in jQuery into the scope.

      You’re thinking of

      $(function (){
      });

    • calm down said:

      Hey everyone, Robb got it wrong. Let’s keep pointing it out and ridiculing him ‘cos it makes us feel all superior ”n’ crap.

      Robb you idiot, how embarrassing. You stupid boy. Ha ha ha. Naa naa na naa na. :P :P :P

      Wow, that’s better – I feel great now.

    • tk said:

      Guys, that’s neither a “self-executing anonymous function” nor “self executing function” or “self-executing function that is run immediately”.
      “annonymous self invoking function” comes closest.

      That’s an immediately-invoked function expression (= IIFE).

      An anonymous function can’t call or execute itself. It just gets immediately invoked …

      tssss, love you all :P

  2. Olivier said:

    Starting from 2.0.0 you can setup a custom build that drops sizzle and you end up having a very nice wrapper around document.querySelectorAll. Check out https://raw.github.com/jquery/jquery/master/src/selector-native.js

    I really think that we won’t need to drop jQuery entirely, even for mobiles, as it is more and more modularized in the future, I am confident we will be able to really extract only what we need from jQuery & get a very tiny footprint for mobile devices.

  3. Brandt Lareau said:

    Great article I was wondering where you were going with this when I read it because it kinda of contradicted it self in some places but I am glad you wrapped it up with Stop Reading Articles That Tell You To Stop Doing Something.

    Thanks again for providing a great example of what you read is not the bible it just a opinion man.

  4. Al Serize said:

    I disagree with your proposition to stop using THIS. Here is why by using this you are saving on having to define a local variable, you are also saving a round trip to get the DOM element since Jquery, or vanilla JS for that matter, has already selected an element of the DOM and has it stored on the variable THIS, THIS is already available and saves on redundancies and an extra round trip to the DOM. I could, however, get very confusing if you don’t know what THIS is at any point in your code or if you don’t organize your JS. Just my 2 cents based purely on experience….

    • Flora X said:

      You’re absolutely right that THIS is extremely useful; I find it helpful, too.

      I think OP meant “Stop using THIS -ALL-the-time-with-no-clarification-” because, as you noted, THIS will get confusing if you don’t meticulously keep track of it. It’s also hard for anyone else to read your code and collaborate with development if you’re the only one who can keep track of your THIS. I benefited a lot from another developer who stored his contexts in VARs with appropriate names. I found that I could easily make sense of all the code and use it as an example to develop my own project.

      Even when I use place-holding variables whenever I can, I still find the need to use THIS pretty often. What I’m saying is, I agree with you that THIS is useful, but I also agree with OP that place-holding variables make the code more readable.

      * I don’t actually know if calling THIS would make a trip to DOM each time or not, so I didn’t address that part of your post. Thanks for pointing it out.

  5. bob said:

    Stay in school? Why? The professor is teaching me about Java. He doesn’t even understand jQuery yet. Sheesh. School is costing me a fortune!

    • xkreperx said:

      Java is a good place to start, and I one doesn´t have to know/understand jQuery to be a pro.

    • Zach said:

      I hope you know that Java and JavaScript are two completely different things. Java is an extremely useful language and used in many many contexts. jQuery is (AFAIK) only run in the browser. Not at all suprising your prof doesn’t know jQuery if he’s not a front-end web-dev.

      And take the following advice with a grain of salt; but if you’re trying to go into CS, expensive schooling might not be the best investment. You can get very far as self-taught, though I’d reccomend community college, or at least a structured approach reccommended by smart folks in the field you’re aspiring to be a part of.

      • drew said:

        I agree. School will only help you understand CS concepts in a structured environment, but to be successful in this field, you need to keep learning beyond school. Once you understand the concepts of CS, the languages change but the fundamental concepts don’t. Coding is not a career. Its a way of life.

    • Alice Young said:

      You could make a fortune developing with Java. Not so much with JQuery/Javascript.

  6. Joe Enos said:

    1) It’s not as simple as that – if you’re using user controls, partial views, master pages, or any similar concept (which I would imagine most people are), you can’t just dump scripts at the bottom, because the bottom of the markup file is not the bottom of the rendered page.

    4) I worry about jQuery custom builds – yes, they work, but anytime you want to use a custom library (one of the thousands of jQuery add-ons), you have to see what jQuery features that library needs, not only in normal scenarios but also in exceptional circumstances. Using and caching the full version of jQuery from the CDN means that there’s zero bandwidth wasted after the first download, so your browser will likely have jQuery before they even visit your site. With a custom build, you’re guaranteed that they have to download your script. The only wasteful part is the execution of the script on load, but executing the jquery.js file is ridiculously fast regardless of what device you’re on.

    5) Remapping $ to document.querySelector is terrible – if you take code that has this and then add jQuery to it later (which is not unreasonable), every piece of script you’ve previously written is now broken. Plus you’ll confuse yourself and other developers looking at your code, as you’re developing and in the future. If you don’t want to use jQuery, that’s fine – but don’t pretend to use it. Write standard javascript, or your own customer wrapper.

    • Dave Schoutens said:

      I tend to agree with your comment on item 1 — scripts at the bottom of the page isn’t necessarily for everyone. For the sites / applications I’ve developed or been involved with, I’ve often found that using a lightweight script loader, such as yepnope (included in Modernizr), to trigger the loading of resources in the HEAD rather than placing them at the bottom of the page to have comparable or better overall performance. Of course, this is in part because most of my recent projects use Modernizr anyway, so given that I’m already blocking rendering in the HEAD waiting for Modernizr to load, I might as well spin up yepnope (Modernizr.load) while I’m at it.

      As for your concern about remapping $ to document.querySelector — I completely disagree. There are plenty more scripts than just jQuery that map themselves to $. ‘$’ is not strictly a jQuery pattern, and using it is not ‘pretending to use jQuery’. I think that if your code is going to use a lot of calls to document.querySelector or document.querySelectorAll, but not a lot of jQuery, then I think it makes perfect sense to use $ and $$, respectively. Turns out, I’ve seen it done plenty of times before, so doing so wouldn’t be out of line with the web development community at large, and consistency is usually a good thing.

      Finally, if you write code like this, and then add jQuery to the project after the fact, none of your old code need be broken — just use jQuery.noConflict() after loading jQuery, or make sure you do your custom ‘$’ remapping after jQuery is loaded.

      • Joe Enos said:

        I suppose I can re-word my position on the $ thing. If you always use the jQuery variable instead of $, you’ll be fine using noConflict and a different meaning for $. Or if you actually wrap all of your jQuery calls inside of an anonymous function mapping $ to jQuery locally, the way plugins do, you’d be ok there too. However, in real life, the overwhelming majority of developers I’ve seen use the global $ variable for jQuery. If you are working with developers who write jQuery all day long and use $ for it, their muscle memory will use $ without thinking about it, and it will conflict, regardless of when the remapping happens.

        Of course you’re right about $ being used in other libraries other than jQuery – but according to some stats (74% of statistics are made up on the spot, but I actually believe this one), more than half the web uses jQuery now – so the $ which represents jQuery is likely an order of magnitude more popular than the next most common one (MooTools?).

    • Zarren said:

      “1) It’s not as simple as that – if you’re using user controls, partial views, master pages, or any similar concept (which I would imagine most people are), you can’t just dump scripts at the bottom, because the bottom of the markup file is not the bottom of the rendered page.”

      You can do this easily in every major framework that comes to mind….except WebForms. Actually, I’d be surprised to find that it wasn’t supported in WebForms as of ASPNet4. Stop using WebForms. The .Net world has largely moved to MVC & WebAPI. If you’re maintaining a WebForms app then you’re SOL.

      • Joe Enos said:

        It’s not just WebForms. Partial views (or partial templates) and layout pages exist in other platforms like ASP.NET MVC and Rails. If I remember, JSP has user controls, and PHP and ColdFusion have partials. I’d expect every other decent platform has the same concepts, whatever they actually call them.

        There’s no “put-this-at-the-bottom-of-the-final-rendered-page” function, so dumping all of your script to the bottom of the page just before the /body tag would require some kind of placeholder. If you have a layout page, a regular view, and a partial view, and the partial has scripts that are supposed to end up at the bottom of the body (defined on the layout page), while the rest of the partial view ends up where it belongs (defined by the regular view), it’s not going to be pretty.

        • Kenneth Truyers said:

          Joe, I agree with you that remapping document.queryselector is and using custom jquery builds is a bad idea, Your first point that it’s not as simple as that, however, is wrong. Every framework that uses either partial views, user controls, partials, … should have a way of letting you include scripts in the bottom of the page. If it doesn’t, you should find a way. Saying the framework doesn’t have support for it, is not a good excuse for litterling you HTML with javascript. ASP.NET MVC has script-sections for example. They let you add scripts to (partial) views which then get rendered on the bottom of the layout-page.

  7. TVD said:

    Using “this” isn’t “bad” per se. It really all depends on function scope and how your code is organized. But, you’re dead on when you advise folks to take some time and analyze when they should use jQuery. Sometimes slowing down and looking ahead makes all the difference.

  8. Jens Roland said:

    While you are right that Array.slice doesn’t accept native NodeLists in IE7/8, it’s trivial to fix this (and very efficient in practice) with a simple loop:

    var nodelist = document.querySelectorAll(selector)
    for (var i = nodelist.length; i–; results.unshift(nodelist[i]));

    One additional line of code and you get oldIE support.

  9. Purushothaman said:

    Nice Article
    The point No3. about the (this) was good i had few issues when i was using it.

    And BTW i too had tears of joy when i started using jQuery.

  10. Bertold von Dormilich said:

    About .map() – there are actually 3 versions of map() involved here:
    - Array.map(), native built-in iterator for Arrays using 3 parameters (item, index, array)
    - $.map(), similar to the native Array.map() method
    - $().map(), which uses the same parameter sequence as $.each()

    So if you have an array (and do not need to care for older IEs) you don’t even need to use jQuery.
    From my experiences, jQuery is great for the UI, but not necessarily needed for business logic.

    PS. $.grep() => Array.filter()

  11. Ryan O’Hara said:

    > Of course, there is no chaining when using the native “style” method, so item logs out “salmon” which is what the backgroundColor method returned.

    backgroundColor isn’t a method, and it doesn’t return anything.

    Regarding the $$ function, why would you create an array-like object with each when you could just, you know, return the array and use forEach?

    Finally:

    > // select item1 by id and change it’s background color to salmon

    *its

  12. Benny said:

    Bad article. “this” is literally one of the best things a dynamic language has. It enables proxy patterns and improves consistency. Furthermore, it makes perfect sense; the likelier case is that you don’t understand it.

    Beyond that, I think “document.ready” still has a very broad use case in the async world — which is soon to be the only world. Even in offline development (e.g. Async calls to load assets etc.) there’s a case for it.

    I don’t personally use jQuery at all — nada — except for work; but it is for different reasons than you listed here.

    • isaac dettman said:

      I fully agree with Benny, bad article. You should only resort to aliasing “this” as a last resort.
      “Stop Reading Articles That Tell You To Stop Doing Something” – I completely agree!

    • Alice Young said:

      You are confused, Benny. “this” helps with closures. Dynamic languages have nothing to do with it.

  13. Andy Matthews said:

    Surprised no one mentioned Zepto.js as a lightweight replacement for jQuery. It’s only 10k and has a near identical API as jQuery.

    • Loïc said:

      Hi Andy, I tried Zepto a few weeks ago for a mobile app development, trying to get a faster solution than jquery.
      At the end, I fall in too many problems with native document querying that zepto rely on and that jquery cares and fix.
      It also appeared that jQuery has a strong cache system that finally made it faster on a real use case than Zepto.
      This is also why I would disagree with the 5) point since for complex manipulation (needing live creation of dom elements with their own events), I think jQuery makes the whole thing work, whereas native implementation (chrome in that case) is far from perfect, and god, such issues are really hard to check and fix ;)

  14. Pingback: Noticias 12-05-2013 - La Web de Programación

  15. IsraelWebDev said:

    As a moderate UNIX user, I believe the array GREP function here more closely resembles the typical use case of extracting lines from a document that match a search pattern, such as

    cat Bayside | grep Zack

    Also, Jessie’s model is incomplete:

    { firstName: “Jessie”, lastName: “Spano”, soExcited: true, soScared: true },

  16. Pingback: Today’s Readings | Aaron T. Grogg

  17. Pingback: A Smattering of Selenium #148 | Official Selenium Blog

  18. Christian said:

    I think you mean “outcry” rather than “decry.”

  19. Pingback: Cheatsheet: 2013 05.01 ~ 05.14 - gOODiDEA.NET

  20. Pingback: Assorted Links | Diminished Utility

  21. Luke Chesser said:

    Good article. Read a similar one a little bit back. Isn’t this a kind-of bad coding convention?
    for ( ; i < length; ) {
    items[i] = results[i];
    i++;
    }

    I realize what it does, but wouldn't it be easier and more clear to just use a while loop?

  22. Akbar said:

    Scripts at bottom is the worst case scenario for automation scripts development. Most of the times, page load completion is checked based on availability of a particular element on the page and since DOM is loaded, it gives incorrect status of the page load completion and cause failures as well.

    • Mark said:

      I am interested in the “scripts at bottom” vs jQuery “on document ready” strategy, but I was puzzled to note that this page loads all its own scripts in the HEAD section. Perhaps this has to do with its blogging setup?

      • Hugh said:

        It looks as a WordPress site and is pretty easy moving the scripts at the bottom of the page using the $in_footer parameter in wp_register_script/wp_enqueue_script

  23. Mathew Porter said:

    Some great points in the article, but for me the key one is ‘stop using jQuery’, not to then use js, but eventually, once doc specs are finalised and all functionality is stable (user base browser / device support permitting) that CSS3 and HTML5 or newer technologies will provide all the support and functionality that jQuery does now.

  24. Pingback: Issue 47 – I’ve Got 99 Problems, But My To-Do List Ain’t One | TLN

  25. Oncle Tom said:

    Hey, nice article. Coding smartly is the best advice we can provide :-)

    However just a small fix, the `$(“#picture”).src` won’t work as `$(“#picture”)` returns an array.
    You have either to do `$(“#picture”).get(0).src`, `$(“#picture”)[0].src` or `document.getElementById(‘picture’).src` to make this working. The caveat is you have to test the existence of the DOM query returned value, as it may not exist.

    Remy Sharp gave a nice talk at jQuery UK this year about this same topic, which can be summarised as “learn the DOM, it’s almost clean now”.
    > http://remysharp.com/2013/04/19/i-know-jquery-now-what/

  26. Pingback: Flat UI Colors, Don't Do's with jQuery and Usability - Treehouse Show Episode 42 - Treehouse Blog

  27. Pingback: Flat UI Colors, Don’t Do’s with jQuery and Usability – Treehouse Show Episode 42 - Learn Every Day

  28. Pingback: Flat UI Colors, Don’t Do’s with jQuery and Usability – Treehouse Show Episode 42 | Html5 Tutorials

  29. Pingback: Flat UI Colors, Don't do's with jQuery and Usability

  30. rpocklin said:

    Apart from #4, I can’t agree with this article. Using this is fine, understanding this is the important part. #1 Not using $(function() {}) – still would do this as a default practise.

    #2 It sounds like the author hasn’t heard of underscore.js or lodash (quoted by others). This gives you _.each, _.map, _.reduce _.filter etc. and IMO read better than JQuery’s.

    #3 use underscore.js and use _.bind(..) to change the context of this.

    I also disagree with #5 except for large performance code. Jquery is pretty much a standard for frontend web development… why go against the grain?

  31. Pingback: Web Performance Resources and Optimization Tools | TechSlides

  32. Nerdy guy said:

    For a guy who is bashing jQuery, your site sure uses a lot of jQuery plugins… anywho I wouldn’t say stop using jQuery, cause it is way easier to work with than javascript, but I would not use others people’s plugin. I would learn to write my own properly.

    • remotesynth said:

      I would kindly suggest you actually read the article rather than just the title. If you read it, you would see that it is far from bashing jQuery but rather about better use of jQuery.

*

*

Top