web-dev-qa-db-ja.com

Drupal.behaviorsの順序を制御するにはどうすればよいですか?

モジュールYのJavaScriptコードが実行された後にのみ、モジュールXのJavaScriptコードを実行したいのですが。これを行うための最良の方法は何ですか?

9
cam8001

Drupal 7で使用されるJavaScriptコードは次のとおりです。

_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は同様のコードを使用します。

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

JavaScriptがオブジェクト/配列のプロパティが常に追加されたのと同じ順序でトラバースされることを保証する場合、値はjQuery.each()から、2番目のパラメーターとして使用される関数に、それらが挿入された順序で渡されます。最初のパラメーターとして渡される配列。
これは、_Drupal.behaviors_に挿入された最初の動作が最初に実行されることを意味します。
この場合、モジュールによって定義された動作を最初に実行できるようにするために、モジュールの軽量化を使用できます。他のものより先に実行したい場合は、モジュールの重みを-50に設定する必要があります。他の値も機能します。 Drupal 7を使用している場合、 drupal_add_js() を使用すると、JavaScriptコードに重みを関連付けることができます。より軽い重みのJavaScriptコードが最初にHTML出力に表示されます。 Drupal 6では考えられません。

JavaScriptは、プロパティが追加されたのと同じ順序でトラバースされることを保証しません。つまり、異なるJavaScript実装は、異なる順序を使用して同じプロパティを表示します。また、同じブラウザの異なるバージョンで同じ順序が変更される可能性があることも意味します。

5
kiamlaluno

Behavior Weights モジュールを使用します。
(本番サイトで使用する前に、テストを行ってください)

このモジュールはビヘイビアーに重みを付けることができ、ハイジャック/置換drupal.attachBehaviorsカスタム実装では、重みを尊重します。


他の回答で示唆されているように、なぜモジュールの重みではないのですか?

  • モジュールの重量は非常に重いツールです。これは、モジュールのすべてのフック実装(php)および動作(js)に適用されますが、1つの単一の動作のみに関心があります。
  • jsオブジェクト内のプロパティの順序は仕様によって保証されていません(ほとんどすべてのブラウザーで期待どおりに実装されていますが)。

見る
JavaScriptオブジェクトのフィールドの順序は、それらをループするときに予測可能ですか? および
要素順序-for(…in…)javascriptのループ

5
donquixote

Drupal 6の場合-

これが移植可能である必要がない場合の単純な解決策は、最後に実行するJSをテーマのtemplate.phpファイルに配置することです。テーマdrupal_add_js呼び出しは常にモジュールの後に呼び出されます。

ポータブルにする必要がある場合、drupal 6の「最もクリーンな」ソリューションは、phpを使用したモジュールとは異なる重みを持つ新しいモジュールを追加することです。2つのモジュールを同じフォルダー、最初のモジュールを最初のモジュールに依存させ、インストール/更新フックで重みを調整します。どれも必要ではなく、インストールを簡単にするだけです。

0
mirzu