51 votes

Un fichier JS pour plusieurs pages

Je mets généralement tous les scripts JavaScript dans un fichier, par exemple scripts.js (moins de requêtes HTTP, c'est mieux). Ainsi, certains scripts sont nécessaires pour certaines pages, d'autres non.

Pour cibler une page spécifique, j'utilise quelque chose comme :

if ($("body#share").length > 0) {
    // Placez ici la logique concernant la page avec l'ID 'share'...
}

// Le fichier / script continue...

D'autres suggestions ou meilleures suggestions? Merci!

Clarification: Je ne cherchais pas à comparer les avantages et les inconvénients entre la consolidation de plusieurs fichiers JS en un seul gros fichier et le maintien de plusieurs fichiers JS séparés. La réponse à cela est sûrement 'dépend de la situation' (nous le savons). Ma question est, en supposant que toute ma logique JS est placée dans un seul grand fichier, comment faire en sorte qu'un (morceau de) script s'exécute seulement lorsque la page correspondante est chargée ? Une façon que j'utilisais était d'utiliser if ($('#id-of-target-element')) { /* exécuter le script */}; y a-t-il une meilleure façon?

2 votes

Utilisez-vous un langage côté serveur comme PHP ? Vous pourriez demander au serveur de vérifier la page actuelle et de renvoyer uniquement le code approprié pour cette page.

0 votes

Si tout le code est téléchargé, de telles comparaisons ne devraient pas être nécessaires. En supposant que je lis correctement votre question.

0 votes

@JeffreySweeney il doit probablement vérifier sur quelle page il agira avec une fonction spécifique... mais pour moi, c'est une approche assez bizarre, j'espère que je ne semble pas trop rigide

26voto

Charlino Points 11217

J'aime l'approche de Paul Irish... vous n'avez pas à la suivre exactement, mais l'idée générale est très solide.

Cela pourrait ressembler à ceci pour votre exemple

Html

Votre javascript spécifique à la page

YourNamespace = {
  share : {
    init : function(){
      // Placez ici la logique concernant la page avec l'ID 'share'...
    }
  }
}

Le javascript de Paul Irish qui rend la magie possible

UTIL = { 
  fire : function(func,funcname, args){
    var namespace = YourNamespace;  // indiquez votre espace d'objets littéraux ici

    funcname = (funcname === undefined) ? 'init' : funcname;
    if (func !== '' && namespace[func] && typeof namespace[func][funcname] == 'function'){
      namespace[func][funcname](args);
    }
  }, 

  loadEvents : function(){
    var bodyId = document.body.id;

    // commencez par les éléments communs.
    UTIL.fire('common');

    // faites attention aussi aux classes.
    $.each(document.body.className.split(/\s+/),function(i,classnm){
      UTIL.fire(classnm);
      UTIL.fire(classnm,bodyId);
    });

    UTIL.fire('common','finalize');
  }
};

// lancez tout ici 
$(document).ready(UTIL.loadEvents);

Donc la ligne que vous voyez directement ci-dessus va lancer ce qui suit

YourNamespace.common.init()
YourNamespace.share.init()
YourNamespace.common.finalize()

Lisez son article de blog et quelques-unes des variantes qui y sont liées.

2 votes

Plutôt que d'utiliser l'identifiant du corps, je voudrais utiliser un attribut data-*, qui vous permettrait d'avoir du code JS partagé entre les pages. Par exemple, si vous avez deux pages : page1 avec : , et page2 avec : , alors ces pages partagent toutes les deux du JS (category1), et ont du JS spécifique à la page (page1 et page2). Evidemment, vous devriez modifier le code JS pour diviser l'attribut data-page par espace et boucler à travers chaque valeur, exécutant les méthodes dans l'ordre.

0 votes

Il s'agit en fait d'une approche très intéressante. J'aimerais ajouter que ma méthode est assez similaire gist.github.com/bacloud14/826329ab11a3d4b00d95b9f0a97d6c6c

9voto

Sajib Mahmood Points 2092

Des questions similaires ont déjà été posées et la réponse correcte était et sera toujours

Cela dépend de la situation.

Cependant, si votre préoccupation concerne la minimisation du temps de trajet aller-retour (RTT) alors il est certain que

Combiner les scripts externes en aussi peu de fichiers que possible réduit les RTT et les retards de téléchargement d'autres ressources.

Il est bon de le garder aussi peu que possible, mais vous n'êtes pas obligé de le garder strictement dans un seul fichier.

Regardons pourquoi c'est ainsi.

Alors que partitionner le code en composants logiciels modulaires est une bonne pratique d'ingénierie, importer des modules dans une page HTML un par un peut augmenter considérablement le temps de chargement de la page. Tout d'abord, pour les clients avec un cache vide, le navigateur doit émettre une requête HTTP pour chaque ressource, et subir les temps de trajet aller-retour associés. Deuxièmement, la plupart des navigateurs empêchent le reste de la page d'être chargé pendant le téléchargement et l'analyse d'un fichier JavaScript.

Ces images montrent plus clairement pourquoi combiner un certain nombre de fichiers JavaScript en moins de fichiers de sortie peut réduire considérablement la latence:

Tous les fichiers sont téléchargés séquentiellement et prennent un total de 4,46 secondes pour terminerTous les fichiers sont téléchargés séquentiellement et prennent un total de 4,46 secondes pour terminer.

Après avoir regroupé les 13 fichiers js en 2 fichiers: Les mêmes 729 kilo-octets prennent désormais seulement 1,87 seconde à téléchargerLes mêmes 729 kilo-octets prennent désormais seulement 1,87 seconde à télécharger

Modifications après les éclaircissements de Siku-Siku.Com: Désolé! J'ai totalement mal compris votre question. Je ne connais pas de meilleure manière de faire en sorte qu'un script particulier (morceau de) ne fonctionne que lorsque la page correspondante est chargée. Je pense que votre manière est suffisante.

4 votes

Ceci est un peu dépassé. La plupart des navigateurs modernes (y compris IE8+) téléchargent le JavaScript simultanément, plutôt que séquentiellement.

6voto

Wesley Points 1307

Votre suggestion semble OK. Cependant, j'utiliserais un attribut de données HTML 5 pour baliser chaque page de cette manière :

Vous pouvez ensuite écrire du code JavaScript conditionnel en vérifiant cette propriété (à partir de jQuery 1.4.3) :

if ($("body").data("title") === "my_page_title") {
    // Placez la logique concernant la page avec le titre 'my_page_title' ici...
}

Cela vous permet de regrouper systématiquement tout le code pour une certaine page de manière sensée

0 votes

Ou même un ID et une classe :

0 votes

Comment cela affecte-t-il le chargement de la page ?

5voto

blo0p3r Points 2106

Une autre option est que vous pourriez avoir, dans le code HTML

    appelerVotreFonctionJS();  /*Les choses que vous voulez voir se produire lors du chargement de la page*/

Cela suivra le flux normal de la page. Par conséquent, si vous manipulez des éléments sur la page, vous devrez placer cette portion </code> en bas de la page, après que tous les éléments ont été chargés par le navigateur.</p> <p>Je ne suis pas sûr à 100% que cela soit plus efficace que la solution actuelle que vous avez, mais d'un autre côté, cela indiquera à quelqu'un regardant votre page HTML quel JavaScript sera exécuté lorsque la page se charge. Cela pourrait être utile en termes de maintenance à l'avenir.... moins un jeu de devinettes quant au script s'exécutant lorsque la page charge.</p> <p>J'espère que cela vous aide!</p></x-turndown>

1 votes

+1 Une bonne alternative à l'approche suggérée (également bonne) dans la question. S'il y a un framework comme jQuery en jeu, alors vous n'avez pas besoin de mettre le code en bas de la page, il suffit de l'encadrer dans un $(document).ready() ou similaire...

3 votes

@Stobor les deux ne sont pas la même chose. $(document).ready() doit exécuter $(document), analyser la fonction que vous nourrissez ready(), et appeler ready() là où il est écrit. Si vous mettez le code à la fin de la page, il n'est pas exécuté tant que tout ce qui précède n'a pas été analysé. De plus, $(document).ready() attend que la page entière se charge, y compris les ressources externes telles que les images. L'équivalent (en termes de fonctionnalité, pas d'ordre de traitement) de mettre le code à la fin de la page serait simplement de définir window.onload.

