web-dev-qa-db-fra.com

Comment contrôler l'ordre des comportements Drupal.be?

Je veux que le code JavaScript du module X ne s'exécute qu'après l'exécution de celui du module Y. Quelle est la meilleure façon de procéder?

9
cam8001

Le code JavaScript utilisé par Drupal 7 est le suivant:

Drupal.attachBehaviors = function (context, settings) {
  context = context || document;
  settings = settings || Drupal.settings;
  // Execute all of them.
  $.each(Drupal.behaviors, function () {
    if ($.isFunction(this.attach)) {
      this.attach(context, settings);
    }
  });
};

Drupal 6 utilise un code similaire:

Drupal.attachBehaviors = function(context) {
  context = context || document;
  if (Drupal.jsEnabled) {
    // Execute all of them.
    jQuery.each(Drupal.behaviors, function() {
      this(context);
    });
  }
};

Si JavaScript garantit que les propriétés d'objet/tableau sont toujours parcourues dans le même ordre dans lequel elles sont ajoutées, alors les valeurs seront passées de jQuery.each() à la fonction utilisée comme deuxième paramètre dans le même ordre dans lequel elles sont insérées. le tableau est passé en tant que premier paramètre.
Cela signifierait que le premier comportement inséré dans Drupal.behaviors Est exécuté en premier.
Dans ce cas, pour permettre aux comportements définis par votre module d'être exécutés en premier, vous pouvez utiliser un poids plus léger. Si vous voulez qu'ils soient exécutés avant les autres, le poids du module doit être réglé sur -50; d'autres valeurs peuvent également fonctionner. Si vous utilisez Drupal 7, drupal_add_js () permet d'associer un poids au code JavaScript; le code JavaScript avec un poids plus léger apparaît en premier dans la sortie HTML. n'est pas possible avec Drupal 6, pensé.

JavaScript ne garantit pas que les propriétés sont parcourues dans le même ordre qu'elles sont ajoutées. Cela signifie que différentes implémentations JavaScript présenteraient les mêmes propriétés en utilisant un ordre différent; cela signifie également que le même ordre peut changer dans différentes versions du même navigateur.

5
kiamlaluno

Utilisez le module Behavior Weights .
(Veuillez lui donner quelques tests avant de l'utiliser sur un site de production)

Le module permet d'attacher des poids aux comportements, puis il détourne/remplace drupal.attachBehaviors avec une implémentation personnalisée, qui respecte les poids.


Pourquoi ne pas moduler le poids à la place, comme suggéré dans l'autre réponse?

  • le poids du module est un outil assez lourd. Il s'applique à toutes les implémentations de hook (php) et comportements (js) du module, alors que nous ne sommes intéressés que par un seul comportement.
  • l'ordre des propriétés dans un objet js n'est pas garanti par la spécification (bien qu'il soit implémenté comme vous vous en doutez dans presque tous les navigateurs).

Voir
L'ordre des champs dans un objet javascript est-il prédictible lors de leur boucle? et
Ordre des éléments - pour la boucle (… dans…) en javascript .

5
donquixote

Pour Drupal 6 -

Une solution simple, si cela n'a pas besoin d'être portable, est de placer le JS que vous souhaitez exécuter en dernier dans le fichier theme template.php. Les appels du thème drupal_add_js sont toujours appelés après les modules.

Si elle doit être portable, la solution "la plus propre" de drupal 6 consiste à ajouter un nouveau module qui a un poids différent de votre module avec le php. Vous pourriez même avoir les deux modules dans le même dossier, rendre le premier module dépendant du premier, et ajuster les poids dans les crochets d'installation/mise à jour. Aucun n'est nécessaire, facilite simplement l'installation.

0
mirzu