web-dev-qa-db-fra.com

Meilleures pratiques communément acceptées concernant l'organisation de code en JavaScript

Alors que les frameworks JavaScript tels que jQuery rendent les applications Web côté client plus riches et plus fonctionnelles, j'ai commencé à remarquer un problème ...

Comment dans le monde gardez-vous cela organisé?

  • Mettez tous vos gestionnaires en un seul endroit et écrivez des fonctions pour tous les événements?
  • Créer des fonctions/classes pour envelopper toutes vos fonctionnalités?
  • Écrire comme un fou et espérer que ça marche pour le mieux?
  • Abandonner et se lancer dans une nouvelle carrière?

Je parle de jQuery, mais c'est vraiment n'importe quel code JavaScript en général. Je constate que lorsque les lignes commencent à s’empiler, il devient de plus en plus difficile de gérer les fichiers de script ou de trouver ce que vous recherchez. Le problème le plus important que j'ai trouvé est sans doute qu'il y a tellement de façons de faire la même chose qu'il est difficile de savoir laquelle est la meilleure pratique couramment acceptée.

Existe-t-il des recommandations générales sur la meilleure façon de garder vos fichiers . Js aussi agréables et ordonnés que le reste de votre application? Ou est-ce juste une question d'IDE? Y a-t-il une meilleure option sur le marché?


EDIT

Cette question était destinée à être davantage sur l'organisation du code et non sur l'organisation des fichiers. Il y a eu de très bons exemples de fusion de fichiers ou de partage de contenu.

Ma question est la suivante: quelle est la meilleure pratique couramment acceptée actuellement pour organiser votre code actuel? Quel est votre moyen, voire un moyen recommandé d’interagir avec les éléments de la page et de créer du code réutilisable qui n’entre pas en conflit?

Certaines personnes ont listé namespaces, ce qui est une bonne idée. De quelles autres manières, en traitant plus spécifiquement des éléments de la page et en gardant le code organisé et ordonné?

553
Hugoware

Ce serait beaucoup plus agréable si javascript avait des espaces de noms intégrés, mais je trouve qu'organiser des choses comme Dustin Diaz décrit ici m'aide beaucoup.

var DED = (function() {

    var private_var;

    function private_method()
    {
        // do stuff here
    }

    return {
        method_1 : function()
            {
                // do stuff here
            },
        method_2 : function()
            {
                // do stuff here
            }
    };
})();

Je mets différents "espaces de noms" et parfois des classes individuelles dans des fichiers séparés. D'habitude, je commence avec un fichier et comme une classe ou un espace de noms devient assez grand pour le justifier, je le sépare dans son propre fichier. Utiliser un outil pour combiner tous vos fichiers en vue de la production est également une excellente idée.

180
polarbear

J'essaie d'éviter d'inclure n'importe quel javascript avec le HTML. Tout le code est encapsulé dans des classes et chaque classe est dans son propre fichier. Pour le développement, j'ai des balises <script> distinctes pour inclure chaque fichier js, mais elles sont fusionnées dans un seul package plus grand pour la production afin de réduire le temps système des demandes HTTP.

En règle générale, je vais avoir un seul fichier "principal" js pour chaque application. Donc, si j’écrivais une application "survey", j’aurais un fichier js appelé "survey.js". Cela contiendrait le point d’entrée dans le code jQuery. Je crée des références jQuery lors de l'instanciation, puis les passe dans mes objets en tant que paramètres. Cela signifie que les classes javascript sont "pures" et ne contiennent aucune référence à des identifiants ou noms de classe CSS.

// file: survey.js
$(document).ready(function() {
  var jS = $('#surveycontainer');
  var jB = $('#dimscreencontainer');
  var d = new DimScreen({container: jB});
  var s = new Survey({container: jS, DimScreen: d});
  s.show();
});

Je trouve aussi que la convention de nommage est importante pour la lisibilité. Par exemple: je ajoute 'j' à toutes les instances de jQuery.