2 votes

@Skier88 : faux, document.ready (ou $(function(){...}); de jQuery) exécute la fonction passée dès que le DOM est chargé, il N'attend PAS le chargement de contenu externe comme les fichiers! Le Window.onload le fait... voir stackoverflow.com/questions/3698200/…

4voto

c69 Points 5140

Ok. Espérons que cet exemple de code sera plus clair que ce long texte :


votre fichier one-and-only.js :

var MY_SITE = {
    // vous avez un objet de namespace où vous stockez toutes vos choses
    main_page: {
        // à l'intérieur vous avez des morceaux plus petits, pour des pages spécifiques ou des widgets
        // celui-ci est pour la page principale
        _init: function () {
        ... 
        },
        ... 
        showSplashScreen: function () {
        ...
        }      
    },
    ... 
    // mais il y a d'autres pages
    contacts: { ... },
    // ou des widgets
    cool_menu: { ... },
    // et peut-être que vous voulez mettre des fonctions communes dans un bloc dédié
    global_utilities: { ... },
    // et bien sûr - le loader
    _start: function () {
        // ici nous appelons simplement un _init du module de page qui a été spécifié 
        this[PAGE_TYPE]._init(); 
        // et des trucs plus complexes - nous pouvons rechercher la page pour des éléments
        // qui contiennent un attribut de données spécial, les collecter
        var widgets = $('[data-our-widget]').each().getAttributeValue( 'data-or-widget' );
       // et puis _init chacun de ces widgets comme nous l'avons fait avec la page principale 
        widgets.forEach( function (v) {
            this[v]._init();
        }
    }
};
document.on('ready', MY_SITE.start); // ici nous supposons un certain framework js aléatoire

vos balises </code> sur la page :</p> <pre><code><script>var PAGE_TYPE = 'main_page'; </code></pre> <p>vos éléments <em>'magiques'</em> sur la page :</p> <pre><code><div id="whatever" data-our-widget="cool_menu"> ... </div> </code></pre> <hr> <p><strong>Attention :</strong> <em>Ceci est un aperçu de haut niveau ! Les détails de mise en œuvre peuvent et doivent varier en fonction de <strong>vos</strong> besoins.</em></p></x-turndown>

0 votes

+1 pour le code. Je vais devoir expérimenter davantage pour assimiler.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X