Maison  >  Article  >  interface Web  >  Quelles précautions faut-il prendre lors de la mise à niveau de la version jQuery ?

Quelles précautions faut-il prendre lors de la mise à niveau de la version jQuery ?

php中世界最好的语言
php中世界最好的语言original
2018-04-23 15:48:273872parcourir

Cette fois, je vais vous apporter les Précautions auxquelles il convient de prêter attention lors de la mise à niveau de la version de jQuery. Jetons un coup d'œil à ce qui suit.

Contexte

------------------------------------- --- ----------------------------------------------- ---

jQuery Tout ingénieur web doit le connaître, mais de nombreux sites Web utilisent encore aujourd'hui la très ancienne version de jQuery. En fait, si les versions antérieures ne sont pas utilisées correctement, il peut y avoir des vulnérabilités DOMXSS. Il est fortement recommandé de passer à jQuery 1.9.x ou supérieur. Il y a quelque temps, j'ai pris les devants dans ce dossier et j'ai mis à niveau la version jQuery du projet dont notre équipe était responsable dans l'entreprise de la 1.4.2 vers la version jQuery 1.11.3. jQuery fournit également officiellement le plug-in jQuery Migrate pour des travaux de mise à niveau similaires.

Retour aux affaires.

D'où vient le piège

-------------------------------- - ------------------------------------------------- -

jQuery 1.11.3 est la dernière version de l'ère 1.x (mise à jour de l'auteur : Le 8 janvier 2016, jQuery 1.12.0 a été lancé, jQuery 1.11.3 n'est plus la dernière version de 1.x), étant donné que mon projet de département existe depuis un certain temps et utilisait encore jQuery 1.4.2 à l'époque, cette mise à niveau est une étape relativement importante. De nombreuses méthodes d'écriture jQuery au début ont été abandonnées dans la nouvelle version, ou certaines méthodes d'écriture non standard la prenaient toujours en charge, mais elles ne sont plus prises en charge. Le pire, c'est que la nouvelle version le supporte toujours, mais les fonctions ne sont plus les mêmes qu'avant... Dans ce cas, même une erreur ne sera pas signalée, et vous devez approfondir la logique du code pour voir.

jQuery recommande officiellement la bibliothèque jQuery Migrate pour résoudre le problème de mise à niveau de jQuery. Cependant, utiliser cette bibliothèque à tout moment n'est pas une solution à long terme. Lors du développement, il est recommandé d'utiliser la version de développement de jQuery Migrate, qui peut imprimer des informations détaillées sur les incompatibilités sur la console du navigateur. A noter que vous devez utiliser la version de développement de jQuery Migrate lors du développement, car la version compressée ne donnera pas d'avertissement dans la console... Citez simplement la librairie jQuery Migrate immédiatement après la librairie jQuery :

db99534a710f711a5502883b79acdbd1/05034471df6398a62d5708f78b78e0ac/jquery-1.11.3.js">2cacc6d41bbb37262a98f745aa00fbf0
db99534a710f711a5502883b79acdbd1/05034471df6398a62d5708f78b78e0ac/jquery-migrate-1.2.1.js">2cacc6d41bbb37262a98f745aa00fbf0

Une fois la mise à niveau terminée et la confirmation qu'il n'y a pas de problème, supprimez simplement la bibliothèque jQuery Migrate. Sur la base de mon expérience personnelle, je discuterai ci-dessous des pièges en deux catégories : les pièges courants et les pièges rares.

Pièges courants

------------------------------------ ---- ----------------------------------------------- -

1. La méthode obsolète jQuery.fn.live est utilisée

La bibliothèque jQuery Migrate a également un avertissement correspondant sur la console pour cette erreur :

JQMIGRATE : jQuery. fn.live() est obsolète
La fonction originale de la méthode live est de définir le proxy d'événement. Cette méthode n'est plus recommandée après jQuery 1.7, et est remplacée par jQuery.fn. sur la fonction. Leurs interfaces sont :