Dans l'exemple ci-dessus, il existe une classe appelée DimScreen. (Supposons que ceci obscurcisse l'écran et ouvre une boîte d'alerte.) Il a besoin d'un élément div qu'il peut agrandir pour couvrir l'écran, puis ajoute une boîte d'alerte. Je passe donc un objet jQuery. jQuery a un concept de plug-in, mais il semblait limité (par exemple, les instances ne sont pas persistantes et ne sont pas accessibles) sans réel avantage. Ainsi, la classe DimScreen serait une classe javascript standard qui utilise justement jQuery.

// file: dimscreen.js
function DimScreen(opts) { 
   this.jB = opts.container;
   // ...
}; // need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
  var me = this;
  me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
  //...
};

J'ai construit des applications assez complexes en utilisant cette approche.

87
Jason Moore

Vous pouvez diviser vos scripts en fichiers distincts à des fins de développement, puis créer une version "release" dans laquelle vous les regroupez tous et exécutez YUI Compressor ou quelque chose de similaire.

39
Greg

Inspiré par les publications précédentes, j'ai créé une copie des répertoires Rakefile et du fournisseur distribués. avec WysiHat (un environnement d'exécution mentionné par changelog) et a apporté quelques modifications pour inclure la vérification de code avec JSLint et minification avec YUI Compressor =.

L'idée est d'utiliser Sprockets (de WysiHat) pour fusionner plusieurs JavaScripts dans un seul fichier, vérifier la syntaxe du fichier fusionné avec JSLint et réduisez-le avec YUI Compressor avant la distribution.

Prérequis

  • Java Runtime
  • Rubis et gemmes
  • Vous devriez savoir comment insérer un fichier JAR dans Classpath

Faites maintenant

  1. Téléchargez Rhino et mettez le JAR ("js.jar") dans votre chemin de classes
  2. Téléchargez YUI Compressor et mettez le fichier JAR (build/yuicompressor-xyz.jar) dans votre chemin de classe.
  3. Téléchargez WysiHat et copiez le répertoire "vendor" à la racine de votre projet JavaScript
  4. Téléchargez JSLint pour Rhino et insérez-le dans le répertoire "vendor"

Créez maintenant un fichier nommé "Rakefile" dans le répertoire racine du projet JavaScript et ajoutez-y le contenu suivant:

require 'rake'

ROOT            = File.expand_path(File.dirname(__FILE__))
OUTPUT_MERGED   = "final.js"
OUTPUT_MINIFIED = "final.min.js"

task :default => :check

desc "Merges the JavaScript sources."
task :merge do
  require File.join(ROOT, "vendor", "sprockets")

  environment  = Sprockets::Environment.new(".")
  preprocessor = Sprockets::Preprocessor.new(environment)

  %w(main.js).each do |filename|
    pathname = environment.find(filename)
    preprocessor.require(pathname.source_file)
  end

  output = preprocessor.output_file
  File.open(File.join(ROOT, OUTPUT_MERGED), 'w') { |f| f.write(output) }
end

desc "Check the JavaScript source with JSLint."
task :check => [:merge] do
  jslint_path = File.join(ROOT, "vendor", "jslint.js")

  sh 'Java', 'org.mozilla.javascript.tools.Shell.Main',
    jslint_path, OUTPUT_MERGED
end

desc "Minifies the JavaScript source."
task :minify => [:merge] do
  sh 'Java', 'com.yahoo.platform.yui.compressor.Bootstrap', '-v',
    OUTPUT_MERGED, '-o', OUTPUT_MINIFIED
end

Si vous avez tout fait correctement, vous devriez pouvoir utiliser les commandes suivantes dans votre console:

  • rake merge - pour fusionner différents fichiers JavaScript en un seul
  • rake check - pour vérifier la syntaxe de votre code (c'est la tâche par défaut , vous pouvez donc taper simplement rake)
  • rake minify - pour préparer une version abrégée de votre code JS

Sur la fusion de source

En utilisant Sprockets, le pré-processeur JavaScript, vous pouvez inclure (ou require) d’autres fichiers JavaScript. Utilisez la syntaxe suivante pour inclure d'autres scripts du fichier initial (nommé "main.js", mais vous pouvez le modifier dans le fichier Rake):

(function() {
//= require "subdir/jsfile.js"
//= require "anotherfile.js"

    // some code that depends on included files
    // note that all included files can be in the same private scope
})();

Et ensuite ...

Consultez le fichier Rakefile fourni avec WysiHat pour configurer les tests automatisés de l’unité. Jolies choses :)

