在上面提到的方法2中的
$(document).ready(function(){ $(‘h1’).addClass('my-class'); });
只会在页面完全加载后执行一次,这种方式对于大多数的情况都没有问题,但是对于AJAX事件就会力不从心了。因为AJAX事件会在页面加载之后改变DOM,而事件发生之后,由于页面并没有重新加载,因此js语句不会再次执行。
为了解决这个问题,jQuery给出了live()方法,以确保AJAX事件发生之后JS语句的有效性。
与此同时,Drupal也给出了自己的方法Drupal.behaviors,也就是上节中的方法3。
Drupal.behaviors的特点在于,每当DOM被完全载入,或者每当DOM发生改变,它所包含的js语句都会被执行一次。因此,当你使用Drupal.behaviors的时候,你不再需要使用$(document).ready来帮你判断你的DOM是否已经做好准备了。并且,当DOM发生改变的时候,你也不再需要使用jQuery的live()。
使用Drupal.behaviors不是必须的,但是是推荐的最佳实践。如下:
Drupal.behaviors.behaviorName = {
attach: function (context, settings) {
// Do something.
},
detach: function (context, settings, trigger) {
// Undo something.
}
};
Drupal.behaviors往往会在页面上被调用多次。这样,发生Ajax事件以后,就可以确保对DOM中新的元素执行Drupal.behaviors中的命令。但是,这样会使得DOM中原有的元素被重复执行Drupal.behaviors中的命令——虽然,很多时候,肉眼看不出变化。这样,效率会比较低,有些时候,可能还会导致一些意想不到的错误。因此我们使用 jQuery.once()来保证JS语句只运行一遍,而且它被加入了Drupal的核心中。 jQuery.once()会对已经被执行过对应JS语句的元素添加一个简单的class作为标记,并在下一次Drupal.behaviors执行的时候,找到这些标记,并跳过相应的元素。
例子如下
(function ($) {
Drupal.behaviors.mybehavior = {
attach: function (context, settings) {
$('#some_element', context).once('mybehavior', function () {
// Code here will only be applied to $('#some_element')
// a single time.
});
}
};
})(jQuery);
更多详情请参考: https://www.drupal.org/node/756722
https://www.lullabot.com/articles/understanding-javascript-behaviors-in…
最后仅以下图纪念在社区中那些快乐的片段:
子曰:“学而时习之,不亦悦乎?有朋自远方来,不亦乐乎?人不知而不愠,不亦君子乎?”—— 《论语·学而》