Drupal 8自定义主题不同JavaScript文件间无法调用函数的报错问题
错误原因
- 作用域限制:你定义的
test()函数属于$(document).ready()回调函数的局部函数,仅能在该回调内部访问,外部作用域无法读取。 - 闭包隔离:两个JS文件都使用了IIFE立即执行函数包裹代码,默认闭包内部的变量、函数不会泄漏到全局作用域,因此file2无法访问到file1内部定义的方法。
- 额外语法错误:file1.js中
console.log('hello')末尾误写为冒号:,需要修改为半角分号;,否则也会触发JS执行报错。
修复方案
按照Drupal的JS开发规范,建议将需要跨文件共享的方法挂载到全局Drupal对象上,同时优先使用Drupal内置的Behaviors机制代替原生$(document).ready,避免作用域污染同时兼容Drupal的AJAX等场景的执行逻辑。你现有的customtheme.libraries.yml和customtheme.info.yml配置没有问题,file1的加载顺序在file2之前,无需调整。
1. 修改file1.js
/** * @file * UI behaviors */ (function ($, Drupal) { 'use strict'; // 将需要共享的方法挂载到Drupal全局对象 Drupal.test = function() { console.log('hello'); }; // 替换原$(document).ready写法,符合Drupal开发规范 Drupal.behaviors.file1Init = { attach: function (context, settings) { // 本文件内需要调用test方法可直接执行 Drupal.test() } }; })(jQuery, Drupal);
2. 修改file2.js
/** * @file * UI behaviors */ (function ($, Drupal) { 'use strict'; Drupal.behaviors.file2Init = { attach: function (context, settings) { // 直接调用file1挂载的共享方法 Drupal.test(); } }; })(jQuery, Drupal);
替代方案(不推荐)
如果你不想遵循Drupal规范挂载方法,也可以临时将函数挂载到window全局对象,修改file1.js的test定义为window.test = function() {console.log('hello')};,file2内直接调用test()即可,缺点是会污染全局作用域,容易和其他第三方脚本的变量/函数名冲突。
内容的提问来源于stack exchange,提问作者Charly
相关产品推荐
相关产品推荐

