jQuery pitfalls to avoid

JavascriptJquery

Javascript Problem Overview


I am starting a project with jQuery.

What pitfalls/errors/misconceptions/abuses/misuses did you have in your jQuery project?

Javascript Solutions


Solution 1 - Javascript

Being unaware of the performance hit and overusing selectors instead of assigning them to local variables. For example:-

$('#button').click(function() {
    $('#label').method();
    $('#label').method2();
    $('#label').css('background-color', 'red');
});

Rather than:-

$('#button').click(function() {
    var $label = $('#label');
    $label.method();
    $label.method2();
    $label.css('background-color', 'red');
});

Or even better with chaining:-

$('#button').click(function() {
    $("#label").method().method2().css("background-color", "red"); 
});

I found this the enlightening moment when I realized how the call stacks work.

Edit: incorporated suggestions in comments.

Solution 2 - Javascript

Understand how to use context. Normally, a jQuery selector will search the whole doc:

// This will search whole doc for elements with class myClass
$('.myClass');

But you can speed things up by searching within a context:

var ct = $('#myContainer');
// This will search for elements with class myClass within the myContainer child elements
$('.myClass', ct);

Solution 3 - Javascript

Don't use bare class selectors, like this:

$('.button').click(function() { /* do something */ });

This will end up looking at every single element to see if it has a class of "button".

Instead, you can help it out, like:

$('span.button').click(function() { /* do something */ });
$('#userform .button').click(function() { /* do something */ });

I learned this last year from Rebecca Murphy's blog

Update - This answer was given over 2 years ago and is not correct for the current version of jQuery. One of the comments includes a test to prove this. There is also an updated version of the test that includes the version of jQuery at the time of this answer.

Solution 4 - Javascript

Try to split out anonymous functions so you can reuse them.

//Avoid
$('#div').click( function(){
   //do something
});

//Do do
function divClickFn (){
   //do something    
}

$('#div').click( divClickFn );

Solution 5 - Javascript

While using $.ajax function for Ajax requests to server, you should avoid using the complete event to process response data. It will fire whether the request was successful or not.

Rather than complete, use success.

See Ajax Events in the docs.

Solution 6 - Javascript

  • Avoid abusing document ready.
  • Keep the document ready for initialize code only.
  • Always extract functions outside of the doc ready so they can be reused.

I have seen hundreds of lines of code inside the doc ready statement. Ugly, unreadable and impossible to maintain.

Solution 7 - Javascript

If you bind() the same event multiple times it will fire multiple times . I usually always go unbind('click').bind('click') just to be safe

Solution 8 - Javascript

"Chaining" Animation-events with Callbacks.

Suppose you wanted to animate a paragraph vanishing upon clicking it. You also wanted to remove the element from the DOM afterwards. You may think you can simply chain the methods:

$("p").click(function(e) {
  $(this).fadeOut("slow").remove();
});

In this example, .remove() will be called before .fadeOut() has completed, destroying your gradual-fading effect, and simply making the element vanish instantly. Instead, when you want to fire a command only upon finishing the previous, use the callback's:

$("p").click(function(e){
  $(this).fadeOut("slow", function(){
    $(this).remove();
  });
});

The second parameter of .fadeOut() is an anonymous function that will run once the .fadeOut() animation has completed. This makes for a gradual fading, and a subsequent removal of the element.

Solution 9 - Javascript

Don't abuse plug-ins.

Most of the times you'll only need the library and maybe the user interface. If you keep it simple your code will be maintainable in the long run. Not all plug-ins are supported and maintained, actually most are not. If you can mimic the functionality using core elements I strongly recommend it.

Plug-ins are easy to insert in your code, save you some time, but when you'll need an extra something, it is a bad idea to modify them, as you lose the possible updates. The time you save at the start you'll loose later on changing deprecated plug-ins.

Choose the plug-ins you use wisely. Apart from library and user interface, I constantly use $.cookie , $.form, $.validate and thickbox. For the rest I mostly develop my own plug-ins.

Solution 10 - Javascript

Pitfall: Using loops instead of selectors.

If you find yourself reaching for the jQuery '.each' method to iterate over DOM elements, ask yourself if can use a selector to get the elements instead.

More information on jQuery selectors:
http://docs.jquery.com/Selectors

Pitfall: NOT using a tool like Firebug

Firebug was practically made for this kind of debugging. If you're going to be mucking about in the DOM with Javascript, you need a good tool like Firebug to give you visibility.

