WordPress中Defer导致jQuery-ui依赖脚本报错求助
Uncaught TypeError: $(...).accordion is not a function 问题 咱们一步步拆解这个错误的根源,然后针对性解决:
1. 先确认jQuery UI是否真的包含Accordion组件
你现在加载的是https://code.jquery.com/ui/1.10.0/jquery-ui.min.js,但要注意:有些CDN的jQuery UI包是「核心精简版」,只包含基础功能,并没有Accordion这类交互组件。这很可能是你找不到accordion方法的直接原因。
- 如果坚持用CDN,建议换用完整版本的jQuery UI;
- 更省心的是用WordPress自带的jQuery UI模块——WordPress已经把jQuery UI拆成了独立组件,你可以精准加载需要的部分:
这样能100%确保Accordion模块被正确加载,而且WordPress会自动处理依赖顺序。// WordPress自带jQuery,不用自己从CDN拉取 wp_enqueue_script('jquery'); // 加载jQuery UI核心 + Accordion组件 wp_enqueue_script('jquery-ui-core'); wp_enqueue_script('jquery-ui-accordion');
2. 修复你的Defer脚本逻辑
你提到的Defer函数给脚本加了defer="defer" onload src="...",这种写法会把脚本变成动态异步加载——这直接破坏了WordPress原本的依赖顺序控制!动态加载的脚本是并行下载的,谁先下完谁先执行,完全不管HTML里的顺序,所以你的自定义脚本很可能在jQuery UI加载完成前就跑起来了,自然找不到accordion方法。
正确的Defer处理应该是直接给脚本标签加defer属性,保留原src,这样浏览器会按HTML里的脚本顺序执行(在DOM加载完成后):
function add_defer_attribute($tag, $handle) { // 可以指定哪些脚本加defer,比如只给自定义脚本加,避免影响依赖 $scripts_to_defer = array('scripts'); foreach($scripts_to_defer as $defer_script) { if ($defer_script === $handle) { return str_replace(' src', ' defer="defer" src', $tag); } } return $tag; } add_filter('script_loader_tag', 'add_defer_attribute', 10, 2);
如果要给所有脚本加defer,只要WordPress输出的脚本顺序是对的(依赖在前,自定义脚本在后),defer的脚本会按顺序执行,也能保证依赖先加载。
3. 检查脚本依赖的配置
你的自定义脚本已经设置了依赖['jquery','jquery-ui'],但如果用的是WordPress自带的jQuery UI组件,依赖要改成对应的handle:
wp_enqueue_script('scripts', 'https://eg1234.cloudfront.net/wp-content/scripts/scripts.js', ['jquery','jquery-ui-core','jquery-ui-accordion'], '', true);
这样WordPress会确保这些依赖脚本在自定义脚本之前输出,配合正确的defer处理,执行顺序就不会乱。
4. 顺便解决jQuery冲突问题(可选)
WordPress自带的jQuery默认是noConflict模式,也就是$变量不会被自动注册。如果你在自定义脚本里用了$(...).accordion(),可以改成jQuery(...).accordion(),或者在脚本开头套个ready函数:
jQuery(document).ready(function($) { // 这里可以正常用$ $('.your-accordion-container').accordion(); });
这能避免因jQuery冲突导致的方法找不到问题。
内容的提问来源于stack exchange,提问作者roshambo