Et maintenant pour la réponse

Cela ne répond pas très bien à la question initiale. Je le sais et je m'en excuse, mais je l'ai posté ici parce que j'espère que cela pourra être utile à quelqu'un d'autre pour organiser son mess.

Mon approche du problème consiste à faire autant de modélisation orientée objet que possible et à séparer les implémentations dans différents fichiers. Ensuite, les gestionnaires doivent être aussi courts que possible. L'exemple avec List singleton est aussi un bel exemple.

Et les espaces de noms ... ils peuvent être imités par une structure d'objet plus profonde.

if (typeof org === 'undefined') {
    var org = {};
}

if (!org.hasOwnProperty('example')) {
    org.example = {};
}

org.example.AnotherObject = function () {
    // constructor body
};

Je ne suis pas un grand partisan des imitations, mais cela peut être utile si vous souhaitez déplacer de nombreux objets hors du champ global.

27
Damir Zekić

L’organisation du code nécessite l’adoption de conventions et de normes de documentation:
1. Code d'espace de noms pour un fichier physique;

Exc = {};


2. Grouper des classes dans ces espaces de noms javascript;
3. Définissez des prototypes ou des fonctions ou classes associées pour représenter des objets du monde réel;

Exc = {};
Exc.ui = {};
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};
Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    ...
};


4. Définissez des conventions pour améliorer le code. Par exemple, regroupez toutes ses fonctions ou méthodes internes dans son attribut de classe d'un type d'objet.

Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    this.internal = {
        widthEstimates: function (tips) {
            ...
        }
        formatTips: function () {
            ...
        }
    };
    ...
};


5. Faites la documentation des espaces de noms, des classes, des méthodes et des variables. Si nécessaire, discutez également du code (certains FI et Fors implémentent généralement une logique importante du code).

/**
  * Namespace <i> Example </i> created to group other namespaces of the "Example".  
  */
Exc = {};
/**
  * Namespace <i> ui </i> created with the aim of grouping namespaces user interface.
  */
Exc.ui = {};

/**
  * Class <i> maskdInput </i> used to add an input HTML formatting capabilities and validation of data and information.
  * @ Param {String} mask - mask validation of input data.
  */
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};

/**
  * Class <i> domTips </i> used to add an HTML element the ability to present tips and information about its function or rule input etc..
  * @ Param {String} id - id of the HTML element.
  * @ Param {String} tips - tips on the element that will appear when the mouse is over the element whose identifier is id <i> </i>.
  */
  Exc.ui.domTips = function (id, tips) {
    this.domID = id;
    this.tips = tips;
    ...
};


Ce ne sont là que quelques conseils, mais cela a grandement aidé à organiser le code. N'oubliez pas que vous devez avoir de la discipline pour réussir!

18
Nery Jr

Suivre de bons OO) principes de conception et modèles de conception permet de rendre votre code facile à gérer et à comprendre. Cependant, l'une des meilleures choses que j'ai récemment découvertes sont les signaux et les créneaux horaires aka publish/subscribe Regardez http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html pour une implémentation jQuery simple.

L'idée est bien utilisée dans d'autres langues pour le développement d'interface graphique. Lorsque quelque chose d'important se produit quelque part dans votre code, vous publiez un événement synthétique global auquel d'autres méthodes d'autres objets peuvent s'abonner. Cela donne une excellente séparation des objets.

Je pense que Dojo (et Prototype?) Ont une version intégrée de cette technique.

voir aussi Que sont les signaux et les slots?

13
meouw

J'ai pu appliquer avec succès modèle de module Javascript à une application Ext JS de mon travail précédent. Cela fournissait un moyen simple de créer du code bien encapsulé.

12
Alan

