Table des matières

Bonnes pratiques jQuery

Sources :
http://chez-syl.fr/2012/03/bonnes-pratiques-jquery/
http://www.lejournaldublog.com/jquery-les-bonnes-pratiques/

Les sélecteurs

Lorsque vous êtes amené à utiliser un objet jQuery plus d'une fois dans votre fonction ou votre script entier, mettez cet objet dans une variable, et de préférence avec un dollar devant de sorte à tout de suite reconnaitre un objet jQuery d'une variable classique qui contient une simple valeur.

Pas bien

var el = $('#element');

Bien

var $el = $('#element');

C'est la même chose pour le $(this) :

Pas bien

$('#element').on('click', function() {
    var href = $(this).attr('href');
    var text = $(this).text();
 
    return false;
});

Bien

$('#element').on('click', function() {
    var $this = $(this);
    var href = $this.attr('href');
    var text = $this.text();
 
    return false;
});

Si vous pouvez mettre un id à votre élément alors ne vous en privez pas ! En effet il reste le sélecteur le plus rapide. D'ailleurs, si l'on souhaite accéder à un id, il ne faut pas renseigner le nom de l'élément avant sinon le DOM utilisera d'abord getElementsByTagName() puis getElementById().

Pas bien

var $el = $('div#element');

Bien

var $el = $('#element');

Quand vous voulez sélectionnez plusieurs éléments, indiquez - si possible - l'id du parent le plus proche.

Pas bien

var $div = $('div');

Bien

var $div = $('#main div');

Pour la sélection de class, il faut - contrairement à l'id - indiquer le nom de l'élément concerné. Encore mieux, indiquer également l'id du parent le plus proche.

Pas bien

var $image = $('div.image');
var $image = $('#main .image');
var $image = $('.image');

Bien

var $image = $('#main div.image');

Le chaînage

Vous êtes censé savoir qu'une grande force de jQuery réside dans le chainage des méthodes sur un sélecteur.

Pas bien

$('#element').hide();
$('#element').css('background-color', 'yellow');
$('#element').fadeIn('slow');
var $el = $('#element');
$el.hide();
$el.css('background-color', 'yellow');
$el.fadeIn('slow');

Bien

$('#element')
    .hide()
    .css('background-color', 'yellow')
    .fadeIn('slow');

Mise à jour du DOM

Injecter du HTML dans le DOM s'avère couteux en ressources, surtout dans une boucle. Il est préférable de mettre le contenu à ajouter dans une variable et de l'ajouter une fois la boucle terminée.

Pas bien

var tableau = [...]; // des données
 
for (var i in tableau) {
    $('#liste')
        .append('<li>' + tableau[i] + '</li>');
}

Bien

var tableau = [...]; // des données
var puces = '';
 
for (var i in tableau) {
    puces += '<li>' + tableau[i] + '</li>';
}
$('#liste').append(puces);

Exploiter la délégation d’évènement

En Javascript, chaque évènement est remonté aux éléments parents le long de l'arborescence du DOM. C'est extrêmement pratique quand nous voulons que plusieurs éléments fils (nodes) appellent une même fonction.

Plutôt que d'associer une fonction de listener d’évènements à plusieurs nodes (très peu efficace) vous pouvez l'associer une fois pour toute à leur parent, en le laissant se débrouiller avec l'élément fils qui a déclenché l’évènement.

Par exemple, nous développons un gros formulaire avec beaucoup de champs, et nous voulons changer la classe d'un champ lorsque ce dernier est sélectionné.

Pas bien

Une association telle que celle-ci n'est pas du tout optimisée

$('#entryform input).bind('focus', function(){
  $(this).addClass('selected');
}).bind('blur', function(){
  $(this).removeClass('selected');
});

Bien

A la place, nous devrions surveiller les événements de focus et de blur au niveau du parent

$('#entryform).bind('focus', function(e){
 
var cell = $(e.target);      // e.target récupère l'élément qui a
 cell.addClass('selected');  // déclenché l'événement.
 
}).bind('blur', function(e){
 
var cell = $(e.target);
 cell.removeClass('selected');
 
});

L'élément parent agit comme un dispatcher et peut ainsi travailler sur l'élément fils cible qui a déclenché l'événement. Si vous associez un même listener à plusieurs éléments, faite attention, vous êtes en train de coder quelque chose de très lent !

Déléguez à $(window).load

Il y a une tentation parmi tous les développeurs jQuery à associer toutes leurs fonctions à l'événement $(document).ready.

Après tout, il est utilisé dans la plupart des exemples que vous trouverez sur le web, pourquoi changer ? $(document).ready se déclenche pendant le rendering de la page par le navigateur, c'est-à-dire au même moment où des éléments sont encore téléchargé par ce dernier.

Si vous remarqué un ralentissement du navigateur durant le chargement de la page, toutes ces fonctions $(document).ready en sont peut-être la raison.

Vous pouvez réduire l'utilisation CPU en affectant toutes vos fonctions jQuery à l'événement $(window).load qui est déclenché après que tous les objets appelés par le HTML soit téléchargés. (Y compris le contenu des iframes).

$(window).load(function(){
 // Fonctions jQuery a initialiser après que la page ait été chargée.
});

Les fonctionnalités "superflues" telles que les drap-n-drop, effets visuels et animations, pré-chargements des images… etc… sont de bonnes candidates pour cette technique.

Questions

Quel est le mieux ou même la différence entre :

$foo.find('div.bar');
$('div.bar', $foo);

Et

$('#foo div.bar');
$('div.bar', '#foo');