6.8. 在 Drupal 中使用 JavaScript / jQuery:什么是 Behaviors?
首先,让我们回顾一下如何在主题中引入自定义 JavaScript 文件。在 .libraries.yml
文件中,我们需要添加 js 部分:
global-styling:
version: 1.x
css:
theme:
css/style.css: {}
css/print.css: { media: print }
js:
js/custom.js: {}
dependencies:
- core/jquery
- core/jquery.once
请注意缩进,必须为两个空格。这样,我们就包含了 js/custom.js
文件。但仅仅这样还不够,Drupal 核心默认并不会自动加载 jQuery。要启用 jQuery,必须显式地声明依赖:
dependencies:
- core/jquery
此外,我们还使用 jQuery.once()
插件,它可以确保事件和方法只绑定到选择器一次,避免重复执行。
dependencies:
- core/jquery
- core/jquery.once
这是因为在 Drupal 中,我们编写的 JavaScript 代码可能会在不同事件中多次触发。因此,为了防止重复执行,我们需要使用 .once()
方法。
现在我们在 custom.js
文件中添加一些示例代码:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$(context).find('.click-me').once('myCustomBehavior').click(function () {
alert('Hello, World!');
});
}
};
})(jQuery);
让我们逐步理解这段代码。
首先,Drupal 中的 jQuery 运行在 .noConflict()
模式下,因此不能直接使用 $
,必须用这种写法:
(function ($) {
})(jQuery);
这样,我们就可以在内部安全地使用 $
符号,而不会与其他 JavaScript 框架(例如 Prototype、MooTools)冲突。
接下来是 Drupal 的核心概念 —— Behaviors(行为)。
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
}
};
})(jQuery);
当您在 Drupal 中编写 jQuery 代码时,必须同时使用 function ($) 封装和 behavior 行为定义。每个 behavior 名称必须唯一,例如这里的 myModuleBehavior
。可以定义多个 behavior:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
}
};
Drupal.behaviors.productPageBehavior = {
attach: function (context, settings) {
}
};
})(jQuery);
命名行为时应使用 camelCase(驼峰命名)。Behavior 会在页面加载时触发,也会在每次 AJAX 请求后再次执行。这意味着当新内容通过 AJAX 加载并插入页面结构时,Behavior 中的代码都会再次运行。这与以下旧式写法不同:
$(document).ready(function () {
// 执行一些代码
// 请不要在 Drupal 中使用这种写法
});
该写法只会在页面首次加载时执行一次,而不会在 AJAX 更新后再次触发。
如果您在使用 Behavior 时发现某些事件被多次执行,例如多次添加了一个区块,可以参考以下错误示例:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Behavior 会在页面上多次被调用,不要忘记使用 .once() 函数。
$('.inner').append('<p>Test</p>');
}
};
})(jQuery);
此时,每次 AJAX 请求都会新增一个 <p>Test</p>
段落。解决方法是使用 .once()
:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Behavior 会在页面上多次被调用,不要忘记使用 .once() 函数。
$('.inner').once('add-paragraph').append('<p>Test</p>');
}
};
})(jQuery);
context 变量也是 Behavior 的一个重要特性。每次当页面加载或通过 AJAX 添加新内容时,新插入的 DOM 元素都在 context
中。因此,我们不需要在每次 AJAX 请求后遍历整个 DOM,只需在 context
中查找目标元素即可:
(function ($) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
// Behavior 会在页面上多次被调用,不要忘记使用 .once() 函数。
$(context).find('.inner').once('add-paragraph').append('<p>Test</p>');
}
};
})(jQuery);
这样写的代码就符合 Drupal 的标准风格。虽然仍可以使用传统的 $(document).ready()
,但它仅在页面加载时执行一次,并且性能不如 Behavior。
如果您对 jQuery / JavaScript 或 Drupal 主题开发有任何疑问或建议,欢迎在评论中留言。