logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

在 Drupal 8 模块中添加样式表 (CSS) 和 JavaScript (JS)

03/10/2025, by Ivan

本指南适用于模块。关于主题的信息,请参阅 在 Drupal 8 主题中添加样式表 (CSS) 和 JavaScript (JS)

在 Drupal 8 中,样式表 (CSS) 和 JavaScript (JS) 的加载通过同一个资源库系统完成,适用于模块(代码)和主题。资源库可以包含一个或多个 CSS 文件、一个或多个 JS 文件以及一个或多个 JS 配置。

Drupal 遵循一个高级原则:资源 (CSS 或 JS) 只有在你告诉 Drupal 需要加载时才会被加载。Drupal 不会在所有页面上加载所有资源 (CSS/JS),因为这会对前端性能产生负面影响。

与 Drupal 7 的区别

对开发者而言,Drupal 7 与 Drupal 8 有两个重要区别:

1. 只有特定页面所需的 JavaScript 才会被添加到该页面。特别是,对于大多数匿名用户可见的页面,Drupal 默认不加载 JavaScript。这意味着 jQuery 不再自动加载到所有页面
因此,如果你的主题需要 jQuery 或其他 JavaScript(且这些脚本也定义在资源库中),你需要显式声明依赖关系。

2. Drupal.settings 对象被替换为 drupalSettings。

流程

加载资源 (CSS / JS) 的基本步骤:

1. 将 CSS 或 JS 保存到文件中。
2. 定义一个“资源库”,它可以包含 CSS 和 JS 文件。
3. 在 hook 中将该资源库“附加”到渲染数组。

但对于主题而言,还有另一种选择:主题可以在所有页面上加载任意数量的资源库。

定义资源库

要定义一个或多个资源库,请在模块根目录下(与 .info.yml 文件在同一目录)添加一个 *.libraries.yml 文件。如果你的模块名为 fluffiness,则文件名应为 fluffiness.libraries.yml。每个资源库是一个条目,描述 CSS 和 JS 文件,例如:

cuddly-slider:
  version: 1.x
  css:
    layout:
      css/cuddly-slider-layout.css: {}
    theme:
      css/cuddly-slider-theme.css: {}
  js:
    js/cuddly-slider.js: {}

注意 CSS 中有 'layout' 和 'theme' 键,而 JS 中没有。这些键表示 CSS 文件的样式类别。

你可以用 5 种不同的样式级别来设置 CSS 权重:

  • base: CSS reset/normalize 以及 HTML 元素的基础样式。权重 = -200
  • layout: 页面宏观布局,包括网格系统。权重 = -100
  • component: 可复用的 UI 组件。权重 = 0
  • state: 与组件状态变化相关的样式。权重 = 100
  • theme: 与视觉外观相关的样式。权重 = 200

这遵循 SMACSS 标准。

在这个例子中,cuddly-slider.js 位于模块的 js 子目录下。你也可以引用外部 JS 或 CSS,详见 CDN/外部库

由于 Drupal 8 默认不在所有页面加载 jQuery,我们必须声明 cuddly-slider 库依赖于 core/jquery:

cuddly-slider:
  version: 1.x
  css:
    theme:
      css/cuddly-slider.css: {}
  js:
    js/cuddly-slider.js: {}
  dependencies:
    - core/jquery

CSS 和 JS 的加载顺序与定义顺序一致。

默认情况下,Drupal 将 JS 加载到页面底部,以避免阻塞 DOM 加载。如果你需要在 <head> 部分加载,可以设置 header 参数:

cuddly-slider:
  version: 1.x
  header: true
  js:
    js/cuddly-slider.js: {}

这样 cuddly-slider.js 就会加载在页面顶部。

将资源库附加到页面

根据所需的资源,你可以以不同方式附加资源库。关键不是基于 URL 或路由来决定,而是基于页面上显示的“元素”。例如,如果页面包含 '#type' => 'table',则只加载与 table 相关的库。

下面是几种方式:

附加到所有某个 “#type”

function yourmodule_element_info_alter(array &$types) {
  if (isset($types['table'])) {
    $types['table']['#attached']['library'][] = 'your_module/library_name';
  }
}

附加到渲染数组

$build['element']['#attached']['library'][] = 'your_module/library_name';

附加到 Block 插件

return [
  '#theme' => 'your_module_theme_id',
  '#attached' => [
    'library' => ['your_module/library_name'],
  ],
];

附加到表单

function yourmodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#attached']['library'][] = 'yourmodule/yourlibrary';
}

附加到所有页面

function contextual_page_attachments(array &$page) {
  if (\Drupal::currentUser()->hasPermission('access contextual links')) {
    $page['#attached']['library'][] = 'contextual/drupal.contextual-links';
  }
}

附加到 Twig 模板

{{ attach_library('your_module/library_name') }}
<div>Some markup {{ message }}</div>

附加 drupalSettings

$build['#attached']['library'][] = 'your_module/library_name';
$build['#attached']['drupalSettings']['fluffiness']['cuddlySlider'] = [
  'foo' => 'bar',
  'baz' => 'qux',
];

禁用聚合

cuddly-slider:
  version: 1.x
  js:
    js/cuddly-slider.js: { preprocess: false }

更多信息