Heim > Artikel > Web-Frontend > Was ist beim Upgrade der jQuery-Version zu beachten?
Dieses Mal werde ich Ihnen zeigen, auf welche Vorsichtsmaßnahmen beim Upgrade der jQuery-Version geachtet werden sollte. Das Folgende ist ein praktischer Fall.
Hintergrund
--------------------------------------------------- --- -------------------------------- ---
jQuery Jeder Webentwickler muss damit vertraut sein, aber viele Websites verwenden heute noch die sehr alte Version von jQuery. Tatsächlich kann es bei unsachgemäßer Verwendung der früheren Versionen zu DOMXSS-Schwachstellen kommen. Es wird dringend empfohlen, ein Upgrade auf jQuery 1.9.x oder höher durchzuführen. Ich habe in dieser Angelegenheit vor einiger Zeit die Führung übernommen und die jQuery-Version des Projekts, für das unser Team im Unternehmen verantwortlich war, von 1.4.2 auf jQuery 1.11.3 aktualisiert. Für ähnliche Upgrade-Arbeiten stellt jQuery offiziell auch das Plug-in jQuery Migrate bereit.
Zurück zum Geschäft.
Woher kommt die Falle
-------------------------------- - ------------------------------------------------- -
jQuery 1.11.3 ist die letzte Version der 1.x-Ära (Update des Autors: Am 8. Januar 2016 wurde jQuery 1.12.0 gestartet, jQuery 1.11.3 ist nicht mehr die letzte Version von 1.x-Ära), da es mein Abteilungsprojekt schon eine gewisse Zeit gibt und ich damals noch jQuery 1.4.2 nutzte, ist dieses Upgrade ein relativ großer Schritt. Viele frühere jQuery-Schreibmethoden wurden in der neuen Version aufgegeben, oder es gibt einige nicht standardmäßige Schreibmethoden. Die damalige Version unterstützte sie noch, wird jedoch nicht mehr unterstützt. Was noch schlimmer ist, ist, dass die neue Version es immer noch unterstützt, aber die Funktion unterscheidet sich von der vorherigen ... In diesem Fall wird nicht einmal ein Fehler gemeldet, und Sie müssen tief in die Codelogik eintauchen, um dies zu sehen.
jQuery empfiehlt offiziell die jQuery Migrate-Bibliothek, um das jQuery-Upgrade-Problem zu lösen. Die ständige Verwendung dieser Bibliothek stellt jedoch keine langfristige Lösung dar. Während der Entwicklung wird empfohlen, die Entwicklungsversion von jQuery Migrate zu verwenden, die detaillierte Informationen zu Inkompatibilitäten auf der Browserkonsole ausdrucken kann. Es ist zu beachten, dass Sie während der Entwicklung die Entwicklungsversion von jQuery Migrate verwenden müssen, da die komprimierte Version keine Warnung in der Konsole ausgibt ... Zitieren Sie einfach die jQuery Migrate-Bibliothek direkt nach der jQuery-Bibliothek:
db99534a710f711a5502883b79acdbd1/05034471df6398a62d5708f78b78e0ac/jquery-1.11.3.js">2cacc6d41bbb37262a98f745aa00fbf0 db99534a710f711a5502883b79acdbd1/05034471df6398a62d5708f78b78e0ac/jquery-migrate-1.2.1.js">2cacc6d41bbb37262a98f745aa00fbf0
Nachdem das Upgrade abgeschlossen ist und bestätigt wurde, dass kein Problem vorliegt, entfernen Sie einfach die jQuery Migrate-Bibliothek. Basierend auf persönlichen Erfahrungen werde ich die folgenden Fallstricke in zwei Kategorien einteilen: häufige Fallstricke und seltene Fallstricke.
Häufige Fallstricke
-------------------------------------------------- ---- ---------------------------------------------- -
1. Die veraltete Methode jQuery.fn.live wird verwendet
Die jQuery Migrate-Bibliothek hat auch eine entsprechende Warnung auf der Konsole für diesen Fehler:
JQMIGRATE: jQuery fn.live() ist veraltet.
Die ursprüngliche Funktion der Live-Methode besteht darin, den Ereignis-Proxy festzulegen. Diese Methode wird nach jQuery 1.7 nicht mehr empfohlen und wird durch jQuery.fn ersetzt. auf Funktion. Ihre Schnittstellen sind:
$(selector).live('click', function(){/* some code */}); $(selector).on('click', [selector,] function(){/* some code */});
Auf den ersten Blick können die Parameter in den eckigen Klammern weggelassen werden. Sind die beiden Funktionen nicht genau gleich? Also habe ich naiverweise den Funktionsnamen „live“ durch „on“ ersetzt. Meistens schien dies keine Ausnahme zu verursachen. Wenn Sie jedoch die Funktion „on“ aufrufen, stimmt der vorherige $(Selektor) mit keinem Element auf der aktuellen Webseite überein (das Element wird möglicherweise in einem späteren Code zum DOM hinzugefügt), dann ist die Bindung nicht erfolgreich. Tatsächlich gibt die Live-Funktion $(selector) an das Dokumentelement weiter. Dieses Element existiert definitiv, sodass eine ähnliche Situation nicht auftreten wird. Die richtige Ersetzungsmethode sollte sein:
$(selector).live('click', function(){/* some code */}); 替换为 $(document).on('click', selector, function(){/* some code */});
2. Die veraltete Methode jQuery.fn.die wird verwendet
Die Warnung von jQuery Migrate für diesen Fehler lautet:
JQMIGRATE: jQuery.fn.die() is deprecated
Diese Methode ist genau das Gegenteil der vorherigen Live-Methode und hebt die Bindung der Ereignisverarbeitungsfunktion auf. In der neuen Version sollte stattdessen die Off-Funktion verwendet werden, und die Ersetzungsmethode ist ähnlich.
3. Die veraltete jQuery.fn.toggle-Funktion wird verwendet
Die Warnung von jQuery Migrate für diesen Fehler lautet:
JQMIGRATE: jQuery.fn.toggle(handler, handler...) is deprecated
Early There are Zwei Funktionen namens „toggle“ dienen in jQuery dazu, die Anzeige und das Ausblenden von Elementen zu steuern. Die andere ist die oben erwähnte Funktion „toggle“, die zum Binden verwendet wird auf das gleiche Element Beim Anklicken des Elements werden die beiden Funktionen abwechselnd ausgeführt. Die Funktionen dieser beiden gleichnamigen Funktionen sind sehr unterschiedlich. Um keine Irreführung zu verursachen, wird ihre Verwendung in jQuery 1.8 nicht mehr empfohlen. Die Ersetzungsmethode besteht darin, die beiden Funktionen in den if-else-Abschnitten einer Funktion zusammenzuführen und dann selbst eine boolesche Variable festzulegen, um zu steuern, welcher Abschnitt bei jedem Klick ausgeführt werden soll.
4. Verwendung der veralteten jQuery.browser-Eigenschaft
jQuery Migrate对此错误的警告是:
JQMIGRATE: jQuery.browser is deprecated
在前端开发中我们经常要根据不同的浏览器版本做出不同的处理,jQuery.browser本来是通过浏览器的userAgent字段来提取浏览器相关信息的。新版本中已经将其废弃,而是建议使用特征检测的方法去判断,并且给了一个Modernizr库作为推荐。不过,改成这个库可能改动成本有点大,如果你还是想沿用jQuery.browser的思路的话,可以自己去实现一下它。例如,判断是不是IE浏览器,可以用
/msie/.test(navigator.userAgent.toLowerCase());
即自己手动获取userAgent字段,并且做一个正则表达式匹配。其他浏览器思路类似,都是对navigator.userAgent做一个正则匹配。
5. $(html)格式书写错误
在jQuery Migrate中,出现以下三种警告中的任何一种,都是属于这个错误:
JQMIGRATE: $(html) HTML strings must start with '<' character JQMIGRATE: $(html) HTML text after last tag is ignored JQMIGRATE: HTML string cannot start with a '#' character
这个错误还是蛮值得注意的,因为我们文章开头所说的jQuery低版本有XSS漏洞,其实就是和这个错误有关系。在javascript中我们经常会直接将一段html格式的字符串写在jQuery引用里面,比如$('e388a4556c0f65e1904146cc1a846bee94b3e26ee717c64999d7867364b1b4a3')。按照新版本的jQuery要求,这段html格式的字符串必须是以左尖括号(小于号)开头,其他字符都不可以。以下几种写法,都是错误的:
$(" <p></p>"); //错误,字符串最开头有一个空格,不是以小于号'<'开头的 $("<p></p>test"); //不标准,html标签结束后后面还有多余的"test",它会被忽略 $("#<p></p>); //错误,以井号开头并且后面并不是一个css选择器
这一点在书写的时候注意一下就可以了,其实还是很容易避免的。其中第三种错误其实就不仅仅是警告了,jQuery会直接抛出一个错误,停止javascript代码的继续执行。一般情况以井号开头,例如$("#test"),其实就是一个普通的选择器,但是上面例子中后面又夹杂着html字符串,这会被jQuery判断为潜在的XSS攻击。
6. jQuery.fn.attr方法的错误使用(这是个非常易犯的错误!)
jQuery Migrate中,关于attr方法的警告有以下这些:
JQMIGRATE: jQuery.fn.attr('value', val) no longer sets properties JQMIGRATE: jQuery.fn.attr('value') no longer gets properties JQMIGRATE: jQuery.fn.attr('checked') may use property instead of attribute JQMIGRATE: jQuery.fn.attr( props, pass ) is deprecated
实践中我发现,早期写的代码里面,获取一个input输入表单的值时,是怎么获取的呢?$('input').attr('value');又是怎么设置的呢?$('input').attr('value', 'helloworld')。这在新版本中都是不正确的!正确的做法应该是
$('input').val(); //获取input表单现在所输入的值
$('input').val('helloworld'); //设置input表单输入的值
到底是获取还是设置,只取决于调用val方法时有没有带着参数。
如果你想手动设置单选框(例如70399a5e80bd8088d4fe7a1486dc379b)被选中,应该怎么设置呢?老的代码里面可能会看到这样 $('input').attr('checked', true)或者$('input').attr('checked', 'checked')。这些现在也都是不正确的!正确的做法应该是
$('input').prop('checked', true); //把单选框设为选中状态 $('input').prop('checked'); //获取单选框是不是被选中了,返回true或false
这是从jQuery 1.6版本开始使用的写法。如果设置disabled和selected属性,也是使用prop方法。那到底什么时候使用attr方法呢?两者的区别是:prop设置的是某元素固有的属性,而attr设置的是写在html标签上的自定义属性。举个例子:
45ec6edb2d9d76ce07367010c4d75f57 var v1 = $('input').prop("checked"); //返回true/false,是否被选中,随状态改变而改变 var v2 = $('input').attr("checked"); //返回"checked",这是你设置在标签上的,不会变 var v3 = $('input').attr("haha"); //返回"hello",自定义属性 var v4 = $('input').prop("haha"); //返回undefined,根本没有这个固有属性
上面提到的第四个错误,jQuery.fn.attr(props, pass) is deprecated这个警告在真实项目中从未见到过,看了一下源码,触发该警告的jQuery写法很少见,可忽略。
7. 向$.parseJSON传入了非法的参数
在jQuery Migrate中,该错误产生如下警告
JQMIGRATE: jQuery.parseJSON requires a valid JSON string
jQuery之所以改这个接口,是为了和浏览器自带的JSON.parse接口对齐,从jQuery 1.9开始生效。这个问题常见于AJAX接收服务端返回值的时候。服务端可能返回一个空字符串,这时候调用该接口会产生错误。必须向$.parseJSON传入合法的JSON字符串。修正方法如下:
var v1 = $.parseJSON(str); 替换为 var v1 = $.parseJSON( str ? str : "null" );
8. 使用了被废弃的'hover'事件字符串
在jQuery Migrate中该错误产生如下警告
JQMIGRATE: 'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'
在注册事件处理函数时,'hover'以前可以看作是'mouseenter mouseleave'两个事件的别称。目前已经将该别称去掉了,所以代码中请用'mouseenter mouseleave'替换之。
9. jQuery.fn.andSelf已经被替换,不能再使用
jQuery Migrate中是这样的警告:
JQMIGRATE: jQuery.fn.andSelf() replaced by jQuery.fn.addBack()
两个函数功能是完全一样的,可以直接替换。
以上,就是在jQuery升级中常见的问题,当然,本着精益求精的精神,我们还是需要研究一下不常见的问题是什么样子的。需要指出的是:下面的问题在我的实际项目中从来没有碰到过,比较少见,但也无法保证一定不会出现在你的项目中,仅供感兴趣的程序员们参考吧。
少见坑
--------------------------------------------------------------------------------
1. jQuery不兼容浏览器的怪异模式
这个错误的触发方式非常简单,直接把html页面最顶端的8b05045a5be5764f313ed5b9168a17e6标签删掉就可以了。浏览器怪异模式是为了兼容老古董网页而设计的,详情可参考这篇文章:链接。我想现在的WEB程序员应该不会傻到不写DOCTYPE,也很少使用这种模式下的浏览器吧。
jQuery Migrate展示的错误警告如下:
2. AJAX全局事件必须绑定到document节点上
jQuery Migrate中的警告如下:
JQMIGRATE: AJAX events should be attached to document: ajaxStart
jQuery中AJAX全局事件包括如下接口ajaxStart, ajaxStop, ajaxSend, ajaxComplete, ajaxError, ajaxSuccess。因为这些事件使用的比较少,所以也归在少见坑当中。从jQuery 1.9开始,这些事件只能绑定到$(document)上。改正方法如下(摘自jQuery官网):
$("#status").ajaxStart(function(){ $(this).text("Ajax started"); }); 修改为 $(document).ajaxStart(function(){ $("#status").text("Ajax started"); });
3. IE6/7/8浏览器不支持修改input表单的type属性
在jQuery Migrate中是这样的警告:
JQMIGRATE: Can't change the 'type' of an input or button in IE 6/7/8
改变input的表单的type属性,你可以直接把文本框改成单选框,改成多选框等等。虽然我感觉这是一种并不算优雅的行为,但是很多浏览器都是支持这么做的,除了IE6/7/8。建议在实际中也是少用这个功能为好。
4. 使用了被移除的$.clean, $.event.handle, $.attrFn, $.fn.data('events'), jQuery.event.trigger属性与方法
在jQuery Migrate中是这样的警告:
JQMIGRATE: jQuery.clean() is deprecated JQMIGRATE: jQuery.event.handle is undocumented and deprecated JQMIGRATE: jQuery.attrFn is deprecated JQMIGRATE: Use of jQuery.fn.data('events') is deprecated JQMIGRATE: Global events are undocumented and deprecated
如果你在自己的代码中使用过这五个接口,那确实是仔细研究过jQuery源代码的高人啊。因为这五个接口从来没有出现在jQuery的官方文档中,并且有些在后续版本中已经删除,可谓来无影去无踪。看源代码的话在早期版本有机会找到他们的存在,但是并不建议使用。建议采用其他方法实现相应的功能。什么?你不知道这五个函数是什么功能?那最好了,你现在也不需要知道了……
5. 使用了过时的$.sub()方法
jQuery Migrate中对本问题的警告如下:
JQMIGRATE: jQuery.sub() is deprecated
这个接口非常简单,不接受任何参数。它用来创建一个jQuery的副本。该方法在jQuery 1.7版本开始就已经不再使用。
6. 使用了过时的jQuery.fn.error方法
jQuery Migrate中对本问题的警告如下:
JQMIGRATE: jQuery.fn.error() is deprecated
在jQuery中,error也是和click一样的事件。注册该事件的处理函数,以前是$(selector).error(function(){}),现在已经被废弃,可以使用$(selector).on('error', function(){})来替代。
示例代码
--------------------------------------------------------------------------------
本文既然自称为“XX大全”,那就应该尽量的全面一些。为了搞明白这些坑是怎么踩进去的,我们最后来写一段js代码,要求是用最少的代码,把jQuery Migration库中所有的坑都踩一遍……也就是让jQuery Migration库打印出来它能打印的所有代码。最终的代码如下所示(博客园竟然没有办法上传附件,只能贴代码了),非常简单易懂。打开index.html文件,然后再按F12键打开控制台,你就可以看到壮观宏伟的控制台警告了^_^
2ecd5497ab3e185051c2e8f4b729bd8d6bcb2e73c7c27ed4e5f30ea75c07bd3c--> //keng0 怪异模式 100db36a723c770d327fc0aef2ce13b1 93f0f5c25f18dab9d176bd4f6de5d30e 8492913265be600fb60cbb94f9489386 b2386ffb911b14667cb8f0f91ea547a7jQuery升级踩坑大全6e916e0f7d1e588d4f442bf645aedb2f a00ff767ab7924c8175b887f7becf7dc2cacc6d41bbb37262a98f745aa00fbf0 8b813f2be3be186aca6635a59bf81c822cacc6d41bbb37262a98f745aa00fbf0 9c3bca370b5104690d9ef395f2c5f8d1 6c04bd5ca3fcae76e30b72ad730ca86d c4a6aa43c5f22940a761fb7454a53467a94b3e26ee717c64999d7867364b1b4a3 07594f6363763abb42a696b9bea48776 642974f256be81137dd77a8ac5f2805d c97f9cbde1fc09cf45a4717cb0fd699ftest94b3e26ee717c64999d7867364b1b4a3 8019067d09615e43c7904885b5246f0a //开始踩坑 //使用被废弃分$.attrFn方法 var keng1 = $.attrFn || {}; //该函数在jQuery内部调用,真实项目中从未见过,可忽略,这里只是为了触发一下错误警告 var keng2 = $.attr($("#a"), "class", "xxx", true); //IE6、7、8中不支持改变输入框的类型 var keng3 = $("input#b").attr("type", "text"); //在该使用prop的地方使用了attr var keng4 = $("input#c").attr("checked", true); //使用attr获取property的值,正确的是应该使用 .val() var keng5 = $("p#d").attr("value"); //使用attr设置property的值,正确的是应该使用 .val('somevalue') var keng6 = $("p#d").attr("value", "abcd"); //html字符串必须以'<'开头(下面这个是以空格开头) var keng7 = $(" e388a4556c0f65e1904146cc1a846bee94b3e26ee717c64999d7867364b1b4a3"); //最后一个tag后面还有多余字符串 var keng8 = $("e388a4556c0f65e1904146cc1a846bee94b3e26ee717c64999d7867364b1b4a3abc"); //html字符串不可以以井号‘#'开头 try{ var keng9 = $("#e388a4556c0f65e1904146cc1a846bee94b3e26ee717c64999d7867364b1b4a3"); }catch(e){ console.error(e); } //$.parseJSON的参数必须是合法的JSON字符串 var keng10 = $.parseJSON(undefined); //使用被废弃的$.browser var keng11 = $.browser; //使用被废弃的$.sub var keng12 = $.sub(); $("#c").on("click", function(){}); var keng13 = $("#c").data("events"); //调用了已经不再使用的函数andSelf,该函数已经被addBack替代 var keng14 = $("#c").nextAll().andSelf(); //使用被废弃的$.clean方法 try{ var keng15 = $.clean(); }catch(e){ console.error(e); } //"hover"字符串注册事件已经被拆成"mouseenter"和"mouseleave"两个 var keng16 = $("#d").on("hover", function(){/*some code*/}); //jQuery.event.handle并没有收录到官方的API中,新版本已经被移除 var keng17 = function(){ $.event.handle.apply(this, arguments); }; //全局AJAX事件处理必须绑定到document对象上 var keng18 = $("#c").ajaxStart(function(){}); //使用了被废弃的error方法 var keng19 = $("#c").error(function(){}); //使用了被废弃的toggle方法 var keng20 = $("#d").toggle(function(){/*some code*/}, function(){/*some code*/}); //使用了被废弃的live方法,应该使用on方法替代之 var keng21 = $("#a").live("click", function(){/*some code*/}); //使用了被废弃的die方法,应该使用off方法替代之 var keng22 = $("#a").die("click"); //使用了全局事件函数,目前全局事件只支持AJAX那几个,其他全局事件都不支持 var keng23 = $.event.trigger("click"); 2cacc6d41bbb37262a98f745aa00fbf0 36cc49f0c466276486e50c850b7e4956 73a6ac4ed44ffec12cee46588e518a5e
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Das obige ist der detaillierte Inhalt vonWas ist beim Upgrade der jQuery-Version zu beachten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!