Jquery ( 8 articles - Voir la liste )

Astuce Bonnes pratiques jQuery

Isoler son code

Pour éviter que ses variables et fonctions ne soient disponibles partout et ne rentrent en conflit entre-elles, il est important d'isoler son code.

Pour cela, plusieurs solutions sont possibles, en fonction des cas.

Code à usage unique

Cela consiste à englober son code pour que les variables et fonctions deviennent locales.

(function($) {

    // Code à exécuter
    // [...]
})(jQuery);

Code à usage régulier

Cela consiste à placer ses variables et fonctions dans un namespace autre que celui par défaut (= lorsqu'on n'en précise pas).

$.myNamespace = {
    multiply: function(x,y) {
        return (x * y);
    }
};

// Appel
var calc = $.myNamespace.multiply(1, 1);

Code affectant des éléments du DOM 1

On utilise le namespace de jQuery : $ ou jQuery.

$.fn.myFunction = function(params) {

    this.css('color', 'red');
    return this;
};

// Appel
$('.element').myFonction();

Explication :

On crée un plugin jQuery, que l'on appelle sur un ensemble d'éléments du DOM (ex: $('.element')). Tous ces éléments sont impactés une fois, sans mémorisation de leur état (= stateless).

Code affectant des éléments du DOM 2

$.widget('ui.trsb.truc.myWidget', [$.ui.widgetParent,]{
    "options": {},
    myWidgetFunction(){...},
    _create: function(){...},
    _destroy: function(){...},
    _setOptions: function(key, value){...},
});

// Appel
$('.element').myWidget();
$('.element').myWidgetFunction();

Explications :

On crée un widget jQuery (nécessite jQueryUI), que l'on appelle sur un ensemble d'éléments du DOM (ex: $('.element')). Tous ces éléments sont impactés avec mémorisation de leur état (= statefull).

Les widgets sont utiles lorsque l'on veut proposer plusieurs méthodes d'action (ex: un accordéon avec une fonction pour dérouler, et une autre pour replier).

Normes de codage et optimisations

Sélecteurs

// Pour des raisons de compatibilité, préférez
$('#container').find('.children').hide();

// à 
$('#container .children').hide();

// ou à 
$('.children', '#container').hide();

Éviter le tout jQuery

