如何控制Drupal.behaviors的顺序?


9

我希望模块X中的JavaScript代码仅在模块Y中的JavaScript代码运行后才能运行。最好的方法是什么?

Answers:


5

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()与插入到作为第二个参数的数组中插入顺序相同的顺序从传递到用作其第二个参数的函数。
这意味着插入的第一个行为将Drupal.behaviors首先执行。
在这种情况下,要允许首先执行模块定义的行为,可以使用更轻的重量。如果要在其他模块之前执行它们,则模块权重应设置为-50;否则,模块权重应设置为-50。其他值也可以。如果您使用的是Drupal 7,则drupal_add_js()允许将权重与JavaScript代码关联;重量更轻的JavaScript代码首先出现在HTML输出中。思想上,Drupal 6无法做到这一点。

JavaScript不保证以添加属性的顺序遍历属性。这意味着不同的JavaScript实现将以不同的顺序呈现相同的属性;这也意味着相同的顺序可能会在同一浏览器的不同版本中发生变化。


我曾经找到一个页面,其中列出了某些模块使用的重量。我不记得该页面的URL,并且该页面是否仅包含特定模块,或者它是否详尽无遗。如果找到该页面,我将在此处报告链接。
kiamlaluno

1
您总是可以只检查系统表-试试select name, weight from system where type = 'module' order by weight ASC, name
cam8001 2011年

不幸的是,我需要我的模块的PHP(mymodule)在其他模块的(vertical_tabs)PHP之前运行,但是我模块的JS要 vertical_tab的JS 之后运行。是否有一种纯粹基于JavaScript的举止行为方式?
cam8001 2011年

@ cam8001:我知道,但这意味着您应该安装所有模块,以了解模块使用的重量更轻。我发现的页面列出了模块权重,当您需要在每个模块之前知道要分配给模块的权重时,该页面可能会很有用。我知道,您可以仅使用极轻的重量,但是所使用的重量要比所需的重量轻。
kiamlaluno

@ cam8001:在这种情况下,除了更改Drupal.behaviors;中包含的对象的顺序之外,无法完成您尝试做的事情。正如我报告$.each(Drupal.behaviors)的那样,对象以插入对象的顺序列出,而不是基于其标识符。
kiamlaluno

5

使用行为权重模块。
(在生产现场使用它之前,请对其进行一些测试)

该模块允许将权重附加到行为,然后drupal.attachBehaviors通过自定义实现劫持/替换,该实现不尊重权重。


如其他答案中所建议的,为什么不使用模块重量呢?

  • 模块重量很重。它适用于模块的所有挂钩实现(php)和行为(js),而我们仅对单个行为感兴趣。
  • 规范不能保证js对象中属性的顺序(尽管它在几乎所有浏览器中都是按预期实现的)。

请参阅
遍历它们时javascript对象中字段的顺序是否可确定?
Elements order-for(…in…)在javascript中循环


@kiam,如果我在drupal.org上将此模块设置为“行为权重”(“ bewgt”),您是否愿意作为共同维护者加入?它可能只是一个很小的模块,但可能比让它与其他产品一起交付更好。我在D6本地有一个示例实现,似乎可以正常工作。
donquixote

刚刚完成了..您仍受邀:)
donquixote 2011年

drupal.org/node/1302126-我希望这将成为D8的核心:)
donquixote 2011年

这将是一个有趣的模块,但是我必须首先更新一些模块的代码,为此我从没写过一段代码。之后,我可以自由地共同开发一个新模块。
kiamlaluno

只是说,人们正在要求用例。drupal.org/node/1302126#comment-5911632
donquixote 2012年

0

对于Drupal 6-

一个简单的解决方案(如果不需要移植)是将要最后运行的JS放到主题template.php文件中。主题drupal_add_js调用始终在模块之后调用。

如果确实需要携带,则drupal 6中的“最干净”的解决方案是添加一个新模块,该模块的权重与使用php的模块的权重不同。您甚至可以将两个模块放在同一文件夹中,使第一个模块依赖第一个模块,然后在安装/更新挂钩中调整权重。都不是必需的,只是使安装更加容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.