Dojo avait le système de modules depuis le premier jour. En fait, il est considéré comme une pierre angulaire du Dojo, la colle qui maintient tout cela ensemble:

Utilisation des modules Dojo atteint les objectifs suivants:

  • Espaces de nommage pour le code Dojo et le code personnalisé (dojo.declare()) - ne polluent pas l'espace global, ne coexistent pas avec d'autres bibliothèques et ne code pas le code utilisateur de Dojo.
  • Chargement de modules de manière synchrone ou asynchrone par nom (dojo.require()).
  • Créez des constructions personnalisées en analysant les dépendances de modules pour créer un fichier unique ou un groupe de fichiers interdépendants (appelés couches) afin d'inclure uniquement les besoins de votre application Web. Les constructions personnalisées peuvent inclure des modules Dojo et des modules fournis par le client.
  • Accès CDN transparent au Dojo et au code de l'utilisateur. AOL et Google utilisent Dojo de cette manière, mais certains clients le font également pour leurs applications Web personnalisées.
11
Eugene Lazutkin

Mon patron parle encore du temps où ils écrivaient du code modulaire (langage C) et se plaignait de la piètre qualité du code! On dit que les programmeurs peuvent écrire Assembly dans n’importe quel cadre. Il y a toujours une stratégie pour surmonter l'organisation du code. Le problème de base concerne les personnes qui traitent le script Java comme un jouet et ne cherchent jamais à l’apprendre).

Dans mon cas, j’écris des fichiers js sur un thème d’interface utilisateur ou sur un écran d’application, avec un init_screen () approprié. En utilisant la convention de nommage appropriée, je m'assure qu'il n'y a pas de conflits d'espace de noms au niveau de l'élément racine. Dans window.load (), peu encombrant, j'attache les choses en fonction de l'ID de niveau supérieur.

J'utilise strictement Java des fermetures de script et des modèles pour masquer toutes les méthodes privées. Cela fait, je n'ai jamais eu à faire face à un problème de conflit de propriétés/définitions de fonction/définitions de variable. Toutefois, lorsque vous travaillez en équipe, souvent difficile d'appliquer la même rigueur.

9
questzen

Départ JavasciptMVC .

Vous pouvez :

  • divisez votre code en couches de modèle, de vue et de contrôleur.

  • compresser tout le code dans un seul fichier de production

  • générer automatiquement du code

  • créer et exécuter des tests unitaires

  • et beaucoup plus...

Mieux encore, il utilise jQuery, vous pouvez donc également tirer parti des autres plugins jQuery.

9
andyuk

Je suis surpris que personne n'ait mentionné les frameworks MVC. J'utilise Backbone.js pour modulariser et découpler mon code, et cela a été inestimable.

Il existe de nombreux types de cadres de ce type, et la plupart d'entre eux sont également minuscules. Mon opinion personnelle est que si vous écrivez plus que quelques lignes de jQuery pour des choses d’interface utilisateur très frappantes, ou si vous voulez une application Ajax riche, un framework MVC vous facilitera la vie beaucoup.

9
Chetan

"Écrire comme un fou et espérer que tout ira pour le mieux?", J'ai vu un projet comme celui-ci, développé et mis à jour par seulement 2 développeurs, une énorme application avec beaucoup de code javascript. En plus de cela, il y avait différents raccourcis pour chaque fonction jquery possible à laquelle vous pouvez penser. Je leur ai suggéré d'organiser le code sous forme de plugins, car c'est l'équivalent jQuery de class, module, namespace ... et de l'univers entier. Mais les choses ont empiré. Ils ont commencé à écrire des plug-ins, remplaçant chaque combinaison de 3 lignes de code utilisées dans le projet. Personnellement, jQuery est le diable et il ne devrait pas être utilisé sur des projets avec beaucoup de javascript, car cela vous encourage à être paresseux et à ne pas penser à organiser du code. Je préfère lire 100 lignes de javascript qu'une ligne avec 40 fonctions jQuery chaînées (je ne plaisante pas). Contrairement à la croyance populaire, il est très facile d'organiser le code javascript de manière équivalente aux espaces de noms et aux classes. C'est ce que font YUI et Dojo. Vous pouvez facilement rouler le vôtre si vous le souhaitez. Je trouve l'approche de YUI bien meilleure et efficace. Mais vous avez généralement besoin d’un éditeur Nice prenant en charge les extraits de code pour compenser les conventions de dénomination YUI si vous souhaitez écrire quelque chose d’utile.

