Comment créer facilement un framework JavaScript Partie 1

KalyParker

Traduction de l'article How to Easily Create a JavaScript Framework, Part 1 de Teylor Feliz paru sur AdmixWeb.
Translated with the permission of AdmixWeb and the author.

Commentez ?

- Titre : Comment créer facilement un framework JavaScript Partie 1

- Auteur : KalyParker

- Parution : 26 janvier 2010

- Mise à jour : 13 octobre 2010

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2020 Teylor Feliz. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.

Sommaire

- I. Introduction

- II. Éviter les variables globales

- III. Création de l'objet principal/framework

- IV. La navigation DOM partie 1

- V. Méthode de Chaînage

- VI. Conclusion

- VII. Remerciements

I - Introduction

Actuellement, JavaScript est l'un des langages de programmation les plus utilisés et les plus populaires sur Internet, car une grande majorité des navigateurs sont compatibles et l'utilisent. JavaScript s'est donc rapidement répandu, car il est simple d'utilisation, précis, et possède un vaste champ d'action. La plupart des programmeurs ont eu l'habitude de croire que JavaScript était un langage futile, mais l'émergence d'AJAX sur le marché a prouvé le contraire, en nous montrant les capacités et fonctionnalités de JavaScript. Depuis cette découverte, les programmeurs peuvent créer des applications Web qui ressemblent à des applications de bureau, ce qui est très utile, car les données peuvent être modifiées plus rapidement.

Cependant, l'utilisation du DOM (Document Object Model) dans les navigateurs, comme Internet Explorer, rend parfois la tâche difficile. C'est la raison pour laquelle les frameworks JavaScript fleurissent sur le marché, rendant ainsi le scripting multinavigateur possible. De nombreux frameworks JavaScript à la mode tels que Prototype, JQuery, YUI et Dojo ont été utilisés ces cinq dernières années par beaucoup de développeurs à travers le monde pour créer d'étonnantes applications Web. Maintenant, je vais vous apprendre pas à pas à créer un framework JavaScript, en utilisant de simples effets DOM et quelques fonctions utiles en AJAX. Nous espérons que vous pourrez utiliser ces informations et apprendre à les mettre en œuvre par vous-même.

II - Éviter les variables globales

Avant de commencer à créer le framework VOZ, vous devez savoir qu'il faut éviter d'utiliser des variables globales dans toutes les pages, car JavaScript utilisera la dernière déclaration de la variable avec sa valeur associée sans avertir que cette variable a déjà été déclarée auparavant dans le code.
Par exemple :

var x = 23; // Déclaration et utilisation de la variable x avec initialisation de sa valeur à 23
var x = 44; // Affectation de la valeur 44 à la variable sans avertir que la variable a déjà été déclarée
x;  // La valeur actuelle est 44

Une bonne méthode pour éviter les variables globales est de créer une fonction anonyme qui restreint la portée de la variable à la fonction.
Par exemple :

(function(){

// Les variables et les fonctions se trouvent ici

})();

Les fonctions anonymes sont très utiles lorsque nous travaillons avec des frameworks JavaScript, car nous pouvons les utiliser comme paramètre de nos fonctions. Nous verrons cela plus tard.

III - Création de l'objet principal/framework

Il est désormais admis qu'en JavaScript il y a deux façons de créer des objets : en utilisant un constructeur ou en utilisant un objet littéral.

En utilisant un constructeur :

// Définition de l'objet/Classe Utilisateur avec deux paramètres "prenom et nom".
function Utilisateur(prenom, nom){
this.prenom = prenom;
this.nom = nom;
}
// Pour utiliser la classe Utilisateur avec new
var monUtilisateur = new Utilisateur('Carl','Anderson');
monUtilisateur.prenom // Cela renvoi "Carl"

En utilisant un objet littéral

La deuxième manière, la plus recommandée par les experts comme Douglas Crockford, est d'utiliser un objet littéral. C'est cette dernière que nous allons utiliser pour créer notre framework, parce que c'est la plus élégante et la plus efficace façon de créer des objets.
Par exemple :

monUtilisateur = {
prenom: 'Carl',
nom: 'Anderson'
};
monUtilisateur.prenom // Renvoi "Carl"

Bien, c'est suffisant pour la théorie, passons à l'action et créons notre framework. Tout d'abord, choisissez un nom court et attractif pour votre framework. Dans cet exemple, nous utiliserons le nom « VOZ ».
Par exemple :

// On protège la fonction principale du framework pour éviter des erreurs imprévisibles avec d'autres frameworks ou variables.
(function (){
// Création du framework VOZ
var VOZ = {}
})();

