翻译者:长风Drupal开发
原文链接:https://www.drupal.org/docs/8/api/javascript-api/accessibility-tools-for-javascript-in-drupal-8
1、Drupal8 JavaScript
Drupal8 JavaScript发生了很大变化。 JavaScript文件,在Drupal 7中的.info文件中引用,Drupal8中被引用到.YML文件中。
在Drupal8中,Drupal8 stylesheets (CSS) and JavaScript (JS) 是通过系统加载的Drupal模块(代码)和Drupal8主题:asset libraries。
Drupal8使用高级原则:Drupal8只加载你告诉它应该加载的assets (CSS和JS)。Drupal8不是在载所有页面上的assets (CSS/JS) ,因为这对前端性能很不利。
可配置的JavaScript与drupalSettings(与Drupal7中的Drupal.settings类似)的继承是可用的。但是,为了使drupalSettings 可以用于JavaScript文件:我们必须声明对它的依赖。
Drupal.behaviors
当使用jQuery时,对于大多数情况来说,将$(document).ready()函数中的几乎所有代码包装起来是标准的,如下所示:
$(document).ready(function () {
// Do some fancy stuff.
});
这确保了我们的代码只在DOM加载后以及所有元素都可用的情况下才运行。然而,Drupal8有另一种更好的方法:使用Drupal.behaviors and once()的功能。如果使用得当,这将确保您的代码运行在正常页面负载和数据加载时,由Ajax(或BigPi管!)-但不是应该避免的像load()这样的jQuery方法,因为Drupal.behaviors对将无法加载除ajax()之外的函数。Drupal.behaviors对象本身是Drupal8对象的属性,当我们希望我们的模块/主题添加新的jQuery行为时,最好的方法是简单地扩展这个对象。
2、一个Drupal8 JavaScript的真实例子
Drupal.behaviors.myBehavior = {
attach: function (context, settings) {
// Using once() to apply the myCustomBehaviour effect when you want to run just one function.
$('input.myCustomBehavior', context).once('myCustomBehavior').addClass('processed');
// Using once() with more complexity.
$('input.myCustom', context).once('mySecondBehavior').each(function () {
if ($(this).visible()) {
$(this).css('background', 'green');
}
else {
$(this).css('background', 'yellow').show();
}
});
}
};
定义为Drupal.actions属性的任何对象都将在DOM最初加载时以及在任何AJAX调用之后调用.()方法。drupal.js有一个$(document).ready() 函数,调用Drupal.attachBehaviors() 函数,该函数依次循环调用Drupal.behaviors对象的每个属性,所有这些都是由各种模块如上声明的函数,并将文档作为上下文传入。在Ajax加载中,除了上下文仅是加载Ajax调用的新内容之外,发生了同样的事情。(而且由于BigPipe在内部构建在AJAX系统之上,所以任何与AJAX系统一起工作的东西都会与BigPipe一起工作。)
每当调用附加行为时,就会触发Drupal行为。传入的上下文变量通常可以让您更好地了解正在处理什么DOM元素,但是它不是确定是否再次处理某个元素的方法。使用带有“context”的jQuery选择器是一个很好的实践,因为只有给定的上下文被搜索,而不是整个文档。当在Ajax请求之后附加行为时,这一点变得更为重要。
注意:因为Drupal8使用jQuery.noConflict()并在需要时只加载JavaScript文件,所以要使用jQuery和jQuery的$符号,必须在MODULE.libraries.yml中的库定义中包括jQuery和Drupal作为依赖项,并在函数.libraries.yml周围添加包装器。所以整个JavaScript文件看起来都是这样的:
(function ($, Drupal) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$('input.myCustomBehavior', context).once('myCustomBehavior').each(function () {
// Apply the myCustomBehaviour effect to the elements only once.
});
}
};})(jQuery, Drupal);
3、Drupal8 JavaScript的引用
要将jQuery作为自定义库的显式依赖项添加一次,请添加core/jquery.once,如下面的MODULE.libraries.yml或THEME.libraries.yml所示:
foobar:
js:
js/foobar.js: {}
dependencies:
- core/jquery
- core/jquery.once