8
Vasil

Je crée des singletons pour tout ce que je n'ai pas vraiment besoin d'instancier plusieurs fois à l'écran, mais un cours pour tout le reste. Et tous sont placés dans le même espace de noms dans le même fichier. Tout est commenté et conçu avec UML, des diagrammes d'état. Le code javascript est clair, donc pas de code javascript en ligne et j’ai tendance à utiliser jquery pour minimiser les problèmes de navigation croisée.

7
Nikola Stjelja

Un bon principe de OO + MVC contribuerait grandement à la gestion d’une application javascript complexe.

En gros, j'organise mon application et mon code javascript en fonction de la conception familière suivante (qui existe depuis le temps de la programmation depuis mon ordinateur jusqu'au Web 2.0)

JS OO and MVC

Description des valeurs numériques sur l'image:

  1. Widgets représentant les vues de mon application. Cela devrait être extensible et séparé, ce qui résulterait bien de la séparation que MVC tente de réaliser plutôt que de transformer mon widget en code spaghetti (équivalent dans une application Web de mettre un grand bloc de Javascript directement en HTML). Chaque widget communique via d'autres en écoutant l'événement généré par d'autres widgets, réduisant ainsi le couplage fort entre les widgets pouvant conduire à un code ingérable (rappelez-vous le jour de l'ajout onclick partout désignant une fonction globale dans la balise de script? Urgh ...)
  2. Modèles d'objet représentant les données que je veux renseigner dans les widgets et les transmettre au serveur. En encapsulant les données dans son modèle, l'application devient agnostique au format de données. Par exemple: bien que ces modèles d’objet soient naturellement sérialisés et désérialisés en JSON, bien que le serveur utilise XML pour la communication, tout ce que je dois changer est de changer la couche de sérialisation/désérialisation et non nécessairement de toutes les classes de widgets. .
  3. Les classes de contrôleur qui gèrent la logique métier et la communication avec le serveur + mettent parfois la couche en cache. Cette couche contrôle le protocole de communication avec le serveur et place les données nécessaires dans les modèles d'objets.
  4. Les classes sont soigneusement encapsulées dans leurs espaces de noms correspondants. Je suis sûr que nous savons tous à quel point l’espace de noms global peut être désagréable en Javascript.

Dans le passé, je séparais les fichiers en son propre js et utilisais la pratique habituelle pour créer des principes OO en Javascript. Le problème que j’ai vite découvert qu’il existe plusieurs façons d’écrire JS OO et ce n'est pas nécessairement que tous les membres de l'équipe ont la même approche. Plus l'équipe grandit (plus de 15 personnes dans mon cas), cela se complique, car il n'existe pas d'approche standard pour le langage JavaScript orienté objet. En même temps, je ne veux pas écrire mon propre cadre et répéter une partie du travail que je suis persuadé que les gens sont plus intelligents que ceux que j'ai résolus.

jQuery est incroyablement agréable comme framework Javascript et j'adore ce projet mais, à mesure que le projet s'agrandit, j'ai clairement besoin d'une structure supplémentaire pour mon application Web, en particulier pour faciliter la standardisation OO pratique. Pour moi, après plusieurs expériences, Je trouve que la base et le widget YUI3 ( http://yuilibrary.com/yui/docs/widget/ et http://yuilibrary.com/yui/docs/base/index. html ) l'infrastructure fournit exactement ce dont j'ai besoin, peu de raisons pour lesquelles je les utilise.

  1. Il fournit un support à Namespace. Un réel besoin de OO et une organisation soignée de votre code
  2. Il supporte la notion de classes et d'objets
  3. Cela donne un moyen standard pour ajouter des variables d'instance à votre classe
  4. Il supporte proprement l'extension de classe
  5. Il fournit le constructeur et le destructeur
  6. Il fournit un rendu et une liaison d'événement
  7. Il a un cadre de widget de base
  8. Chaque widget peut maintenant communiquer entre eux à l'aide d'un modèle standard basé sur des événements
  9. Plus important encore, il offre à tous les ingénieurs un OO Standard pour le développement Javascript)

