Proposition de structure JavaScript
Modified version of the Garber-Irish Implementation of a Markup-based unobtrusive comprehensive DOM-ready execution.
by fparent
HTML
<link rel="stylesheet" href="https://raw.github.com/fparent/StarterCSS/master/starter.min.css">
<h1>Structure JavaScript</h1>
<p>Voici la nouvelle technique (aussi appelée "DOM-based Routing" et présente dans plusieurs frameworks comme Backbone, Ruby, CodeIgniter, etc.) que j'ai commencé à utilisée dernièrement dans mes projets. C'est une version que j'ai adaptée de la méthode Garber-Irish qui exécute automatiquement des functions JavaScript à la fin du chargement des pages, sans obstruer le document HTML (comme nous le faisais actuellement en faisant NAMESPACE.function partout).</p>
<p>À mon avis, c'est une excellente technique autant pour les petits projets que pour les gros. Elle peut sembler limitée à première vue, mais qui offre une très bonne structure tout en étant extrêmement flexible. Elle permettrait de développer des sites plus modulaires, faciles à maintenir, mieux structurés, avec avec du code plus compréhensif et "propre", et qui évolueraient bien avec le temps.</p>
<p>Le fonctionnement est simple: au lieu d'appeller toutes les functions individuellement dans chacunes des pages comme ceci...</p>
<div class="code">
<script><br />
PROJET.initHome();<br />
PROJET.initValidation();<br />
PROJET.initCarousel();<br />
</script>
</div>
<p>... la technique utilise les attributs HTML5 "data" sur le body, ce qui fait plus "propre" et fait du sens sémantiquement parlant.</p>
<h3>Nouveaux attributs, moins de redondance</h3>
<p>Les attributs disponibles sont "data-controller" et "data-action" et ils sont utilisés sur la balise "body". Le controller représente une function spécifique de la page en cours (par exemple, data-attribute="contact" équivaut à SITE.contact.init() et serait probablement utilisé dans la page "Contact Us") et l'action correspond à une tâche particulière de cette page. Les controlleurs peuvent aussi avoir une function "init";...
CSS
html {
font-family: sans-serif;
font-size: 80%;
line-height: 1.3em;
color: #444;
}
h3 {
margin-top: 3em;
}
p, .code, li {
margin-bottom: 1.5em;
}
.code {
background-color: #fefdf2;
border: solid 1px #dad8c5;
padding: 1em;
margin-top: 0.5em;
}
mark {
background-color: #15e1ff;
color: #fff;
}
JavaScript
// Une version sans commentaire du boilerplate est disponible ici:
// http://bit.ly/Mahd5J (1.5k)
// Namespace principal du projet.
// Sert à englober et restreindre le code du projet, ainsi
// qu'à exposer l'interface publique. Je suggère qu'on utilise
// toujours le préfixe "UI_" dans nos variables globales pour
// réduire au maximum les chances de conflits et être plus
// représentatif de l'entreprise.
var UI_PROJECT = (function( $, window, document, undefined ) {
// Devrait maintenant être utilisé dans tous nos projets.
// Va nous permettre de développer du meilleur code JavaScript:
// http://bit.ly/JNBf5z
'use strict';
var SITE = {}, UTIL = SITE;
// Objet contenant toutes les fonctionnalitées propres au site en cours.
SITE = {
common: {
// Function commune exécutée dans toutes les pages
init: function() {
console.log('exécute une action générale');
},
// Exemple de function commune qui pourrait servir pour
// certains controlleurs seulement
notSoCommon: function() {
console.log('exécute une action générale spécifique à certaines pages');
},
// Exemple d'action commune qui pourrait être appellé sans controlleur,
// comme dans les pages d'erreur par exemple, en utilisant
// <body data-action="error">...
error: function() {
console.log('oups, ceci ressemble à une page d\'erreur!');
}
},
// Chaque controlleur représente une page
home: {
init: function() {
console.log('initialisation de la page Home');
// Appelle une function semi-commune, qui pourrait servir à certains
// controlleurs seulement.
SITE.common.notSoCommon();
},
...