More information on Firebug: http://getfirebug.com/

Other great ideas are in this episode of the Polymorphic Podcast: (jQuery Secrets with Dave Ward) http://polymorphicpodcast.com/shows/jquery/

Solution 11 - Javascript

Misunderstanding of using this identifier in the right context. For instance:

$( "#first_element").click( function( event)
{
   $(this).method( ); //referring to first_element
   $(".listOfElements").each( function()
   {
      $(this).someMethod( ); // here 'this' is not referring first_element anymore.
   })
});

And here one of the samples how you can solve it:

$( "#first_element").click( function( event)
{
   $(this).method( ); //referring to first_element
   var $that = this;
   $(".listOfElements").each( function()
   {
      $that.someMethod( ); // here 'that' is referring to first_element still.
   })
});

Solution 12 - Javascript

Avoid searching through the entire DOM several times. This is something that really can delay your script.

Bad:

$(".aclass").this();
$(".aclass").that();
...

Good:

$(".aclass").this().that();

Bad:

$("#form .text").this();
$("#form .int").that();
$("#form .choice").method();

Good:

$("#form")
    .find(".text").this().end()
    .find(".int").that().end()
    .find(".choice").method();

Solution 13 - Javascript

Always cache $(this) to a meaningful variable especially in a .each()

Like this

$(selector).each(function () {
    var eachOf_X_loop = $(this); 
})

Solution 14 - Javascript

Similar to what Repo Man said, but not quite.

When developing ASP.NET winforms, I often do

$('<%= Label1.ClientID %>');

forgetting the # sign. The correct form is

$('#<%= Label1.ClientID %>');

Solution 15 - Javascript

Events

$("selector").html($("another-selector").html());

doesn't clone any of the events - you have to rebind them all.

As per JP's comment - clone() does rebind the events if you pass true.

Solution 16 - Javascript

Avoid multiple creation of the same jQuery objects

//Avoid
function someFunc(){
   $(this).fadeIn();
   $(this).fadeIn();
}

//Cache the obj
function someFunc(){
   var $this = $(this).fadeIn();
   $this.fadeIn();
}

Solution 17 - Javascript

I say this for JavaScript as well, but jQuery, JavaScript should NEVER replace CSS.

Also, make sure the site is usable for someone with JavaScript turned off (not as relevant today as back in the day, but always nice to have a fully usable site).

Solution 18 - Javascript

Making too many DOM manipulations. While the .html(), .append(), .prepend(), etc. methods are great, due to the way browsers render and re-render pages, using them too often will cause slowdowns. It's often better to create the html as a string, and to include it into the DOM once, rather than changing the DOM multiple times.

Instead of:

var $parent = $('#parent');
var iterations = 10;

for (var i = 0; i < iterations; i++){
	var $div = $('<div class="foo-' + i + '" />');
	$parent.append($div);
}

Try this:

var $parent = $('#parent');
var iterations = 10;
var html = '';

for (var i = 0; i < iterations; i++){
	html += '<div class="foo-' + i + '"></div>';
}

$parent.append(html);

Or even this ($wrapper is a newly created element that hasn't been injected to the DOM yet. Appending nodes to this wrapper div does not cause slowdowns, and at the end we append $wrapper to $parent, using only one DOM manipulation):

var $parent = $('#parent');
var $wrapper = $('<div class="wrapper" />');
var iterations = 10;

for (var i = 0; i < iterations; i++){
	var $div = $('<div class="foo-' + i + '" />');
	$wrapper.append($div);
}

$parent.append($wrapper);

Solution 19 - Javascript

Using ClientID to get the "real" id of the control in ASP.NET projects.

jQuery('#<%=myLabel.ClientID%>');

Also, if you are using jQuery inside SharePoint you must call jQuery.noConflict().

Solution 20 - Javascript

Passing IDs instead of jQuery objects to functions:

myFunc = function(id) { // wrong!
    var selector = $("#" + id);
    selector.doStuff();
}

myFunc("someId");

Passing a wrapped set is far more flexible:

myFunc = function(elements) {
    elements.doStuff();
}

myFunc($("#someId")); // or myFunc($(".someClass")); etc.

Solution 21 - Javascript

Excessive use of chaining.

See this:

this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);

Explanation

Solution 22 - Javascript

Use strings accumulator-style

Using + operator a new string is created in memory and the concatenated value is assigned to it. Only after this the result is assigned to a variable. To avoid the intermediate variable for concatenation result, you can directly assign the result using += operator. Slow:

a += 'x' + 'y';

Faster:

a += 'x';
a += 'y';

Primitive operations can be faster than function calls

Consider using alternative primitive operation over function calls in performance critical loops and functions. Slow:

var min = Math.min(a, b);
arr.push(val);

Faster:

var min = a < b ? a : b;
arr[arr.length] = val;

Read More at JavaScript Performance Best Practices

Solution 23 - Javascript

If you want users to see html entities in their browser, use 'html' instead of 'text' to inject a Unicode string, like:

$('p').html("Your Unicode string")

Solution 24 - Javascript

my two cents)

Usually, working with jquery means you don't have to worry about DOM elements actual all the time. You can write something like this - $('div.mine').addClass('someClass').bind('click', function(){alert('lalala')}) - and this code will execute without throwing any errors.

In some cases this is useful, in some cases - not at all, but it is a fact that jquery tends to be, well, empty-matches-friendly. Yet, replaceWith will throw an error if one tries to use it with an element which doesn't belong to the document. I find it rather counter-intuitive.

Another pitfall is, in my opinion, the order of nodes returned by prevAll() method - $('<div><span class="A"/><span class="B"/><span class="C"/><span class="D"/></div>').find('span:last-child').prevAll(). Not a big deal, actually, but we should keep in mind this fact.

Solution 25 - Javascript

If you plan to Ajax in lots of data, like say, 1500 rows of a table with 20 columns, then don't even think of using jQuery to insert that data into your HTML. Use plain JavaScript. jQuery will be too slow on slower machines.

Also, half the time jQuery will do things that will cause it to be slower, like trying to parse script tags in the incoming HTML, and deal with browser quirks. If you want fast insertion speed, stick with plain JavaScript.

Solution 26 - Javascript

Using jQuery in a small project that can be completed with just a couple of lines of ordinary JavaScript.

Solution 27 - Javascript

Not understanding event binding. JavaScript and jQuery work differently.

By popular demand, an example:

In jQuery:

$("#someLink").click(function(){//do something});

Without jQuery:

<a id="someLink" href="page.html" onClick="SomeClickFunction(this)">Link</a>
<script type="text/javascript">
SomeClickFunction(item){
    //do something
}
</script>

Basically the hooks required for JavaScript are no longer necessary. I.e. use inline markup (onClick, etc) because you can simply use the ID's and classes that a developer would normally leverage for CSS purposes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionflybywireView Question on Stackoverflow
Solution 1 - JavascriptGavin GilmourView Answer on Stackoverflow
Solution 2 - JavascriptslolifeView Answer on Stackoverflow
Solution 3 - JavascriptBrianHView Answer on Stackoverflow
Solution 4 - JavascriptredsquareView Answer on Stackoverflow
Solution 5 - JavascriptArtem BargerView Answer on Stackoverflow
Solution 6 - JavascriptredsquareView Answer on Stackoverflow
Solution 7 - JavascriptScott EverndenView Answer on Stackoverflow
Solution 8 - JavascriptSampsonView Answer on Stackoverflow
Solution 9 - JavascriptElzo ValugiView Answer on Stackoverflow
Solution 10 - JavascriptDan EsparzaView Answer on Stackoverflow
Solution 11 - JavascriptArtem BargerView Answer on Stackoverflow
Solution 12 - JavascriptgoogletorpView Answer on Stackoverflow
Solution 13 - JavascriptadardesignView Answer on Stackoverflow
Solution 14 - JavascriptRonView Answer on Stackoverflow
Solution 15 - JavascriptChris SView Answer on Stackoverflow
Solution 16 - JavascriptredsquareView Answer on Stackoverflow
Solution 17 - JavascriptMartinView Answer on Stackoverflow
Solution 18 - JavascriptAlex HeydView Answer on Stackoverflow
Solution 19 - JavascriptJacobs Data SolutionsView Answer on Stackoverflow
Solution 20 - JavascriptCraig StuntzView Answer on Stackoverflow
Solution 21 - JavascriptSolutionYogiView Answer on Stackoverflow
Solution 22 - JavascriptPir AbdulView Answer on Stackoverflow
Solution 23 - JavascriptPatrick J. AndersonView Answer on Stackoverflow
Solution 24 - JavascriptshabuncView Answer on Stackoverflow
Solution 25 - JavascriptmkoryakView Answer on Stackoverflow
Solution 26 - JavascriptviseView Answer on Stackoverflow
Solution 27 - JavascriptJasonView Answer on Stackoverflow