Contrairement à beaucoup d’opinions, je n’ai pas nécessairement à choisir entre jQuery et YUI3. Ces deux peuvent coexister pacifiquement. Alors que YUI3 fournit le modèle OO) nécessaire pour mon application Web complexe, jQuery fournit toujours à mon équipe un logiciel facile à utiliser, JS Abstraction, que nous connaissons tous avec amour.

En utilisant YUI3, j'ai réussi à créer un motif MVC en séparant les classes qui étendent la base en tant que modèle, les classes qui étendent le widget en tant que vue et bien sûr, vous avez des classes de contrôleur qui effectuent la logique nécessaire et des appels côté serveur.

Le widget peut communiquer entre eux en utilisant un modèle basé sur les événements, en écoutant l'événement et en effectuant la tâche nécessaire en fonction d'une interface prédéfinie. En termes simples, ajouter OO + structure MVC à JS est une joie pour moi.

Juste un disclaimer, je ne travaille pas pour Yahoo! et simplement un architecte qui essaie de faire face au même problème posé par la question initiale. Je pense que si quelqu'un trouve un cadre équivalent OO, cela fonctionnerait également. Cette question s'applique également à d'autres technologies. Merci à Dieu pour toutes les personnes qui ont proposé OO Principes + MVC pour rendre nos journées de programmation plus gérables.

6
momo

L'organisation de votre code selon une méthode NameSpace centrée sur Jquery peut se présenter comme suit ... et ne pas entrer en conflit avec d'autres API Javascript, telles que Prototype, Ext non plus.

<script src="jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">

var AcmeJQ = jQuery.noConflict(true);
var Acme = {fn: function(){}};

(function($){

    Acme.sayHi = function()
    {
        console.log('Hello');
    };

    Acme.sayBye = function()
    {
        console.log('Good Bye');
    };
})(AcmeJQ);

// Usage
//          Acme.sayHi();
// or
// <a href="#" onclick="Acme.sayHi();">Say Hello</a>


</script>

J'espère que cela t'aides.

6
Darryl

Dans mon dernier projet -Viajeros.com- j'ai utilisé une combinaison de plusieurs techniques. Je ne saurais pas comment organiser une application Web - Viajeros est un site de réseautage social pour voyageurs doté de sections bien définies. Il est donc assez facile de séparer le code pour chaque zone.

J'utilise la simulation d'espaces de noms et le chargement différé de modules en fonction de la section du site. À chaque chargement de page, je déclare un objet "vjr" et lui charge toujours un ensemble de fonctions communes (vjr.base.js). Ensuite, chaque page HTML décide quels modules ont besoin avec un simple:

vjr.Required = ["vjr.gallery", "vjr.comments", "vjr.favorites"];

Vjr.base.js obtient chaque fichier compressé du serveur et les exécute.

vjr.include(vjr.Required);
vjr.include = function(moduleList) {
  if (!moduleList) return false;
  for (var i = 0; i < moduleList.length; i++) {
    if (moduleList[i]) {
      $.ajax({
        type: "GET", url: vjr.module2fileName(moduleList[i]), dataType: "script"
      });
    }
  }
};

Chaque "module" a cette structure:

vjr.comments = {}

