jQuery 升級到 1.7 之後發生的問題以及解決方法記錄
在把 jQuery 1.3 (1.4以前)升級到 jQuery 1.7 之後發現原本正常運作的效果出現許多異常,不是沒反應就是反應變慢,於是展開漫長的除錯大作戰,為了避免以後忘記,還是記錄下來比較好。
網路上寫 jquery 各版本差異的文章很多,這裡就不重複,直接用出錯狀況來記錄。
網路上寫 jquery 各版本差異的文章很多,這裡就不重複,直接用出錯狀況來記錄。
- 狀況:原先透過 AJAX 取得伺服器回傳資料來顯示,在升級後不能顯示或動作。
- 偵查:用 firebug 偵查不會出現錯誤訊息,捕捉回傳訊息時會在 .error 顯示 「Invalid JSON」。
- 問題: jquery 在 1.3 以前是用 javascript 的 eval 來解析 json 資料,而在 1.4 以後(包含 jquery 1.5 、 1.6、1.7)都改用更嚴格的方式來解析。
- 解決:回傳的資料無論是鍵 key 或值 value 都必須用雙引號「"」呈現(單引號 ' 不行) --- 但數字除外。
舉例來說:
原本回傳
{ name:"王小明", year:20}
在 1.3.x 以前是可以解析的。
但在 jquery 1.4 以後就要寫成
{"name":"王小明", "year":20}
- 狀況:某些物件 bind() 、 unbind() 效果失效。
- 偵查:在瀏覽器開發工具中不會顯示錯誤訊息。
- 問題:有幾個物件透過 bind() 不同效果,例如
<div id="123">點這裡會有效果</div>
$('#123').bind('click',function(){alert('Hello');});
$('#123').bind('mouseover',function(){ $(this).css('color','red');});
$('#123').bind('click',function(){ $('#other1').hide();});
$('#other1').cilick(function(){
$('#123').unbind().bind('click',function(){ $('#other2').hide();});
});
希望出現點擊 #123 時會出現兩個效果--跳出提示、把另一個物件隱藏。
而點擊 #other1 時會把 #123 最後 bind 的 #other1.hide() 效果移除,換上 bind #other2.hide();
在 jquery 1.3.2 中用 unbind 似乎只會移除最後 bind() 效果,不過因為在此案中其它的 click 效果有用其它 jquery 封裝所以這點需要確定,總之原先是正常 unbind 最後加的效果,但不影響其它 mousehove 、click 。
換成 jquery 1.7 後,採用 $('#123').unbind() 會把 $('#123') 上所有 bind() 效果一起移除。
- 解決:
- 方案一:
var way1= function(){ $('#other1').hide(); }
$('#123').bind('click',way1);
$('#123').unbind(way1);
這樣就不會影響其它 bind 效果。 - 方案二:
如果 function 需要代變數又希望用直覺方式編碼,方案一就不怎麼合用,這時候可以用事件命名空間來 bind。
$('#123').bind('click.myEvent',function(){$('#other1').hide();});
$('#123').unbind('click.myEvent').bind('click.myEvent',function(){$('#other2').hide();}); //先移除原先效果再附上其它效果
這樣 unbind 時就不會影響其它點擊效果。
如果要移除所有自定點擊效果可以這樣寫:.unbind('.myEvent');
附帶一提, jquery 1.7 建議改採 .on .off 來取代 .bind() .unbind()。 - 方案一:
- 狀況:改為 jquery 1.7 之後,檢查 checked、selected 效果失效
- 偵查:瀏覽器無提示錯誤。
- 問題:checkedbox 用 if($(':checkbox').attr('checked')){alert('已選取');}
在 jquery 1.6 以後改為
attr('checked') 只能檢查元件在載入頁面時的值,之後要動態變動或取得變動後的狀態,要用 prop("checked")才可以。 - 解決:改為
if( $(':checkbox').prop('checked') ){ alert('已選取'); $(this).prop('checked',false); }
問題解決!
- 狀況:原本可以用 .css('background-color':'none') 或 .css('background-color':'') 把背景色去除掉。現在不行!
- 解決:改用繼承父元素即可。
.css('background-color':'inherit')
完成!
- 解決:改用繼承父元素即可。
- a