将 jQuery.once() 替换为 JavaScript once() 在 Drupal 10 中
Drupal 10 来了!而且 Drupal 10 不再包含 drupal/jquery.once 库:
https://www.drupal.org/node/3158256
jQuery once 已从 Drupal 核心中移除,但它仍然存在于许多贡献模块中:

模块维护者收到了带有 “Automated Drupal 10 compatibility fixes”(Drupal 10 自动兼容性修复)的补丁更新工单:
https://www.drupal.org/project/media_library_edit/issues/3288511
但是这些更新并不包含对 jquery.once 的修复。因此许多维护者认为模块已经准备好支持 Drupal 10,而没有进行测试。
所以,如果你遇到错误 “Uncaught TypeError: $(...).once is not a function”,别担心,这很容易修复。
1. 你需要在 *.libraries.yml
文件中将 core/jquery.once
库替换为 core/once
(见上方截图)
dependencies:
- core/jquery
- core/once
2. 更新 JavaScript 代码,将 $.once()
替换为 JavaScript once()
,例如使用 jQuery.once() 的代码:
Drupal.behaviors.fileBrowserClickProxy = {
attach: function (context, settings) {
$('.grid-item', context).once('bind-click-event').click(function () {
// javascript/jQuery 代码在这里.
});
}
};
使用 JavaScript once() 的代码(Drupal 10 可运行代码):
Drupal.behaviors.fileBrowserClickProxy = {
attach: function (context, settings) {
$(once('bind-click-event', '.grid-item', context)).each(function () {
$(this).on('click', function() {
// javascript/jQuery 代码在这里.
});
});
}
};
Drupal 10 仍然在使用 jQuery,因此我们可以将 once()
函数包裹在 jQuery 符号 $
中,这样它会返回一个来自 once()
函数的 jQuery 对象,我们就可以使用 jQuery 的 .each()
方法。
你也可以在自定义 JavaScript 中完全不使用 jQuery:
https://youmightnotneedjquery.com/
Drupal.behaviors.fileBrowserClickProxy = {
attach: function (context, settings) {
once('bind-click-event', '.grid-item', context).forEach(el => {
el.addEventListener('click', () => {
// 这里只使用原生 Javascript.
});
el.classList.add(className);
});
}
};
但这样的话,你就需要重写 'click'
回调函数内部的所有 jQuery 代码。