Créer un plugin jQuery

jQuery est une librairie de plus en plus utilisée. Les principales raisons qui me poussent à m’en servir sont sa simplicité d’utilisation et l’assurance d’une compatibilité de mon code sur la majorité des navigateurs. Cependant, on peut être rapidement amener à vouloir développer ses propres plugins jQuery pour gagner du temps. Pour illustrer cet article, je vais décrire la réalisation d’un plugin jQuery très léger qui permettra de gérer les attributs personnalisés en HTML5 (cf : HTML5 et les attributs personnalisés) sur tous les navigateurs.

Comment se déroule la création d’un plugin jQuery ?

Quelques explications sur le fonctionnement de jQuery

La classe jQuery a été conçue pour ne pas rester figée. En effet, elle contient directement une méthode pour être étendue : jQuery.extend();. Avant de continuer, il faut savoir que jQuery a deux types de méthodes. Le plus souvent, on l’utilise sur des objets DOM (des éléments HTML) (ex : $('#elmt').attr('href'); renvoie la valeur de l’attribut href de l’élément qui possède id elmt). Mais, il existe également d’autres méthodes comme jQuery.ajax(); qui elles n’ont pas besoin d’avoir de « selecteur » :

  • $('.elmt').each(function(){ ... }) : each est appelé avec un sélecteur et ne s’applique que sur les éléments qui possèdent la classe elmt
  • $.each( obj, function(){ ... }) : each est appelé sans sélecteur.

Pour avoir plus de détails, je vous invite à visiter le site officiel de jQuery.

Dans notre cas, on va créer un plugin jQuery qui récupère des attributs particuliers. On va donc devoir travailler avec un sélecteur.

Fonctionnement de jQuery.extend

Cette méthode permet de fusionner deux (ou plus) objets. Pour ceux qui ont déjà fait du PHP, on peut la rapprocher de la fonction array_merge(). On peut donc l’utiliser de la façon suivante :

var obj1 = { a:'Test', c:'Autre' };
var obj2 = { a:'Super', b:'Cool', d:'Fun' };

var obj = $.extend( obj1, obj2 );

//Alors obj vaut :
obj = { a:'Super', b:'Cool', c:'Autre', d:'Fun' });

Dans le cas de la création d’un plugin jQuery, on peut aller plus vite. En effet, la fonction a été prévue pour étendre rapidement jQuery :

//Ajout de la méthode "maMethode" aux fonctions jQuery
$.fn.extend({
maMethode: function(){
//Code js
}
});

Ici on n’étend pas directement l’objet jQuery mais bien ses fonctions (jQuery.fn) pour pouvoir utiliser le sélecteur d’élément.

Pour que ce code soit fonctionnel, il faut l’exécuter au chargement du document :

(function($){

$.extend({
maMethode: function(){
//Code js
},
uneAutreMethode: function(){
//Code js
}
});

})(jQuery);

Mise en place du plugin jQuery

Tout l’intérêt de rattacher une méthode aux fonctions jQuery est qu’elle sera appelée dans un contexte particulier. En effet, la variable this renverra à la liste des éléments sur lesquels nous voulons agir.

Pour rappel le plugin que je veux faire doit lire ou modifier un attribut data-* d’un ou plusieurs éléments. On ne va pas tout coder de zéro. Là encore, on va se servir des méthodes existantes dans jQuery et en particulier de la méthode attr. En effet cette méthode permet déjà de récupérer ou changer la valeur d’un attribut.

Voici un exemple :

//Retourne la valeur de l'attribut href de l'élément #elmt
$("#elmt").attr("href");

//Change la valeur de l'attribut href par 'http://google.fr'
$("#elmt").attr("href", "http://google.fr");

Il est temps de passer à la pratique. On va décomposer le plugin en deux méthodes. Une première méthode que l’on appellera dataget pour récupérer la valeur d’un attribut data-*, puis, dataset pour modifier une valeur.

La méthode dataget

Cette méthode ne prendra qu’un seul argument, le nom de l’attribut data-* :

//Méthode qui fait appelle à la méthode attr de jQuery
var dataget = function( attName ){
var elmt = $(this);

return elmt.attr( "data-" + attName );
}

La méthode dataset

Cette méthode, elle, prendra deux arguments, le nom de l’attribut et la valeur à y mettre :

//Méthode qui fait appelle à la méthode attr de jQuery
var dataset = function( attName, attValue ){
var elmt = $(this);

elmt.attr( "data-" + attName, attValue );
}

On va améliorer un peu cette méthode pour pouvoir modifier plusieurs attributs en ne passant qu’un objet en paramètre. Pour cela on va détecter le type des arguments et effectuer une action différente en fonction du résultat.

var dataset = function( attName, attValue ){
var elmt = $(this);

if( typeof(attName)=="string" && typeof(attValue)=="string" ){
//Les deux arguments sont des chaines de caractère
//On modifie l'attribut
elmt.attr( "data-" + attName, attValue );

} else if( typeof(attName)=="object" && typeof(attValue)=="undefined" ){
//Il n'y a qu'un unique argument, un objet
//On parcours alors l'objet
for( var i in attName ){
//On fait appelle à la même méthode mais
//cette fois ci avec deux arguments
elmt.dataset( i, attName[i] );
}
} else if( typeof(attName)=="string" && typeof(attValue)=="undefined" ) {
//Il n'y a qu'un unique argument, une chaine de caractères
//On appelle dataget
return elmt.dataget( attName );
}

}

Le comportement de notre fonction sera similaire à celui de la plupart des fonctions jQuery :

//Modifier UNE valeur :
$("#elmt").dataset( "nomDeLattribut", "test" );

//Modifier plusieurs valeurs :
var values = { nomDeLattribut:"test", autreAttribut:"super" };
$("#elmt").dataset( values );

//Récupérer une valeur :
$("#elmt").dataset( "nomDeLattribut" );

Le plugin complet

Le code complet :

(function($){

$.fn.extend({

dataget: function( attName ){

var elmt = $(this);

return elmt.attr( "data-" + attName );

},
dataset: function( attName, attValue ){

var elmt = $(this);

if( typeof(attName)=="string" && typeof(attValue)=="string" ){

elmt.attr( "data-" + attName, attValue );

} else if( typeof(attName)=="object" && typeof(attValue)=="undefined" ){

for( var i in attName )
elmt.dataset( i, attName[i] );

} else if( typeof(attName)=="string" && typeof(attValue)=="undefined" ) {

return elmt.dataget( attName );

}

}

});

})(jQuery);

Ce plugin est assez basique et ne fait que poser les bases de la programmation d’un plugin jQuery. Dans un prochain article, j’aborderai une fonction plus complexe permettant d’aller un peu plus loin.

Laisser une réponse