Maintenant notre framework est prêt, mais nous devons encore créer un certain nombre de propriétés et méthodes. Pour l'instant, nous allons ajouter les méthodes « getById », « addClass » et « on ».

(function(){

var VOZ = {
// Le tableau elems va contenir tous les éléments les uns derrière les autres dans l'ordre
elems :[],
// Méthode pour récupérer les éléments par Id
getById:function(){},
// Méthode pour ajouter une classe CSS
addClass:function(){},
// Méthode pour ajouter un événement sur nos éléments
on:function(){},
// Ajoute du texte dans un élément
appendText:function(){}
// Affiche/Masque
toggleHide:function(){}
}
})() ;

IV - La navigation DOM partie 1

Savoir utiliser DOM (Document Object Model) est vital pour un programmeur JavaScript, car cela donne la capacité de modifier, supprimer ou ajouter de nouveaux éléments à des emplacements spécifiques sur la page Web.

Pour l'instant nous allons voir la méthode « getById; » cependant, ce n'est pas la méthode « document.getElementById » normale, car celle-ci prend plus d'un paramètre pour trouver les éléments par leur ID.
Par exemple :

// Récupère tous les éléments par ID
// Peut prendre plus d'un paramètre
getById:function(){
var tempElems = []; // tableau temporaire pour sauvegarder les éléments trouvés
for(var i = 0; i<arguments.length; i++){
if(typeof arguments[i] === 'string'){ // Vérifie que le paramètre est une chaine
tempElems.push(document.getElementById(arguments[i])); // Ajoute l'élément à tempElems
}
}
this.elems = tempElems; // Tous les éléments sont copiés dans la propriété elems
return this; // Renvoie this dans l'ordre d'appel
},

Nous avons ainsi une méthode pour trouver des éléments par ID, créons à présent la méthode suivante qui ajoute un nom de classe à nos éléments, appelée « addClass » :

// Ajoute une nouvelle classe à un élément
// Cela ne supprime pas les autres classes, elle en ajoute simplement une nouvelle
addClass:function(name){
for(var i = 0; i<this.elems.length; i++){
this.elems[i].className += ' ' + name; // C'est ici qu'on ajoute la nouvelle classe
}
return this; // Renvoie this dans l'ordre d'appel
},

La dernière méthode pour aujourd'hui est la fonction « on » qui est utilisée pour ajouter des événements à nos éléments, par exemple 'click', 'mouseover', 'mouseout', etc.

// Ajoute un événement aux éléments trouvés par les méthodes : getById et getByClass
//-- Action est un type d'événement comme 'click', 'mouseover', 'mouseout', etc.
//-- Callback est la fonction à exécuter lorsque l'événement est déclenché
on: function(action, callback){
if(this.elems[0].addEventListener){
for(var i = 0; i<this.elems.length; i++){
this.elems[i].addEventListener(action,callback,false);//Ajout de l'événement du W3C pour Firefox,Safari,Opera...
}
}
else if(this.elems[0].attachEvent){
for(var i = 0; i<this.elems.length; i++){
this.elems[i].attachEvent('on'+action,callback);// Ajout de l'événement pour Internet Explorer :(
}
}
return this; // Renvoie this dans l'ordre d'appel
},

Pour rattacher du texte à nos éléments, nous pouvons utiliser cette méthode :

// Ajout du texte sur les éléments
// text est la chaine à insérer
appendText:function(text){
text = document.createTextNode(text); // Crée un nouveau noeud texte avec la chaine fournie
for(var i = 0; i<this.elems.length; i++){
this.elems[i].appendChild(text); // Ajoute le texte à l'élément
}
return this; // Renvoie this dans l'ordre d'appel
},

Pour afficher/masquer les éléments trouvés, nous utiliserons cette méthode :

// Affiche ou masque les éléments trouvés
toggleHide:function(){
for(var i = 0; i<this.elems.length; i++){
this.elems[i].style['display'] = (this.elems[i].style['display'] == 'none')  ? '' :'none';
// Vérifie le statut de l'élément pour savoir s'il peut être affiché ou masqué
}
return this; // Renvoie this dans l'ordre d'appel
}

Note de traduction :

Pour des raisons de compatibilité, nous avons modifié la définition de la fonction toggleHide, dans l'article original nous avions :

