jQuery patterns

Boilerplate

http://jqueryboilerplate.com/

Quel pattern ?

Créer des modules par fonctionnalité et pas par page !

Essayer de concevoir des modules 

courts

Jouer sur les options pour configurer les modules et les rendre faciles à paramétrer

;(function ($, window, document) {
    "use strict";

    // 1) Nom du module dynamique, facile à changer
    // 2) Liste de variables par défaut (surchargeable)
    // ==> Placer dans cette liste les références aux éléments du DOM à requêter
    //     ==> De préférence des data-attributes
    // ==> Placer les noms des classes d'état (is-visible, ...) 
    var pluginName = "searching",
        defaults = {
            container: '.searchBox',
            hasResultsState: 'has-results',
            resultsContainer: '.js-searchbox-results'
        };

    // Constructeur (à laisser tel quel)
    function Plugin (element, options) {
        this.element = element;
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    [...]
$.extend(Plugin.prototype, {
        hasFocus: false,
        init: function () {
            // Définit impérativement ces 2 méthodes
            this.setElements();
            this.setEvents();
        },
        // Stocker tous les éléments de DOM utiles dans des variables ($xxx)
        // Cela évite de parcourir le DOM trop souvent
        setElements: function() {
            this.$window = $(window);
            this.$element = $(this.element);
            this.$results = this.$element.parent().find(this.settings.resultsContainer);
        },
        // Brancher les événements sur les éléments
        setEvents: function() {
            this.$element.on('focus', $.proxy(this.onFocus, this));
            this.$element.on('blur', $.proxy(this.onBlur, this));
        },
        // Méthodes propres au module (à définir soit même)
        onFocus: function() {
            this.hasFocus = true;
            this.proxySearch = this.proxySearch || $.proxy(this.doSearch, this);
            this.$window.on('keydown', this.proxySearch);
        },
        onBlur: function() {
            this.hasFocus = false;
            this.closeSearch();
            this.$window.off('keydown', this.proxySearch);
        },
        doSearch: function() {
            this.$results.addClass(this.settings.hasResultsState);
        },
        closeSearch: function() {
            this.$element.val('');
            this.$results.removeClass(this.settings.hasResultsState);
        }
    });

[...]
    // Fin du module (à laisser tel quel) 
    $.fn[ pluginName ] = function (options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
        return this;
    };

})(jQuery, window, document);

Déclarer les modules

Utiliser un fichier racine de registry.js

// Exemples
$('[data-preview-src]').mediaPreview();
$('[data-scroll-omniture]').scrollOmniture();

// On peut passer des options et les récupérer dans le module !
$('[data-spastic-nav]').spasticNav(options);

Et aussi...

// Ne jamais cibler les scripts avec les classes BEM
// Utiliser des data-attributes, des classes .js-*** ou des ID.
// Ne pas utiliser les classes js-** en CSS, ni les ID.
// ==> Garantir l'indépendance des scripts et des styles
$('.block__element') => NON
$('.js-machin') => OK
$('[data-truc]') => OK
$('#truc') => OK (à condition que l'ID ne soit pas référencé dans le css)

Vu dans le code...

// Ne JAMAIS déclencher des événements sur des éléments du DOM en JS
// http://davidwalsh.name/dont-trigger-real-event-names
$file.click()

Vu dans le code...

// Extrait de code
classicBlock = widget.find(".card-content")[0];
emptyBlock = widget.find(".card-content")[1];

// CORRECTION
// Le JS va parcourir deux fois le DOM
// alors qu'il peut le faire qu'une seule fois (PERF)
var elm = widget.find(".card-content");
classicBlock = elm[0];
emptyBlock = elm[1];

jQuery patterns

By Julien Herpin

jQuery patterns

  • 910