原文地址:
https://docs.acquia.com/articles/drupal-8-adding-javascript-css-libraries-components
Drupal 7 里,推荐使用渲染数组里的 #attached 向组件添加 JavaScript 或 CSS 。许多开发者也使用 drupal_add_js,drupal_add_css 和 drupal_add_library 。Drupal 8 只支持 #attached 。所以现在推荐把所有的 JavaScript 和 CSS 定义为一个库,之后附加到渲染数组。
创建一个库
模块的 libraries.yml 文件把你渲染页面所需要的 CSS 和 JavaScript 定义为库。这个文件指定了库中每个组件的位置。
下面是 theme_example.libraries.yml 例子。在这个例子中,我们只定义了一个库 sample-library。它包含 JavaScript 和 CSS,也依赖几个核心库。Drupal 7 里,我们假定 jQuery,jQuery.once 和 settings 是有效的。Drupal 8,你必须把这些定义为依赖,因为默认它们不会被加载。
sample_library: css: # For some reason, you need to put css under 'theme'. theme: css/example.css: {} js: # For some reason, you need to put the js directly under 'js'. js/example.js: {} dependencies: # jQuery is not included by default, so we add it as a dependency - core/jquery # We are also going to use jQuery.once so that code doesn't trigger multiple times. - core/jquery.once # drupal and drupalSettings are not included by default either. - core/drupal
这两个 CSS 例子可以在库中使用:
myElement { border: 3px solid purple; border-radius: 3px; padding: 1em; margin: 1em; background-color: #EEE; } .myElement .randomNumber { color: purple; font-weight: bold; font-size: 1.2em; }
向组件附加库
我们已经有了库,现在可以在渲染数组内引用了。
$output = [ '#markup' => '<div>hello world</div>', '#attached => [ 'library' => [ 'theme_example/sample_library', ], ], ];
我们也可以定义一个传递给 JavaScript 的设置。
$output = [ '#markup' => '<div>hello world</div>', '#attached => [ // This setting will be sent to drupalSettings.sampleLibrary.mySetting. 'drupalSettings' => [ 'sampleLibrary' => [ 'mySetting' => 'hello world', ], ], ], ];
更新插件 #pre_render 函数:
最后更新 src/Element/MyElement.php 文件:
/** * Prepare the render array for the template. */ public static function preRenderMyElement($element) { // Create a link render array using our #label. $element['link'] = [ '#type' => 'link', '#title' => $element['#label'], '#url' => Url::fromUri('http://www.drupal.org'), ]; // Create a description render array using #description. $element['description'] = [ '#markup' => $element['#description'] ]; $element['pre_render_addition'] = [ '#markup' => 'Additional text.' ]; // Create a variable. $element['#random_number'] = rand(0,100); // Add the library $element['#attached'] = [ 'library' => [ 'theme_example/sample_library', ], 'drupalSettings' => [ 'sampleLibrary' => [ 'mySetting' => 'hello world', ], ], ]; return $element; }
Drupal 8 中的 JavaScript 模式
JavaScript 的最佳实践与 Drupal 7 相同。我们把 jQuery 对象包裹在一个闭包内,把函数附加在 Drupal.behaviors 上。主要的变化是:设置变量现在是 drupalSettings 。
(function ($) { Drupal.behaviors.themeExample = { attach: function (context, settings) { // jQuery once ensures that code does not run after an AJAX or other function that calls Drupal.attachBehaviors(). $('body').once('themeExample').each(function () { // We have console.log() here to make it easy to see that this code is functioning. You should never use console.log() on production code! if (typeof console.log === 'function') { console.log('My Setting: ' + settings.sampleLibrary.mySetting); } }); if (typeof console.log === 'function') { console.log('This will run every time Drupal.attachBehaviors is run.'); } $('body').once('themeExampleModifyDOM').each(function () { // Add an element to the body. $('body').append('<div>Hello World</div>'); // Tell Drupal that we modified the DOM. Drupal.attachBehaviors(); }); } }; })(jQuery);
测试库是否工作
导航到路径 /examples/theme-example/simple,使用 Chrome 或 FireFox 查看控制台。你会看到 JavaScript 库产生的消息。
文件
这个练习中应该有这些文件:
- theme_example.info.yml
- theme_example.routing.yml
- theme_example.libraries.yml
- theme_example.module
- cs/example.css
- js/example.js
- src/Element/MyElement.php
- src/Controller/ThemeExampleController.php
- templates/my-element.html.twig