this.elems[i].style['display'] = (this.elems[i].style['display'] == 'none || '') ? 'block' :'none';

Pour afficher l'élément, le mieux est que l'on affecte à sa propriété display une chaine vide (''). La difficulté est de déterminer le type de display par défaut de l'élément et aussi que certaines valeurs par défaut (en particulier pour les tableaux) ne sont pas acceptées par tous les navigateurs (table-row, table-cell…) donc affecter une chaine vide revient à affecter la valeur par défaut de cet élément, quelle que soit cette valeur et valable pour tous les navigateurs.

Attention, dans ce cas si une valeur a été définie dans une feuille de style, c'est cette valeur qui sera la valeur par défaut, alors il vaut mieux éviter d'utiliser un display: none; dans la feuille de style et mettre un style inline dans l'attribut style de la balise afin d'éviter toute surprise.

Finalement, ajoutons cela à la fin du framework :

if(!window.$$){window.$$=VOZ;} //Nous créons un raccourci pour notre framework, nous pouvons appeler les méthodes par $$.method ();

Ceci permet d'utiliser notre framework avec $$ comme raccourci.
Par exemple :

$$.getById('myElement')

Maintenant notre framework ressemble à ça :

(function(){
var VOZ = {
elems:[],// Tableau pour sauvegarder tous les éléments trouvés par les fonctions getById, getByClass
// Récupère tous les éléments par ID
// Peut prendre plus d'un paramètre
getById:function(){
var tempElems = []; // tableau temporaire pour sauvegarder les éléments trouvés
for(var i = 0; i<arguments.length; i++){
if(typeof arguments[i] === 'string'){ // Vérifie que le paramètre est une chaine
tempElems.push(document.getElementById(arguments[i])); // Ajoute l'élément à tempElems
}
}
this.elems = tempElems; // Tous les éléments sont copiés dans la propriété elems
return this; // Renvoie this dans l'ordre d'appel
},

// Ajoute une nouvelle classe à un élément
// Cela ne supprime pas les autres classes, elle en ajoute simplement une nouvelle
addClass:function(name){
for(var i = 0;i<this.elems.length;i++){
this.elems[i].className += ' ' + name; // C'est ici qu'on ajoute la nouvelle classe
}
return this; // Renvoie this dans l'ordre d'appel
},

// Ajoute un événement aux éléments trouvés par la méthode : getById et getByClass
//-- Action est un type d'événement comme 'click', 'mouseover', 'mouseout', etc.
//-- Callback est la fonction à exécuter lorsque l'événement est déclenché
on: function(action, callback){
if(this.elems[0].addEventListener){
for(var i = 0;i<this.elems.length;i++){
this.elems[i].addEventListener(action,callback,false);//Ajout de l'événement du W3C pour Firefox,Safari,Opera...
}
}
else if(this.elems[0].attachEvent){
for(var i = 0;i<this.elems.length;i++){
this.elems[i].attachEvent('on'+action,callback); // Ajout de l'événement pour Internet Explorer :(
}
}
return this; // Renvoie this dans l'ordre d'appel
},

// Ajout du texte sur les éléments
// text est la chaine à insérer
appendText:function(text){
text = document.createTextNode(text); // Crée un nouveau noeud texte avec la chaine fournie
for(var i = 0;i<this.elems.length;i++){
this.elems[i].appendChild(text); // Ajoute le texte à l'élément
}
return this; // Renvoie this dans l'ordre d'appel
},

// Affiche ou masque les éléments trouvés
toggleHide:function(){
for(var i = 0;i<this.elems.length;i++){
this.elems[i].style['display'] = (this.elems[i].style['display']==='none' || '') ?'block':'none';
// Vérifie le statut de l'élément pour savoir s’il peut être affiché ou masqué
}
return this; // Renvoie this dans l'ordre d'appel
}
}
if(!window.$$){window.$$=VOZ;} //Nous créons un raccourci pour notre framework, nous pouvons appeler les méthodes par $$.method ();
})();

V - Méthode de Chaînage

Le chaînage est la capacité d'appeler une méthode à partir du résultat retourné par la précédente. Cela rend le code plus compréhensible et mieux organisé.

Sans Chaînage

$('#element').method1();
$('#element').method2();
$('#element').method3();

Avec chaînage

$('#element').method1().method2().method3();

Ceci est rendu possible parce que nos méthodes retournent systématiquement l'objet (this) sur lequel nous travaillons.

VI - Conclusion

Exemple du framework JavaScript VOZ

Visitez le lien ci-dessus pour voir la première partie de notre framework VOZ en action ! Aussi, attendez la deuxième partie de cette série d'articles, qui devrait arriver bientôt ! J'espère que vous avez aimé lire ce tutoriel et que vous l'avez trouvé facile à suivre ! N'hésitez pas à laisser vos commentaires, car j'apprécie d'avoir les impressions des autres développeurs !

VII - Remerciements

Je tiens ici à remercier l'équipe de Developpez.com pour ses relectures attentives et ses suggestions, et en particulier Bovino et Bérénice MAUREL.