在WordPress中使用jQuery时,如何让$(document).on正常执行?
问题原因分析
这个报错的核心原因有两个,缺一不可:
- jQuery版本过低:你的主题把WordPress原生的jQuery(WP4.7自带的是1.12.4版本,完全支持
on()方法)替换成了jQuery 1.4,而$(document).on()这个方法是从jQuery 1.7版本才正式引入的,1.4版本根本没有这个API,所以执行时直接抛出TypeError。 - WordPress的jQuery无冲突模式补充:WordPress默认加载的jQuery是启用了
noConflict()模式的,这意味着$不会自动指向jQuery对象,必须用jQuery来调用方法。但你在全新WP4.7里装插件没问题,是因为正规的WordPress插件都会处理这种情况——要么用jQuery代替$,要么用自执行函数把$映射为jQuery(比如(function($){ ... })(jQuery))。但你的情况里,版本过低才是最致命的问题,哪怕解决了$的映射,1.4也没有on()方法。
不修改插件的解决方案
因为你提到移除主题的jQuery替换代码会出现其他错误,说明旧主题依赖这个老版本的jQuery或者特定的加载方式,我们可以用以下两种方式解决:
方案1:升级主题加载的jQuery版本到兼容版
把主题functions.php里的jQuery替换代码,改成加载至少1.7以上的jQuery版本(推荐用和WP4.7原生接近的1.12.x,兼容性最好),同时保留无冲突模式的兼容处理:
// Load jQuery (升级到兼容版本) if ( !is_admin() ) { wp_deregister_script('jquery'); // 换成jQuery 1.12.4,和WP4.7原生版本一致 wp_register_script('jquery', ("https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"), false, '1.12.4'); wp_enqueue_script('jquery'); // 添加$映射,兼容主题里用$的代码 add_action('wp_footer', function(){ ?> <script type="text/javascript"> // 把$映射为jQuery,兼容主题和插件的写法 jQuery(document).ready(function($){ // 这里主题里依赖$的代码可以正常运行 }); // 或者直接全局映射(如果主题没有其他冲突脚本) var $ = jQuery.noConflict(); </script> <?php }); }
这样既解决了on()方法不存在的问题,又能让主题里依赖$的代码继续工作,同时插件的$(document).on()也能正常执行。
方案2:保留主题的jQuery,但为插件添加兼容补丁
如果实在不想升级jQuery版本(不推荐,因为1.4有很多安全漏洞),可以给插件的脚本添加一个补丁,把on()方法替换成1.4支持的bind()或者delegate()方法,不需要修改插件文件,只在主题里添加代码:
// 在主题functions.php里添加 add_action('wp_enqueue_scripts', function(){ // 确保在GDPR插件的脚本之后加载补丁 wp_add_inline_script('gdpr-public', ' // 为老版本jQuery添加on方法的兼容补丁 if (!jQuery.fn.on) { jQuery.fn.on = function(event, selector, handler) { if (selector && typeof selector === "function") { // 当没有选择器时,用bind return this.bind(event, selector); } else { // 有选择器时,用delegate return this.delegate(selector, event, handler); } }; } ', 'after'); });
这个补丁会在GDPR插件的gdpr-public.js加载后,给低版本的jQuery补上on()方法的兼容实现,模拟高版本的行为,这样插件的代码不用修改就能正常运行。
额外注意事项
- 优先选择方案1,因为jQuery 1.4是2010年的版本,存在大量已知的安全漏洞和兼容性问题,升级到较新的版本(和WP原生一致的版本)对整个网站的安全性和稳定性都有好处。
- 如果升级后主题还是有错误,需要排查主题里哪些代码依赖了jQuery 1.4的过时API,比如
live()(已经被on()取代),然后逐步修改这些代码,这是长远来看更健康的做法。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