vjr.comments.submitComment = function() { // do stuff }
vjr.comments.validateComment = function() { // do stuff }

// Handlers
vjr.comments.setUpUI = function() {
    // Assign handlers to screen elements
}

vjr.comments.init = function () {
  // initialize stuff
    vjr.comments.setUpUI();
}

$(document).ready(vjr.comments.init);

Compte tenu de ma connaissance limitée de Javascript, je sais qu'il doit y avoir de meilleurs moyens de gérer cela, mais jusqu'à présent, cela fonctionne très bien pour nous.

6
Danita

J'utilise gestion des paquets de Dojo (dojo.require et dojo.provide) et le système de classe (dojo.declare qui permet également un héritage multiple simple) pour modulariser toutes mes classes/widgets en fichiers séparés. Non seulement cela permet de garder votre code organisé, mais cela vous permet également de charger paresseux/juste à temps des classes/widgets.

5
Justin Johnson
3
Chetan

Créez de fausses classes et assurez-vous que tout ce qui peut être jeté dans une fonction distincte et ayant un sens le soit. Veillez également à faire de nombreux commentaires et à ne pas écrire de code spagghetti, mais plutôt en les conservant dans des sections. Par exemple, un code absurde décrivant mes idéaux. Évidemment, dans la vie réelle, j'écris aussi de nombreuses bibliothèques qui englobent essentiellement leurs fonctionnalités.

$(function(){
    //Preload header images
    $('a.rollover').preload();

    //Create new datagrid
    var dGrid = datagrid.init({width: 5, url: 'datalist.txt', style: 'aero'});
});

var datagrid = {
    init: function(w, url, style){
        //Rendering code goes here for style / width
        //code etc

        //Fetch data in
        $.get(url, {}, function(data){
            data = data.split('\n');
            for(var i=0; i < data.length; i++){
                //fetching data
            }
        })
    },
    refresh: function(deep){
        //more functions etc.
    }
};
3
Dmitri Farkov

Il y a quelques jours, les gars de 37Signals ont sorti un contrôle RTE , avec une torsion. Ils ont créé une bibliothèque qui regroupe des fichiers javascript à l'aide d'une sorte de commandes de pré-processeur.

Je l’utilise depuis pour séparer mes fichiers JS puis pour les fusionner en un. De cette façon, je peux séparer les préoccupations et, à la fin, avoir un seul fichier qui passe par le tuyau (gzip, pas moins).

Dans vos modèles, vérifiez si vous êtes en mode de développement et incluez les fichiers séparés. En production, incluez le dernier (que vous devrez "créer" vous-même).

3
changelog

Je pense que cela est peut-être lié au DDD (Domain-Driven Design). L’application sur laquelle je travaille, bien qu’elle ne possède pas d’API formelle, en donne des indications au moyen du code côté serveur (noms de classe/fichier, etc.). Armé de cela, j'ai créé un objet de niveau supérieur en tant que conteneur pour l'ensemble du domaine du problème. ensuite, j'ai ajouté des espaces de noms là où cela était nécessaire:

var App;
(function()
{
    App = new Domain( 'test' );

    function Domain( id )
    {
        this.id = id;
        this.echo = function echo( s )
        {
            alert( s );
        }
        return this;
    }
})();

// separate file
(function(Domain)
{
    Domain.Console = new Console();

    function Console()
    {
        this.Log = function Log( s )
        {
            console.log( s );
        }
        return this;
    }
})(App);

// implementation
App.Console.Log('foo');
2
ken

Pour l'organisation JavaScript utilisé les éléments suivants

  1. Dossier pour tous vos javascript
  2. Au niveau de la page, javascript obtient son propre fichier avec le même nom que la page. ProductDetail.aspx serait ProductDetail.js
  3. Dans le dossier javascript des fichiers de bibliothèque, j'ai un dossier lib
  4. Placez les fonctions de bibliothèque associées dans un dossier lib que vous souhaitez utiliser dans votre application.
  5. Ajax est le seul javascript que je déplace en dehors du dossier javascript et obtient son propre dossier. Puis j'ajoute deux sous-dossiers client et serveur
  6. Le dossier client récupère tous les fichiers .js, tandis que le dossier serveur récupère tous les fichiers côté serveur.
2

Vous pouvez utiliser jquery mx (utilisé dans javascriptMVC), qui est un ensemble de scripts vous permettant d'utiliser des modèles, des vues et des contrôleurs. Je l'ai utilisé dans un projet et m'a aidé à créer du javascript structuré, avec des tailles de script minimales en raison de la compression. Ceci est un exemple de contrôleur:

$.Controller.extend('Todos',{
  ".todo mouseover" : function( el, ev ) {
   el.css("backgroundColor","red")
  },
  ".todo mouseout" : function( el, ev ) {
   el.css("backgroundColor","")
  },
  ".create click" : function() {
   this.find("ol").append("<li class='todo'>New Todo</li>"); 
  }
})

new Todos($('#todos'));

Vous pouvez également utiliser le côté niquement le contrôleur de jquerymx si la vue et les pièces de modèle ne vous intéressent pas.

2
rolnn

J'utilise cette petite chose. Il vous donne la directive "include" pour les modèles JS et HTML. Cela élimine complètement le désordre.

https://github.com/gaperton/include.js/

$.include({
    html: "my_template.html" // include template from file...
})
.define( function( _ ){ // define module...
    _.exports = function widget( $this, a_data, a_events ){ // exporting function...
        _.html.renderTo( $this, a_data ); // which expands template inside of $this.

        $this.find( "#ok").click( a_events.on_click ); // throw event up to the caller...
        $this.find( "#refresh").click( function(){
            widget( $this, a_data, a_events ); // ...and update ourself. Yep, in that easy way.
        });
    }
});
2
gaperton

Votre question est celle qui m'a tourmenté à la fin de l'année dernière. La différence - transmettre le code à de nouveaux développeurs qui n’avaient jamais entendu parler de méthodes privées ou publiques. Je devais construire quelque chose de simple.

Le résultat final était un petit framework (environ 1 Ko) qui traduisait les littéraux d'objet en jQuery. La syntaxe est visuellement plus facile à analyser et si votre js s'agrandit, vous pouvez écrire des requêtes réutilisables pour trouver des éléments tels que les sélecteurs utilisés, les fichiers chargés, les fonctions dépendantes, etc.

Publier un petit cadre ici n’est pas pratique, j’ai donc écrit un billet de blog avec exemples (Mon premier. C’était une aventure!). Vous pouvez y jeter un coup d'œil.

Pour tous les autres ici avec quelques minutes pour le vérifier, j'apprécierais grandement les commentaires!

FireFox recommandé car il prend en charge toSource () pour l'exemple de requête d'objet.

À votre santé!

Adam

1
Adam

Lazy Chargez le code dont vous avez besoin à la demande. Google fait quelque chose comme ça avec leur google.loader

0
Brig Lamoreaux

Vous ne mentionnez pas votre langue côté serveur. Ou, plus précisément, quel framework vous utilisez - le cas échéant - côté serveur.

IME, j'organise les choses côté serveur et les laisse bouger sur la page Web. La structure est chargée d’organiser non seulement JS que chaque page doit charger, mais également les fragments JS qui fonctionnent avec le balisage généré. De tels fragments que vous ne voulez généralement pas émettre plus d'une fois - c'est pourquoi ils sont résumés dans le cadre permettant à ce code de résoudre ce problème. :-)

Pour les pages de fin qui doivent émettre leur propre JS, je trouve généralement qu'il existe une structure logique dans le balisage généré. De tels JS localisés peuvent souvent être assemblés au début et/ou à la fin d'une telle structure.

Notez que rien de tout cela ne vous dispense d'écrire du code JavaScript efficace! :-)

0
staticsan

J'utilise un script personnalisé inspiré par le comportement de Ben Nolan (malheureusement, je ne trouve plus le lien actuel), pour stocker la plupart de mes gestionnaires d'événements. Ces gestionnaires d'événements sont déclenchés par les éléments className ou Id, par exemple. Exemple:

Behaviour.register({ 
    'a.delete-post': function(element) {
        element.observe('click', function(event) { ... });
    },

    'a.anotherlink': function(element) {
        element.observe('click', function(event) { ... });
    }

});

J'aime inclure la plupart de mes bibliothèques Javascript à la volée, à l'exception de celles qui ont un comportement global. J'utilise assistant headholder () de Zend Framework pour cela, mais vous pouvez aussi tiliser javascript pour charger d'autres scripts à la volée avec Ajile par exemple .

0
Aron Rotteveel