$(selector).live('click', function(){/* some code */});
$(selector).on('click', [selector,] function(){/* some code */});

À première vue, les paramètres entre crochets peuvent être omis. Les deux fonctions ne sont-elles pas exactement les mêmes ? J'ai donc naïvement remplacé le nom de la fonction live par on. La plupart du temps, cela ne semblait provoquer aucune exception. Mais si lorsque vous appelez la fonction on, le $(selector) précédent ne correspond à aucun élément de la page Web actuelle (l'élément peut être ajouté au DOM dans un code ultérieur), alors la liaison échouera. En fait, la fonction live proxy $(selector) vers l'élément document Cet élément existe définitivement, donc une situation similaire ne se produira pas. La méthode de remplacement correcte doit être :

$(selector).live('click', function(){/* some code */}); 替换为
$(document).on('click', selector, function(){/* some code */});

2. La méthode jQuery.fn.die obsolète est utilisée

L'avertissement de jQuery Migrate pour cette erreur est :

JQMIGRATE: jQuery.fn.die() is deprecated

Cette méthode est tout le contraire du live précédent, annulant la liaison de la fonction de traitement des événements . La fonction off doit être utilisée à la place dans la nouvelle version et la méthode de remplacement est similaire.

3. La fonction obsolète jQuery.fn.toggle est utilisée

L'avertissement de jQuery Migrate pour cette erreur est :

JQMIGRATE: jQuery.fn.toggle(handler, handler...) is deprecated

Early There are deux fonctions nommées toggle dans jQuery. L'une est utilisée pour contrôler l'affichage et le masquage des éléments. La fonction à cet effet existe toujours dans jQuery ; l'autre est la fonction toggle abandonnée mentionnée ci-dessus, qui est utilisée pour la liaison. au même élément Lorsque l'on clique sur l'élément, les deux fonctions sont exécutées alternativement. Les fonctions de ces deux fonctions du même nom sont très différentes. Afin de ne pas induire en erreur, leur utilisation n'est plus recommandée dans jQuery 1.8. La méthode de remplacement consiste à fusionner les deux fonctions dans les sections if-else d'une fonction, puis à définir vous-même une variable booléenne pour contrôler quelle section doit être exécutée à chaque fois que vous cliquez dessus.

4. Utilisation de la propriété jQuery.browser obsolète

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 &#39;<&#39; character
JQMIGRATE: $(html) HTML text after last tag is ignored
JQMIGRATE: HTML string cannot start with a &#39;#&#39; character

这个错误还是蛮值得注意的,因为我们文章开头所说的jQuery低版本有XSS漏洞,其实就是和这个错误有关系。在javascript中我们经常会直接将一段html格式的字符串写在jQuery引用里面,比如$('e388a4556c0f65e1904146cc1a846bee94b3e26ee717c64999d7867364b1b4a3')。按照新版本的jQuery要求,这段html格式的字符串必须是以左尖括号(小于号)开头,其他字符都不可以。以下几种写法,都是错误的:

$(" <p></p>"); //错误,字符串最开头有一个空格,不是以小于号&#39;<&#39;开头的
$("<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(&#39;value&#39;, val) no longer sets properties
JQMIGRATE: jQuery.fn.attr(&#39;value&#39;) no longer gets properties
JQMIGRATE: jQuery.fn.attr(&#39;checked&#39;) 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')。这些现在也都是不正确的!正确的做法应该是

$(&#39;input&#39;).prop(&#39;checked&#39;, true); //把单选框设为选中状态
$(&#39;input&#39;).prop(&#39;checked&#39;); //获取单选框是不是被选中了,返回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: &#39;hover&#39; pseudo-event is deprecated, use &#39;mouseenter mouseleave&#39;

在注册事件处理函数时,'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&#39;t change the &#39;type&#39; 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(&#39;events&#39;) 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中文网其它相关文章!

推荐阅读:

怎样使jQuery延迟执行

使用JQuery操作Ajax(附案例)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn