升级到 jQuery 3.6.1 遇见的几个坑以及应对方法
创始人
2024-02-13 07:25:29
0

项目因安全问题(jquery 早期版本存在XSS 漏洞),需要整体将 jQuery 从 1.7.2 升级到 3.6.1 。早前就因为 jQuery 的版本兼容性不佳,因此对于版本升级的事情,能拖则拖。但升级的事情,总归是要做的,何况项目上因为甲方重视安全性,对于中等风险的安全也必须解决、规避,因此这回是硬着头皮上了。

第一阶段的问题,就是各种不兼容,各种不顺。好在同事方法多,路子广,找到了一个 jquery-migrate-3.4.0.js 文件,专治新旧版本兼容的 包,解决了大多数的问题。UI 界面总算能跑起来,能看得着了。

但是接下来,陆续遇到了几个问题:

问题一:curCSS 方法找不到问题

解决方法:

    jQuery.curCSS = function(element, prop, val) {return jQuery(element).css(prop, val);};

问题二:UI 布局错误,多处动态计算 div 占用的宽度、高度 进行自适应布局的页面都拉跨了。

仔细分析后发现,罪魁祸首出现在  outerWidth 和 outerHeight 方法上。

这两个方法,老版本 jquery (以 1.7.2 为例),例如调用 $("body").outerWidth() ,是可以返回整数值的。但是新版的方法,如果不带参数,则返回 元素的 jQuery 对象。 而由于程序将之视为 int 参与计算,因此导致后续计算错误,界面布局拉跨也就难免了。

另外,老版本 jQuery  对于查找器搜索不到的情况,比如 $("#不存在的id").outerWidth() 是会返回 0 的,因为将一个不存在的元素的宽度视为0,也算是容错的,但是新版本在这种情况下,直接返回 undefined,这也会造成一些代码上的问题。

OK,知道原因,就可以有解决方案,如下:

	var oldOuterWidth = jQuery.fn.outerWidth;jQuery.fn.outerWidth =function(  ) {if (arguments.length <= 0) {arguments[0] = false;arguments.length = 1;}var result = oldOuterWidth.apply( this, arguments ) ;return result === undefined ? 0 : result;};var oldOuterHeight = jQuery.fn.outerHeight;jQuery.fn.outerHeight =function(  ) {if (arguments.length <= 0) {arguments[0] = false;arguments.length = 1;}var result =  oldOuterHeight.apply( this, arguments );return result === undefined ? 0 : result;};	

问题三、添加 html 内容 出错,页面元素 层次错乱。

比如,有以下代码:

