7.2.4 drupal_add_library
另外,你还可以使用drupal_add_library添加js库。格式如下:
drupal_add_library($module, $library);
这里,库指的是一个js+css的集合,库中还可以包含其它依赖的库。例如,Drupal7中所包含jQuery UI,就是一个库,并且,这个库存在于核心的 system模块中,如果你想引入整个jQuery UI,你可以这样:
<?php
drupal_add_library('system', ‘ui');
?>
当它其中的子库ui.autocomplete被页面某个元素调用的时候,为了使其正常工作,还需要同时在页面上引入ui.core和ui.position。如果你使用drupal_add_js的话需要引入三次,这还不包括对应的css。但是,drupal_add_library可以一次性为我们搞定这些事情。你只需要使用以下代码引入ui.autocomplete,就可以引入相关的CSS/JS/依赖的子库:
<?php
drupal_add_library('system', 'ui.autocomplete');
?>
这一个语句就引入了 jquery.ui.autocomplete.js, jquery.ui.autocomplete.css, 以及所依赖的 jquery.ui.position.js, jquery.ui.widget.js, jquery.ui.core.js, jquery.ui.core.css, 和 jquery.ui.theme.css.
7.3.1 drupal中的JS 的写法
ok,经过上面的学习,你已经学会如何引入js语句了,那么在Drupal中js的写法有什么特殊之处呢?
假设,我们的jQuery文件内容如下——它看上去和平常的jQuery代码没有什么区别:
$(document).ready(function(){ $(‘h1’).addClass('my-class'); });
如果我们直接引入这个文件,在Drupal中就会出现本章第一节中第7点所提到的错误,解决方案如下:
1 用jQuery代替美元符号$:
jQuery(document).ready(function(){ $(‘h1’).addClass('my-class'); });
2 用下面红色代码包围原始文件:
(function($){
$(document).ready(function(){
$(‘h1’).addClass('my-class');
});
})(jQuery);
另外,由于在jQuery中 //https://api.jquery.com/ready/
$( document ).ready(function() { // Handler for .ready() called. });
和
$(function() { // Handler for .ready() called. });
是等效的,所以你也可以把上面的代码写为:
(function($){
$(function() {
$(‘h1’).addClass('my-class');
});
})(jQuery);
3 用drupal7自己的 behaviors
(function($){ Drupal.behaviors.behaviorName = { attach: function (context, settings) { $(‘h1’).addClass('my-class'); } }; })(jQuery);
我们还可以将context变量作为jQuery选择器的第二个参数,这样效率更高。所以代码还可以写成这样:
(function($){ Drupal.behaviors.behaviorName = { attach: function (context, settings) { $(‘h1’, context).addClass('my-class'); } }; })(jQuery);
7.3.2 Drupal.behaviorsv和 jQuery $.once()
在上面提到的方法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-drupal
最后仅以下图纪念在社区中那些快乐的片段:
子曰:“学而时习之,不亦悦乎?有朋自远方来,不亦乐乎?人不知而不愠,不亦君子乎?”—— 《论语·学而》
请指教
drupal_add_library();这个语句是加在那些文件里的?
赞~~~
赞~~~