升级到jQuery 3的挑战和解决方案

在2024年3月,jQuery的最新版本是3.7。在检查代码时,发现有超过2000处引用了旧版本的jQuery 1.8.3。为了更新这些引用,花费了一整天的时间将它们指向最新的jQuery版本,并添加了对jQuery Migrate插件的引用,该插件可以帮助处理已弃用代码。然而,当完成这些工作后,登录按钮变得无响应,并出现了错误信息:“在初始化之前无法调用对话框的方法——尝试调用方法close”。

错误堆栈指向了以下代码行,这是jQuery UI对话框关闭按钮的事件处理程序:

<script> .click(function() { $(this).dialog('close'); location.reload(); }) </script>

意识到,在jQuery 3中,上述代码中的$(this)不再引用当前活动的jQuery UI对话框。因此,$(this).dialog()是未定义的,错误消息提示在调用方法close之前先初始化对话框。为了修复这个问题,添加了.closest('.ui-dialog-content')来定位最近的jQuery UI对话框:

<script> .click(function() { $(this).closest('.ui-dialog-content').dialog('close'); location.reload(); }) </script>

这样,登录页面就可以正常工作了,但是在后续页面上的一个按钮出现了类似的错误信息:“在初始化之前无法调用对话框的方法——尝试调用方法enable”:

<script> $('#remove-button').toolbarbutton('enable', function() { ... }); </script>

在这里,toolbarbutton是代码中使用的一个自定义UI控件。经过一些调试,确定在调用方法enable之前,$('#remove-button')没有被初始化为toolbarbutton(),尽管初始化代码在$(document).ready()方法中已经存在。通过在调用enable之前再次初始化按钮来解决了这个问题:

<script> $('#remove-button').toolbarbutton({ state: 'enabled' }); $('#remove-button').toolbarbutton('enable', function() { ... }); </script>

然后是这个顽固的jQuery spinner控件,它在调用spinner-up方法时抱怨未初始化,尽管已经使用了上述技巧。暂时通过捕获异常来修复它。由于该方法只是在某些情况下禁用spinner,这是可选的,因此对UI没有影响:

<script> try { $(this.element).next().next('.spinner-up').setElementDisabled(false); } catch (err) { console.log("spinner error: " + err); } </script>

很少在JavaScript中使用try/catch,但在这种情况下,捕获异常并忽略错误是唯一能让事情工作的方法。

在修复了数百个类似的问题之后,页面部分功能正常,但复选框仍然存在问题。然后不得不将已弃用的.attr()替换为.prop(),这样复选框才能再次工作:

<script> // element.attr('checked', false); // 旧版本 element.prop('checked', false); // 新版本 </script>

还更新了对.live()的几次调用(这已被移除)到.on()(jQuery v3支持),以便事件绑定能够正常工作。接下来,遇到了一个JavaScript错误:$.browser.msie,这是一个布尔值,用于确定用户是否在Microsoft Internet Explorer中。由于IE不再被支持,这个属性在最新版本的jQuery中已被移除。通过声明一个自定义方法来解决这个问题,该方法为$.browser.msie返回false

<script> (function($) { // 定义一个空对象$.browser $.browser = {}; // 用一个虚拟的msie属性扩展jQuery.browser $.extend($.browser, { msie: false }); // 覆盖对$.browser.msie的访问 Object.defineProperty($.browser, 'msie', { get: function() { return false; } }); })(jQuery); </script>

这样,解析用户代理的代码现在可以正常工作了。最后一个挑战也是最困难的一个,是偶尔出现的空的OK/Cancel按钮,如下所示:

这两个按钮应该是OK和Cancel,虽然它们是空的,但仍然按设计工作。根据,如果页面加载了多个冲突的jQuery版本,例如同时加载了1.8和3版本的.js文件,就会出现这个问题。经过大量的故障排除努力,发现尽管已经将代码中的所有jQuery引用更新到了最新版本,但这个门户的这部分是从远程站点加载应用程序的,该站点仍然包含过时的jQuery库。由于无法更新远程jQuery库,不得不使用CSS为Cancel按钮添加❌,为OK按钮添加✓,以便按钮看起来不为空:

<style> button.okbutton::before { content: "\2713"; } button.cancelbutton::before { content: "\274C"; } </style>
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485