jQuery升级的速度越来越快,很容易如果你沉浸在项目中一段时间你就发现原来又跳了几个小版本了。
1.4以后有哪些值得关注的呢,简单整理了一下,至于是1.5, 1.6还是1.7的,我也就不特别标注了
1,attrhook和valhooks
开始错误理解了这两个钩子的作用,后来发现它不是针对特定元素绑定的,那么这应该是内核级别的,我们用的可能性小。
当然你可以在事件里判断是否特定元素,达到绑定特定元素的作用,但这样明显没多大意义了,同时,1.7中例中的程序居然不生效了,pass吧
//被修改的元素:<span id="x">Darkthread</span> //演示一个叫MyData的自定义属性勾子 //监听MyData的值,是数字文字变红,非数字就变绿 $.attrHooks.MyData = { set: function (elem, value) { if($(elem).is("#x")) $(elem).css("color",isNaN(value) ? "green" : "red"); //return value; } } setTimeout(function(){$("#x").attr("MyData", "123");}, 2000); setTimeout(function(){$("#x").attr("MyData", "ABC");}, 4000); //同样的,你可以监听别的状态如$.attrHooks.checked
2,deferred系列
这是一个相当大的改动,deferred是jquery提供的一个延迟执行的类队列对象,因为引入了这一对象,很多执行有时长的函数纷纷把返回值变成了deferred对象,比如ajax和animation.
我们先看这一系列用法:$.when().done().fail().then()
html代码:
<div>测试多个执行,最后一个完成后得到结果<br/> v1:<input type="text" value="" id="t1"/> v2:<input type="text" value="" id="t2"/> <input type="button" value="ajax" id="snd"> <br/><input type="button" id="tsend" value="submit">全部ajax请求结束后才激活此按钮 </div>
js代码
$("#snd").click(function(){ $("#tsend").attr("disabled",true);//开始前禁用按钮 var url="back.php"; $.ajaxSetup({cache:false}); var sum=0; //几个测试的ajax请求,每一个完成后把返回值相加,所有请求完成后才启用之前禁用的按钮 var a1=$.get(url,{v:$("#t1").val()},function(d){sum+=Number(d); console.log("ajax step 1, get: "+d);}); var a2=$.get(url,{v:$("#t2").val()},function(d){sum+=Number(d); console.log("ajax step 2, get: "+d);}); $.when(a1,a2).done(function(a1,a2){console.log(a1);console.log("ajax done, sum: "+sum);$("#tsend").attr("disabled",false);}) .fail(function(jXHR,errtype,errmsg){//注意fail的参数 console.log(errtype+": "+errmsg); }); });
PHP代码:
<?PHP sleep(1); if(isset($_GET["v"])){ exit($_GET["v"]); } echo "1"; ?>
结果如下,注意done方法中的参数a1,a2
另一个例子,由于号称animation也具有了deferred的属性,所以我测试过直接将动画函数用deferred对象的一些函数拼接起来,但是失败了,结果还是要像普通函数一样把它包在deferred对象里面
测试内容:一个红色方块,点击其就开始移动,然后复位。
html代码:
<div id="obj" style="background:red; 100px; height:50px; position:relative; left:0; top:0;"></div>
js代码:
$("#obj").click(function(){ var m=$(this); $.Deferred(function(d){ m.text("begin!") d.pipe(function(){return m.animate({left:'+=500px'},1000);})//用的是pipe方法拼接 .pipe(function(){return m.animate({left:'-=500px'},1000);}) .done(function(){m.text("done!");}); }).resolve(); });
上例中可以看到,引入了Deferred对象后,做链式动画稍稍方便了那么一些,不再要一层一层地套到每个动画的callback里面去。
例中的用法是new一个新的Deferred对象,参数就是需要执行的方法,该方法的第一个参数就是new出来的对象本身。
当然deferred的深入用法建议放狗搜索专门讨论的文章。
3,$.map()开始支持“对象”而不仅仅是数组,如json对象
var s={"a":234,"b":"9e8fjd",c:{"aa":23948,"bb":2394}}; $.map(s,function(value,name){console.log(name+": "+value);});
4,prop和attr的插曲
1.5中有个改动,将selected, checked等属性的attr方法取得的值不再返成布尔类型,而是原生的字符串(为了与原生html保持一致),同时为了编程方便,提供了prop方法来取得布尔值,这本无可厚非,但关键在于无数基于1.5版以前的项目,涉及到此处变动的地方相当相当之多,因为引起了强烈的反弹,结果在1.6中,就采用了折衷的方案:
取值,1.5版的做法会失效,但是设置的时候,则两种兼容,示例
alert($("#a").attr("checked"));//undefined alert($("#a").prop("checked"));//true/false //1.6版下面两句均作用 $("#a").attr("checked",true); $("#a").prop("checked",false);
5,delegate进一步进化
1.4中推出的delegate据说比live更有效率,实测(比如绑上几万个元素)可以得到证明,因此会将下例中的写法A改为写法B:
$("#t td").live("click",handler);//A $("#t").delegate("td","click",handler);//B //只是应用的时候相信大家会得有点别扭,因为第一个参数传事件名可能更符合使用习惯,因此在1.7中又新出一个新的api on/off,分别对应事件的绑定和解绑,功能上等同于delegate,只是参数风格上与普通的live靠近了,于是B写法在1.7中可以写成下面的C写法: $("#t").on("click","td",handler);//C