$("body").append('
ok
');

在旧版 jQuery 当中,页面内容渲染得到:

ok

但是在新版 jQuery 3.6.1 里得到的却是:

hello

两者差别就是,针对 的写法,渲染有不同。

造成这个差异的原因是什么呢?我们抛开 jQuery ,试试原生 JS 的效果:

document.children[0].children[1].innerHTML = '
ok';

结果渲染得到的与 jQuery 3.6.1 是一致的。也就是针对 这种写法,HTML 5 是不认的,因为 本身不属于 HTML5 非闭合标签 (所谓 非闭合标签,是类似
这种,数量有限),则 渲染引擎 将 视为未闭合。实际上 的写法,属于 XHTML ,而不是 HTML5 的规范。

奇怪的是,为啥旧版 jQuery 我们用着就没有问题,难道它在 append 方法里做了什么特殊处理? 

排查了源码,果不其然。如下:

			// Convert html string into DOM nodesif ( typeof elem === "string" ) {if ( !rhtml.test( elem ) ) {elem = context.createTextNode( elem );} else {// Fix "XHTML"-style tags in all browserselem = elem.replace(rxhtmlTag, "<$1>");

注释上明确说了 Fix "XHTML"-style tags in all browsers  。哎,我们这些一直误用的人啊,被老版本 jQuery 保护的太好了!

OK,为了确保此前的UI代码能继续使用,我们还是要得来个解决方案:

	var oldAppend = jQuery.fn.append;jQuery.fn.append =function(  ) {/*** 相关素材来自 jquery 1.7.2 */var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig;if (arguments.length > 0 && typeof(arguments[0]) == "string" ) {var elem = arguments[0];elem = elem.replace(rxhtmlTag, "<$1>");arguments[0] = elem;}return oldAppend.apply( this, arguments );};

至此,遇到的不兼容问题基本都解决了。我们将包含前述问题的解决办法,汇总到 以下 js 代码里,需要的各位可以自取。


( function() { /*** 注意,以下代码,应确保 引用在 jquery 3.6.1, jquery-migrate-3.4.0.min.js,以及 jquery-ui-1.8.10.custom.min.js 等内容之后,否则* 相关的 代码托管 可能会被取代 而 无效。   */jQuery.curCSS = function(element, prop, val) {return jQuery(element).css(prop, val);};/***  James add on 2022.11.24 , 相关代码摘录自 jquery 1.7.2*  此 修复是为了 兼容 以下有关写法,在 append 到 jquery 对象里时,能适应 老版本的渲染逻辑。*     $.append("
ttt
");* 上述内容,在 jquery 1.7.2 版本里,会被渲染为:*
ttt
* * 而在 jquery 3.6.1 里,则会被渲染为:*
ttt
* * 这是由于 在 旧版 jquery 里,针对 非闭合的标签有过特定处理,而在 jquery 3.6.1 里则移除了这个做法。* 因此直接在 element 的 innterHtml 里面写入
ttt
这个内容,* 与 3.6.1 里面是一致的。* * 所以根本上是不规范的 html 写法,只是老版本 jquery 做了容错,而新版本没有容错,因而导致问题。* */var oldAppend = jQuery.fn.append;jQuery.fn.append =function( ) {/*** 相关素材来自 jquery 1.7.2 */var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig;if (arguments.length > 0 && typeof(arguments[0]) == "string" ) {var elem = arguments[0];elem = elem.replace(rxhtmlTag, "<$1>");arguments[0] = elem;}return oldAppend.apply( this, arguments );};var oldOuterWidth = jQuery.fn.outerWidth;jQuery.fn.outerWidth =function( ) {if (arguments.length <= 0) {arguments[0] = false;arguments.length = 1;}var result = oldOuterWidth.apply( this, arguments ) ;return result === undefined ? 0 : result;};var oldOuterHeight = jQuery.fn.outerHeight;jQuery.fn.outerHeight =function( ) {if (arguments.length <= 0) {arguments[0] = false;arguments.length = 1;}var result = oldOuterHeight.apply( this, arguments );return result === undefined ? 0 : result;}; })();

注意,上述代码在页面中的引入,应确保在 jquery 3.6.1, jquery-migrate-3.4.0.min.js,以及 jquery-ui-1.8.10.custom.min.js 等内容之后,否则可能会被取代而无效。 

好了,感谢您收看我的文章,后会有期!

相关内容

热门资讯

一汽解放:公司经营优化,努力提... 投资者提问:公司经营如此糟糕,是否有出售闲置产能及裁撤人员的打算?否则长期每年无故增加的几十亿成本是...
上海汽配今日大宗交易折价成交8... 5月15日,上海汽配大宗交易成交82.3万股,成交额1204.87万元,占当日总成交额的34.5%,...
酒钢宏兴首次回购股份0.01%... 酒钢宏兴(维权)于2025年5月16日发布公告,披露了其以集中竞价交易方式首次回购公司股份的相关情况...
王府井完成1.5亿元股份回购,... 王府井集团股份有限公司于2025年5月16日发布关于股份回购实施结果暨股份变动的公告,宣告此次回购计...
美国与卡塔尔签经济军事协议   美国白宫14日发表声明说,美国与卡塔尔当天签署总价值超过2435亿美元的多项协议,包括卡塔尔从美...
廊坊市明珠商业企业集团有限公司... 转自:河工新闻网  廊坊市明珠商业企业集团有限公司工会举办第24届职工运动会  零售职工解锁“隐藏副...
海程邦达连续3个交易日收盘价格... 5月15日,海程邦达(603836)发布公告,公司股票在2025年5月13日、14日及15日连续3个...
广告字体审美引争议:天津美院院... 来源:@经济观察报微博解码艺术家 邱志杰所批评的“武士道书法”近日,天津美术学院院长邱志杰的一段视频...
从“金饭碗”到“铁饭碗”?金融... 是“金饭碗”,还是“铁饭碗”?似乎不再是个难题。近年来,考公热度持续攀升,计划招录人数虽小幅增长,但...
2025天津滨海新区龙舟争霸赛... 【2025天津滨海新区龙舟争霸赛即将激情上演!】#滨海资讯# 鼓声激荡海河潮,桨影翻飞逐浪高!为弘扬...
智选假日酒店全新发布5.0版本... 近日,洲际酒店集团旗下中高端精选服务品牌—智选假日酒店,顺应消费市场“质价比”导向与酒店投资回归理性...
退休不到五年 浙江省能源集团原... 浙江省能源集团(简称“浙能集团”)原党委书记、董事长童亚辉涉嫌严重违纪违法,主动投案,目前正接受浙江...
白河县人大:以监督之力助推高质... 近日,白河县人大常委会印发2025年监督工作计划,围绕贯彻决策部署、落实法律规定、回应民生关切,全年...
中捷精工(301072.SZ)... 格隆汇5月15日丨中捷精工(301072.SZ)于近期投资者关系活动表示,公司已与天纳克、博戈、威巴...
调研速递|山东美晨科技接受投资... 5月15日下午15:00 - 16:30,山东美晨科技(维权)股份有限公司通过全景网“投资者关系互动...
招商蛇口5月15日现1笔大宗交...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会!   5月15日,招商...
中国银河(06881.HK):... 格隆汇5月15日丨中国银河(06881.HK)发布公告,公司已于2025年5月15日完成向专业投资者...
强化行业监管 提升服务质效——... 为进一步规范基层法律服务市场秩序,提升法律服务质量,根据《基层法律服务所管理办法》相关规定,韩城市司...
上海市重大工程一季度开局良好,... 今年上海市重大工程共安排正式项目186项,计划完成投资2400亿元。其中,生态文明类15项。截至目前...
证监会:2024年查办59起从... 转自:北京商报北京商报讯(记者 马换换 王蔓蕾)5月15日,证监会发布2024年中国证监会执法情况综...