jQuery版本升级有哪些注意事项?
背景
-
jQuery一定是所有web工程师都很熟悉的,但是现在很多网站还是采用一个很老的版本的JQuery。事实上,如果早期版本使用不当,DOMXSS可能会有漏洞。强烈建议升级到jQuery 1.9.x或以上版本。前段时间我牵头做了这件事,把我们组负责的项目的jQuery版本从1.4.2升级到了jQuery 1.11.3。JQuery官方也为类似的升级工作提供了jQuery Migrate插件。
言归正传。
坑从何而来?
-
JQuery 1.11.3是1.x时代的最后一个版本(作者更新:2016 1.12.0上线,JQuery 1.11.3不再是1.x时代的最后一个版本)。在早期,jQuery的很多书写方式在新版本中已经被抛弃,或者以前版本支持一些不规则的书写方式,现在不支持了。更糟糕的是,新版本还是支持的,只是功能和以前不一样了?这种情况甚至不会报错,需要深入代码逻辑才能看出来。
jQuery官方推荐了jQuery迁移库来解决JQuery升级问题。但是,一直使用这个库不是长久之计。建议在开发中使用jQuery Migrate的开发版,可以在浏览器控制台上打印出不兼容的细节。需要注意的是,开发时必须使用jQuery Migrate的开发版,因为压缩版不会在控制台上给出警告?只需在jQuery库之后立即引用jQuery迁移库:
& ltscript src = " & lt路径& gt/& lt;to & gt/jquery-1.11.3 . js " & gt;& lt/script & gt;
& ltscript src = " & lt路径& gt/& lt;to & gt/jquery-migrate-1 . 2 . 1 . js " >& lt/script & gt;升级完成后,确认没有问题,就把jQuery迁移库去掉。根据我个人的经验,我把坑分为两类:普通坑和稀有坑。
公共坑
-
1.使用了废弃的jQuery.fn.live方法。
对于此错误,jQuery迁移库在控制台上也有相应的警告:
JQMIGRATE: jQuery.fn.live()已被否决
live方法的原始功能是设置事件代理。jQuery 1.7以后不推荐这种方法,取而代之的是jQuery.fn.on函数。它们的接口是:
$(选择器)。live('click ',function(){/*部分代码*/});
$(选择器)。on('click ',[选择器,] function(){/*某代码*/});乍一看,括号中的参数可以省略。两个功能不是一模一样吗?所以我很天真的把函数名live直接换成了on,大部分时候好像都没有引起什么异常。但是,如果在调用on函数时,前面的$(selector)与当前网页上的任何元素完全不匹配(该元素可能只在代码之后添加到DOM中),则不会绑定成功。实际上,live函数将$(选择器)委托给了document元素,这是肯定存在的,所以不会出现类似的情况。正确的替换方法应该是:
$(选择器)。live('click ',function(){/*部分代码*/});用…替换
$(文档)。on('click ',选择器,function(){/*某代码*/});2.使用废弃的jQuery.fn.die方法。
JQuery Migrate对此错误的警告是:
Jqmigrate: jquery.fn.die()已被否决。这个方法和之前的live正好相反,解除绑定事件处理程序。在新版本中,应该使用off功能代替,替换方法类似。
3.使用废弃的jQuery.fn.toggle函数。
JQuery Migrate对此错误的警告是:
Jqmigrate: jQuery.fn.toggle(处理程序,处理程序...)已弃用早期的jquery中有两个名为toggle的函数,一个是用来控制元素的显示和隐藏,目前jQuery中还存在用于此目的的函数;另一种是上面提到的废弃的toggle函数,用于将至少两个函数绑定到同一个元素上,在点击元素时交替执行这两个函数。这两个同名函数的作用相差甚远,在jQuery 1.8中不再推荐使用。另一种方法是将两个函数合并成一个函数的两个if-else部分,然后设置一个布尔变量来控制每次单击时应该执行哪个部分。
4.使用废弃的jQuery.browser属性。
JQuery Migrate对此错误的警告是:
Jq migrate: jQuery.browser在前端开发中被弃用,我们经常要根据不同的浏览器版本做出不同的处理。Jquery.browser最初通过浏览器的userAgent字段提取浏览器相关信息。在新版本中已经被抛弃,但建议使用特征检测的方法进行判断,并给出一个Modernizr库作为推荐。但是,改变这个库可能需要一点成本。如果还是想按照jQuery.browser的思路,可以自己实现。例如,要确定它是否是IE浏览器,可以使用
/msie/。test(navigator . user agent . tolowercase());
即手动获取userAgent字段,并进行正则表达式匹配。其他浏览器也有类似的想法,它们都定期匹配navigator.userAgent。
5.$ (HTML)格式中的写入错误
在jQuery Migrate中,以下三个警告中的任何一个都是错误:
JQMIGRATE: $(html) HTML字符串必须以' & lt'开头性格;角色;字母
JQMIGRATE: $(html)忽略最后一个标记后的html文本
Jqmigrate: html字符串不能以' # '字符开头是相当值得注意的,因为我们文章开头提到的jQuery低版本中的XSS漏洞实际上与这个错误有关。在javascript中,我们经常将html格式的字符串直接写入jQuery引用,比如$('
$(" & lt;p & gt& lt/p >;);//错误,字符串开头有一个空格,而不是小于号'
$(" & lt;p & gt& lt/p & gt;测试”);//不标准,html标签后面多了一个“test”,会被忽略。
$(" # & lt;p & gt& lt/p & gt;);//错误,以井号开始,后面没有css选择器,在编写时可以很容易地避免。第三个错误实际上不仅仅是一个警告。jQuery会直接抛出错误,停止javascript代码的继续执行。一般以井号开头,比如$(“# test”),其实就是一个普通的选择器,但在上面的例子中,后面是一个html字符串,会被jQuery判断为潜在的XSS攻击。
6.jquery.fn.attr方法使用错误(这是一个非常容易犯的错误!)
在jQuery Migrate中,关于attr方法的警告如下:
JQMIGRATE:jquery . fn . attr(' value ',val)不再设置属性
JQMIGRATE:jquery . fn . attr(' value ')不再获取属性
JQMIGRATE:jquery . fn . attr(' checked ')可以使用属性而不是特性
Jqmigrate: jquery.fn.attr (props,pass)已弃用。在实践中,我发现如何在早期代码中获取一个输入表单的值?$('输入')。attr('值');它是如何设置的?$('输入')。attr('值',' helloworld ').这在新版本中是不正确的!正确的做法应该是
$('输入')。val();//获取输入表单现在输入的值。
$('输入')。val(' hello world ');//设置输入表单输入的值。
是get还是set,只取决于调用val方法时是否带参数。
如果要手动设置单选按钮框(例如
$('输入')。prop('checked ',true);//将单选按钮框设置为选中状态。
$('输入')。prop(' checked ');//获取单选框是否选中,返回true或false。这是从jQuery 1.6开始使用的写法。如果设置了disabled和selected属性,也将使用prop方法。那么具体什么时候使用attr方法呢?它们之间的区别在于,prop设置元素的固有属性,而attr设置写在html标记上的自定义属性。例如:
& ltinput type = " checkbox " checked = " checked " haha = " hello " & gt;
var v1 = $('input ')。prop("已检查");//返回true/false,是否选中会随着状态的变化而变化。
var v2 = $('input ')。attr("已检查");//返回“选中”,是你在标签上设置的,不会改变。
var v3 = $('input ')。attr(“哈哈”);//返回“hello”自定义属性。
var v4 = $('input ')。道具(“哈哈”);//返回undefined,没有这样的固有属性。上面提到的第四个错误,jQuery.fn.attr (props,pass)被弃用,在真实项目中从未见过。阅读源代码后,触发此警告的jquery编写很少,可以忽略。
7.非法参数被传入$.parseJSON。
在jQuery Migrate中,此错误会生成以下警告。
JQMIGRATE: jQuery.parseJSON需要有效的JSON字符串
jQuery之所以更改这个接口,是为了和浏览器自带的JSON.parse接口看齐,从jQuery 1.9开始生效。当AJAX从服务器接收返回值时,这个问题很常见。服务器可能会返回一个空字符串,调用这个接口会产生一个错误。必须将合法的JSON字符串传递给$.parseJSON。更正方法如下:
var v1 = $。parse JSON(str);用…替换
var v1 = $。parseJSON( str?str:“null”);8.使用了放弃的“悬停”事件字符串。
在jQuery Migrate中,此错误会生成以下警告。
jq migrate:“hover”伪事件已被否决,在注册事件处理程序时使用“mouse enter mouselive”,“hover”曾被视为两个事件“mouse enter mouselive”的另一个名称。目前昵称已被删除,请在代码中用' mouseenter mouseleave '替换。
9.jQuery.fn.andSelf已被替换,不能再使用。
jQuery Migrate中的警告是:
jqmigrate: jquery.fn.andself()替换成jquery.fn.addback()的功能完全一样,可以直接替换。
以上是jQuery升级中的常见问题。当然,本着精益求精的精神,我们还是要研究不寻常的问题是什么样子的。需要指出的是,以下问题在我的实际项目中从未遇到过,比较少见,但不保证不会出现在你的项目中。仅供感兴趣的程序员参考。
尖尖坑
-
1.jQuery与浏览器的怪异模式不兼容。
触发该错误的方法非常简单,只需将
jQuery Migrate显示的错误警告如下:
2.AJAX全局事件必须绑定到文档节点。
jQuery迁移中的警告如下:
JQMIGRATE: AJAX事件应该附加到document: ajaxStart
jQuery中的Ajax全局事件包括以下接口:Ajax开始、Ajax停止、Ajax发送、Ajax完成、Ajax错误、AJAX成功。因为这些事件很少使用,所以也被归为稀有坑。从jQuery 1.9开始,这些事件只能绑定到$(document)。修正方法如下(来自jQuery官网):
$("#status ")。ajaxStart(function(){ $(this)。text(" Ajax started ");});修改为
$(文档)。Ajax start(function(){ $(" # status ")。text(" Ajax started ");});3.IE6/7/8浏览器不支持修改输入表单的类型属性。
在jQuery迁移中,警告是这样的:
Jq migrate:在IE 6/7/8中不能改变输入或按钮的“类型”。可以直接把文本框改成单选框,多选框等等。虽然我感觉这不是一个优雅的行为,但是很多浏览器都支持,除了IE6/7/8。建议在实践中还是少用这个函数比较好。
4.$的移除属性和方法。干净,美元。event.handle,$。attrfn,$。使用fn.data ('events ')和jquery.event.trigger。
在jQuery迁移中,警告是这样的:
JQMIGRATE: jQuery.clean()已被否决
JQMIGRATE: jQuery.event.handle未记录在案,已被弃用
JQMIGRATE: jQuery.attrFn已被否决
JQMIGRATE:不推荐使用jQuery.fn.data('events ')
Jq migrate:全局事件无文档,不推荐使用如果你在自己的代码中使用过这五个接口,你真的是一个仔细研究过jQuery源代码的专家。因为这五个接口从来没有在jQuery的官方文档中出现过,而且在后续版本中也删除了一部分,可以说是来去无踪。如果看源代码,有机会在早期版本找到它们,但不推荐。建议采用其他方法实现相应的功能。什么?你不知道这五个功能是什么?太好了。你现在不需要知道?
5.过时的美元。使用sub()方法。
jQuery Migrate中出现此问题的警告如下:
Jqmigrate: jquery.sub()已被否决。这个接口非常简单,不接受任何参数。它用于创建jQuery的副本。这个方法从jQuery 1.7开始就不再使用了。
6.使用过时的jQuery.fn.error方法。
jQuery Migrate中出现此问题的警告如下:
Jqmigrate: jQuery.fn.error()已被否决。在jquery中,error是与click相同的事件。注册这个事件的处理程序,以前是$(selector)。error(function(){}),已被放弃,可以用$ (selector)代替。on ('error ',function () {})。
示例代码
-
这篇文章既然自称“XX大全”,那就要尽量全面。为了理解这些坑是怎么踩进去的,我们最后写一个js代码,要求用最少的代码踩完jQuery迁移库中的所有坑。也就是让jQuery迁移库打印出它能打印的所有代码。最终代码如下(博客园没有办法上传附件,只能贴代码),非常简单易懂。打开index.html文件,然后按F12打开控制台,可以看到华丽的控制台警告_
& lt!-文件名:index.html-& gt;& lt!-& lt;!DOCTYPE html & gt-& gt;//keng0怪异模式
& lthtml & gt
& lthead & gt
& ltmeta charset = " utf-8 "/& gt;
& lttitle & gtJQuery升级践踏百科
& ltscript type = " text/JavaScript " src = "/jquery-2.1.4 . min . js " & gt;& lt/script & gt;
& ltscript type = " text/JavaScript " src = "/jquery-migrate-1 . 2 . 1 . js " & gt;& lt/script & gt;
& lt/head & gt;
& ltbody & gt
& ltp class="test" id="a " >a & lt/p & gt;
& ltinput type = " radio " id = " b " value = " b "/& gt;
& ltinput type = " radio " id = " c " value = " c "/& gt;
& ltp id="d" value="d " >测试& lt/p & gt;
& ltscript type = " text/JavaScript " & gt;
//开始踩坑
//使用丢弃的$。attrFn方法。
var keng1 = $。attr fn | | { };
//这个函数是在jQuery内部调用的,在真实项目中从未见过,可以忽略。这只是为了触发一个错误警告。
var keng2 = $。attr($("#a ")," class "," xxx ",true);
//在//IE6、IE7和IE8中不支持更改输入框的类型。
var keng3 = $(“输入#b”)。attr("type "," text ");
//在应该使用prop的地方使用了attr。
var keng4 = $(“输入#c”)。attr("已检查",真);
//使用attr获取属性值,正确的话,应该使用。val()。
定义变量