$('#link').on('click', function() {

    // Préférez
    this.id

    // à
    $this.attr(id');
});

Chargement du DOM

// Préférez 
$(function() {

});

// à 
$(document).ready(function() {

});

Gestion des évènements

// Préférez 
$('#element').on('click', function() {

});

// à 
$('#element').click(function() {

});

No conflict

// Préférez 
(function($) {
 // [...] Code sans conflit
})(jQuery);

// à 
jQuery.noConflict();
// [...] Code sans conflit

Appels AJAX

// Préférez 
$.ajax()

// à 
$.getJSON();

Astuce Savoir si un case à cocher est cochée

Si dans un formulaire vous avez une checkbox et que vous voulez savoir si elle est cochée, vous pouvez utiliser la fonction is() de jQuery :

jQuery('#ma_checkbox_id').is(':checked')

Par exemple, pour loguer un message lorsqu'on coche/décoche une checkbox :

jQuery('#ma_checkbox_id').on('change', function() {

    // Si la checkbox est cochée
    if (jQuery(this).is(':checked')) {

        console.log('Je viens d\'être cochée !');

    } else {

        console.log('Je viens d\'être décochée !');
    }
});

Astuce Placer une boîte de dialogue au niveau d'un bouton

Par défaut, les boîtes de dialogue de jQuery UI sont centrées verticalement et horizontalement. Cependant, le centrage vertical n'est pas très intelligent et agit par rapport à la hauteur de l'écran, peu importe où on est dans la page.

Imaginons par exemple que votre écran fasse 1200px de hauteur et votre page 2000px. Placez un bouton qui ouvre la pop-up tout en bas de la page, scrollez jusqu'à lui et cliquez dessus. La pop-in s'ouvrira à 600px (environ) du haut de la page, alors que vous serez tout en bas.

Voici une astuce pour la placer à hauteur du bouton :

jQuery('#my-button').on('click', function(event) {

    event.preventDefault();

    jQuery('#my-dialog-confirm').dialog({
        "resizable": false,
        "draggable": false,
        "modal": true,
        "buttons" : {
            "Oui" : function() { 
                jQuery(this).dialog("close");

                // Traitement à effectuer
                // [...]
            },
            "Non" : function() {                
                jQuery(this).dialog("close");
            }
        }
    });

    // Positionnement de la pop-in
    var topOffset = jQuery(this).offset().top - (jQuery('#my-dialog-confirm').height() / 2);
    jQuery('#my-dialog-confirm').dialog( 'option', 'position', ['center', topOffset] );
});

Explications :

  • Au clic sur le bouton, l'élément avec l'ID `my-dialog-confirm``` s'ouvre en fenêtre de dialogue de confirmation, avec les boutons Oui et Non.
  • Après l'ouverture de la pop-in, on la positionne au centre de l'écran en largeur, et la centre en hauteur au niveau du bouton.

Astuce Scroller automatiquement jusqu'à un élément

Voici une petite fonction pour scroller automatiquement vers le haut jusqu'à un élément :

/**
 * Scrolle automatiquement vers le haut jusqu'à l'élément dont le sélecteur est en argument.
 *
 * @param selector string Sélecteur de l'élément vers lequel scroller
 * @param nbMs Nombre de millisecondes pour effectuer l'animation de scroll (facultatif, 10 par défaut)
 */
function scrollToElement(selector, nbMs) {

    nbMs = nbMs || 10;
    var documentBody = (($.browser.chrome)||($.browser.safari)) ? document.body : document.documentElement;
    jQuery(documentBody).animate({scrollTop: jQuery(selector).offset().top}, nbMs, 'linear');
}

Remarques :

  • JQuery doit être inclus dans la page.
  • Depuis jQuery 1.9, la propriété browser a été retirée et transférée dans le plugin jQuery Migrate. Il faut donc ajouter ce plugin pour pouvoir l'utiliser.

Marque-page Timepicker

JQuery UI fournit un datepicker pour agrémenter les champs date d'un petit calendrier. Malheureusement il ne propose pas l'équivalent pour un champ heure.

Premier Datepicker

C'est ce que propose ce site : http://trentrichardson.com/examples/timepicker/.

Premier timepicker

Ce timepicker étends jQuery UI et permet de le combiner ou non avec le datepicker déjà existant.

Remarque :

Le timepicker a été traduit dans de nombreuses langues. Les traductions sont disponibles sur ce repo git.

Second Datepicker

Si vous utilisez le framework Bootstrap, ce site propose un autre timepicker un peu plus agréable à utiliser : http://jdewit.github.io/bootstrap-timepicker/.

Second timepicker

Astuce Savoir quel bouton radio est sélectionné

Si dans un formulaire vous avez deux boutons radio "Oui"/"Non et que vous avez besoin de savoir lequel est sélectionné, vous pouvez utiliser la fonction suivante :

/**
 * Retourne si l'élément radio est à true.
 * 
 * @param elementName Nom de l'élément (attribut "name")
 */
function isChecked(elementName) {

    var element = jQuery('input[name=' + elementName + ']:checked');

    return element != null && element.val() == 1;
}

Remarques :

  • Cette fonction suppose que le bouton radio "Oui" a pour valeur 1 et l'autre 0.
  • Cette méthode peut être utilisée pour une liste de radio plus importante. Il suffit de modifier le test element.val() == 1 par une autre valeur que 1.

Astuce Optimiser l'affichage des animations javascript

Lorsque vous utilisez des animations en Javascript avec jQuery, il arrive que les animations s'emmêlent si elles sont exécutées rapidement les unes après les autres.

Par exemple, si vous construisez un menu en accordéon et que vous cliquez très vite de lien en lien, les menus n'ont pas forcément le temps de se déplier puis se replier.

Vous pouvez remédier à ce problème en utilisant la fonction stop() de jQuery, pour que les animations en cours s'arrêtent avant d'en commencer de nouvelles.

Par exemple :

// Arrêt de toutes les animations en cours sur les éléments du menus
jQuery('#right-menu li.sub-menu-container ul.sub-menu').stop(true, true);

Toutes les animations en cours sur les éléments ul.submenu sont annulées/s'arrêtent instantanément.

Remarque :

Le second paramètre passé à true, permet de terminer les animations en cours instantanément. S'il est à false, les animations se terminent normalement mais toutes celles en attente sont annulées.