28 votes

gestion des événements document.ready sur un site Web à grande échelle

NOTE: j'ai créé un plugin jQuery qui est ma tentative de trouver une solution à ce problème. Je suis sûr qu'il pourrait être amélioré et j'ai sans doute négligé beaucoup de cas d'utilisation, donc si quelqu'un veut donner de la rétroaction se sentir libre :-) https://github.com/WickyNilliams/ReadyBinder

Je n'ai pas de problème en tant que tel, mais pensé que ce serait un point intéressant pour la discussion, et j'espère que les gens ont des idées intéressantes pour cette.

En gros, je travaille sur une grande échelle de site web et de plus en plus, nous écrivons de plus en plus et JavaScript. C'est très bien, j'aime JS' approche unique et je trouve que le décalage dans le plus sombre, annales de la langue pour être attachants ;-) Cependant une chose qui m'a toujours ennuyé est de savoir comment gérer document prêt événements comme ils se sont de plus en plus grande au fil du temps (et comme un résultat moins axés/spécifique à la page servie)

Le problème est que nous avons un fichier JS (fusionné & minimisé, même si c'est sans conséquence pour mes questions). La plupart des JS est écrite à l'aide de la révélation motif de module, et jQuery est notre cadre de choix. Donc, tous nos JS funcitonality est logiquement regroupées dans des méthodes, des espaces, puis à droite au bas du fichier de script, nous avons ce

$(function(){
    //lots of code here, usually calling encapsulated methods 
    //on our namespaced revealing module
});

Le problème est que pas tout le code dans le présent document prêt gestionnaire se rapporte à chaque page. Par exemple, sur une page seulement 10% des elle pourrait être pertinente, sur un autre peut-être 80% pourrait être pertinente. Pour moi, c'est incroyablement mauvais, je sens que je ne dois exécuter le code que j'ai besoin par page, surtout pour l'efficacité, mais aussi la facilité de maintenance.

J'ai cherché sur google pour les approches à ce problème, mais impossible de trouver quoi que ce soit, peut-être que je suis à la recherche de quelque chose de mal!

De toute façon, donc mes questions sont:

  • Personne n'a jamais pensé à ce problème?
  • Est-il vraiment un problème dans l'opinion des autres?
  • Avez-vous une grande, englobant le document de prêt gestionnaire dans votre code ou est-il plus concentré pour le type de page servi?
  • Dans ce dernier cas, comment gérez-vous cela? Plusieurs gestionnaires qui se met en JS ou dynamiquement cracher le document prêt gestionnaire de serveur-côté?

Hâte de les pensées des gens sur la question.

Cheers

7voto

RameshVel Points 24472

C'est ce que j'ai fait dans ma rails de projet mvc avec de lourdes javascript, j'ai crée un namespace pour les contrôleurs en js qui ressemble à de la les rails contrôleur

class BusinessController
   def new
   end  
   def index
   end
end

et

Var Business =  {
      init : function(action) {
         //code common to the Business module
         //even add the common jquery doc ready here, its clean
         //and call the page specific action
         this[action]();
      },
      new : function() {
             // check jquery document ready code here, thats relevant to this action
             //New rental page specific code here
      },
      index : function() {
             //  check jquery document ready code here, thats relevant to this action
             //index rental page specific code here 
      }
}

et sur le code de la vue(côté serveur) vient de lancer la page spécifique du code js par

<script type="text/javascript"> 
 <%= controller_name %>.init('<%= controller.action_name %>'); 
//which will render to
//  Business.init(index);
</script>

Vous pouvez très bien le tordre pour le faire fonctionner dans n'importe quelle langue. Et cette approche ne se soucie pas si vous avez un seul fichier ou plusieurs fichiers.

2voto

zjs Points 198

Je pense que le must intuitive solution à ce problème est, tout simplement, de réduire la quantité de travail effectuée au moment du chargement.

Si votre code ressemble à quelque chose comme:

$(function () {
    // Binds a single click event (which will never be triggered if the hypothetical
    // widget is never used), regardless of how many widgets are used on the page.
    $(document).delegate('.rating-widget', 'click', namespace.rating.handler);
    // and so on for similar things which simply require event handler registration

    // Initializes each of the forms on the page, letting the initializer take care
    // of any details (datepicker widgets, validation, etc) based on the root element
    $('form.fancy').each(namespace.fancyform.initializer);
    // and so on for similar things that require initialization

    // ... (for each type of thing on the page requiring initial setup,
    //      find the most general/high level pattern that sufficient)
});

les choses devraient être relativement facile à gérer, même si il y a quelques dizaines de lignes. Il n'y a pas compliquée, intéressantes logique à ce niveau de mise à jour/rappelez-vous lorsque vous travaillez avec le code du composant et, parce que tout à ce niveau est trivial, il est facile à lire. À ce stade, il n'y a pas besoin d'inventer certains compliqué système d'enregistrement; il ne va pas être plus simple que d' .delegate et .each.

Note que bien que tous les ci-dessus gracieusement traite le cas où l'élément n'est pas utilisé. Dans ces cas, peu ou pas de travail est fait et pas de la logique conditionnelle est nécessaire.

Pour des idées intéressantes sur la façon dont vous pourriez mettre en œuvre les gestionnaires/initializers, vous voudrez peut-être jeter un oeil à, par exemple, le "Contextuelle jQuery dans la pratique" parler Doug Neiner a donné à jQuery de Boston la semaine dernière.

1voto

topek Points 8288

D'abord j'ai mis des classes spécifiques sur le corps ou sur des conteneurs spécifiques par exemple, articles, form-validation, password-meter, ... . Si j'ai une application MVC, je préfère mettre le nom du contrôleur dans un corps de catégorie. Ce n'est pas mal et peut être utile pour le style, trop.

Ensuite, sur chaque document.prêt bloc j'ai vérifier l'existence d'une telle classe, et s'il n'existe pas, j'en retour de cette fonction. Cette approche est plus simple car il n'a pas le code principal à l'intérieur d'une clause if. Cette approche ressemble à des assertions qui sont utilisés pour vérifier les conditions préalables d'une fonction.

Exemple:

$(function(){
    if($('body').hasClass('articles') === false){ return; }

    //body of the articles code
});

$(function(){
    if($('body').hasClass('password-meter') === false){ return; }

    //include password meter in page
});

Le bonus de cette approche est qu'aucun code malveillant peut se faufiler dans un prêt de rappel, ce qui rend plus facile de les réutiliser. L'inconvénient est que vous obtenez de nombreuses rappel des blocs et si vous ne payez pas l'attention de code en double peuvent facilement se faufiler dans votre application.

0voto

amcc Points 629

Je sais d'où vous venez. Droit webapps pour une utilisation mobile, il peut me rends compte à rendre à l'utilisateur de télécharger un énorme fichier JS plein de pertinence code (le JQuery API pour l'un est un bon début!).

Ce que je fais, ce qui peut être bon ou mauvais, mais certainement semble fonctionner est d'inclure les fonctions nécessaires à une page par page avant la balise. (Cette position pour la plupart, reçoit le document.prêt de l'émission). Pourtant, ne peut pas aider mais sentir cette approche est trop simple.

Je suis intéressé à entendre d'autres réponses mais si c'est une bonne question, +1.

0voto

nnnnnn Points 70578

"Le problème est que nous avons un fichier JS"

Je ne suis pas sûr de savoir comment vous pouvez l'éviter tant que vous êtes, y compris le même (fusionné) fichier JS pour toutes les pages. Vous pouvez utiliser certaines de serveur-côté de la logique de fusionner les différentes pièces pour aller avec les différentes pages, mais alors vous avez probablement perdre les avantages de la mise en cache côté client de la JS,...

Projets sur lesquels j'ai travaillé ont (généralement) utilisé plusieurs fichiers JS, un couple a été commun à chaque page, et les autres étant inclus ou non le cas échéant, certains fichiers JS inclus en une seule page. Cela veut dire que pratiquement chaque page comprend le commun des fonctions de la bibliothèque, qu'ils utilisent ou pas, mais le JS fichier est mis en cache, donc il n'a pas vraiment d'importance. Page de code est vraiment propre à chaque page.

Je ne peux pas dire à partir de votre question de savoir si vous êtes au courant, mais vous pouvez avoir plusieurs document prêt gestionnaires (je crois jQuery exécute dans l'ordre où ils ont été liés?). Donc, si vous découpez la JS chaque fichier JS peuvent inclure son propre document de prêt. Bien sûr, cette approche a son propre dessus, mais je pense que c'est mieux que de mettre tout dans le même fichier.

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