1. 程式人生 > >jQuery1.9+ 廢棄的函式和方法 升級Jquery版本遇到的問題

jQuery1.9+ 廢棄的函式和方法 升級Jquery版本遇到的問題

面臨問題

很久沒關注JQuery了,今天突然想升級一下系統中使用的版本,突然發現,升級JQuery版本到1.9之後出現了很多問題,比如:$.browser is undefined。突然就想到難不成升級刪除了這個屬性?記得以前有個版本中JQuery已經不建議使用該屬性來判斷瀏覽器了。

查了一下Google發現jQuery升級1.9還真是去掉和廢棄了不少的東西,升級系統就有了很大的難度,以前用過一些比較老的外掛咋辦,只能自己一個個修改了。

jQuery1.9中改變的地方

Jquery1.9中改變了很多東西,具體的升級可以參考一下官方的升級指南

.toggle(function, function, … ) 方法刪除

這個方法繫結兩個或多個處理程式到匹配的元素,用來執行交替的點選事件。它不應該被混同於顯示或隱藏匹配元素.toggle( )方法,因為它沒有過時。前者被刪除,以減少混亂和提高模組化程度。jQuery Migrate(遷移)外掛可以恢復此功能。

jQuery.browser() 方法刪除

jQuery.browser()方法從jQuery 1.3開始已經過時了,在1.9中被刪除。 如果需要的話,jQuery Migrate(遷移)外掛可以恢復此功能。我們建議如特徵檢測,請使用Modernizr庫

.live() 方法移除

.live()方法從jQuery 1.7開始已經過時了,在1.9中被刪除。 我們建議使用.on()方法來替換升級你的程式碼。要完全匹配$(“a.foo”).live(“click”, fn),例如,你可以寫$(document).on(“click”, “a.foo”, fn)(譯者注:因為原來的live事件其實是繫結在文件document上的)。有關詳細資訊,請參閱

.on()文件。在此期間,你可以使用jQuery Migrate(遷移)外掛來恢復.live() 功能。

.die() 方法移除

.die()方法從jQuery 1.7開始已經過時了,在1.9中被刪除。 我們建議使用. off()方法來替換升級你的程式碼。要完全匹配$(“a.foo”).die(“click”),例如,你可以寫$(document).off(“click”, “a.foo”)。有關詳細資訊,請參閱.off()文件。在此期間,你可以使用jQuery Migrate(遷移)外掛來恢復. die() 功能。

jQuery.sub() 方法移除

jQuery.sub()方法被移到jQuery Migrate(遷移)外掛中。使用的頻率證明它沒有必要再保留在核心程式碼庫中,jQuery Migrate(遷移)外掛添加了此功能。

.add() 方法修改

.add()方法返回的結果總是按照節點在document(文件)中的順序排列。在1.9之前,如果上下文或輸入的集合中任何一個以脫離文件的節點(未在文件中)開始,使用.add()方法節點不會按照document(文件)中的順序排序。現在,返回的節點按照文件中的順序排序,並且脫離文件的節點被放置在集合的末尾。

.addBack(selector) 替換 .andSelf()

從jQuery1.8開始,.andSelf()方法已經被標註過時,在jQuery1.8和更高版本中應使用.addBack()。

我們認為對於“新增並返回”以前的結果集合這是一個更好的名字。新方法可以接受一個可選的選擇器,該選擇器可以用來過濾之前集合,將它新增到當前集合並返回。$(“section, aside”).children(“ul”).addBack(“aside”) 會根據他們在文件中的順序,得到section與aside下所有ul子元素,外加所有aside元素。雖然.addSelf()在1.9中仍然可以使用,我們建議您儘快修改名稱。如果使用.addSelf(),jQuery Migrate外掛會提出警告。

.after(), .before(), 和 .replaceWith()使用脫離文件的節點

1.9以前,.after(), .before(), 和 .replaceWith()將嘗試在當前的jQuery集合中新增或改變節點,如果在當前的jQuery集的節點未連線到文件(注:即脫離文件的節點),在這種情況下,返回一個新的jQuery集合,而不是原來的那個集合。這將產生一些前後矛盾和徹底的錯誤 – 該方法可能會,也可能不會返回一個新的結果,這取決於它的引數!從1.9開始,這些方法總是返回原始未修改集並且試圖在一個沒有父節點的節點上使用.after(), .before(), or .replaceWith() 有沒有任何效果 – 即這個集或它包含的節點兩者都不被改變。

.appendTo, .insertBefore, .insertAfter, 和 .replaceAll

在1.9中,這些方法總是返回一個新的集合,使他們可以使用的鏈式呼叫和.end()方法。1.9之前,只有當他們是一個單獨的目標元素時,他們將返回舊的集合。需要注意的是這些方法總是返回所有元素附加到目標元素的聚合集合。如果沒有元素被目標選擇器選中(例如,$(elements).appendTo(“#not_found”))那麼返回的集合是空的。

AJAX 事件需要繫結到document

在jQuery 1.9中, 全域性的AJAX事件(ajaxStart, ajaxStop, ajaxSend, ajaxComplete, ajaxError, and ajaxSuccess) 只能在document元素上觸發。修改AJAX事件監聽程式到document元素上。例如,如果目前的程式碼看起來像這樣:

1 $(“#status”).ajaxStart(function(){ $(this).text(“Ajax started”); });

修改成:

1 $(document).ajaxStart(function(){ $(“#status”).text(“Ajax started”); });

.trigger() “click” 事件時Checkbox/radio 的狀態

當用戶點選一個複選框或單選按鈕時,如果節點上沒呼叫event.preventDefault(),事件處理程式中會根據複選框或單選按的當前狀態判斷並且得到它的新狀態。因此,例如,如果使用者點選一個未選中的checkbox,事件處理程式將選中(checked)這個checkbox。1.9之前,.trigger(“click”) 或 .click()任何一個將觸發一個合成事件,根據使用者點選行為,我們可以看到checkbox與實際checked屬性相反的狀態。在1.9中修復了這個bug,使用者行為會得到相應的狀態。

focus事件觸發順序

當用戶再表單元素上點選或者按tab鍵,使元素獲取焦點,瀏覽器首先在焦點元素上觸發一個blur(失去焦點)事件,然後在新元素上觸發一個focus(獲取焦點)事件。在1.9之前,使用.trigger(“focus”) 或 .focus() 繫結一個focus事件,新元素將觸發一個focus事件,然後觸發先前焦點元素的blur事件,1.9已修正此問題。

如果目標元素沒有獲取焦點並且可以成功的獲取焦點(譯者注:比如disabled被禁用的表單元素獲取不到焦點),那麼使用DOM原生的focus事件,瀏覽器只訪問focus事件處理程式。jQuery總是呼叫.trigger(“focus”) 或 .focus()繫結的處理程式,無論元素是否獲取焦點。在jQuery 1.9中還是這樣處理的。和DOM的.focus()方法不同之處在於,在許多情況下,元素已經獲取焦點或者元素被禁用,DOM的.focus()方法不會呼叫事件處理程式。

不幸的是,所有版本的Internet Explorer(6-10)觸發焦點事件是非同步的。當你在IE中使用.trigger(“focus”),jQuery無法“預知”非同步focus事件以後會發生什麼。所以它總是會觸發一個自己的focus事件,以確保功能正常。這可能會造成focus事件重覆執行,建議改用DOM內建的focus()較單純,例如: $(“#boo”).get(0).focus()。

jQuery(htmlString)與jQuery(selectorString)

在1.9以前,如果一個字串中有任何HTML標籤,那麼這個字串將被認為是一個HTML字串。這有可能造成意外的程式碼執行和拒絕有效的選擇器字串。 1.9開始,以一個小於號(“<”)字元開頭的字串才被認為是HTML字串。Migrate(延遲)外掛可以恢復到1.9以前的行為。

如果一個字串被認為是HTML,但可能會以不是一個HTML標籤的任意文字開始,將它傳遞給jQuery.parseHTML()將返回一個DOM節點陣列表示的標記。我們可以通過它來建立一個jQuery集合,例如:$($.parseHTML(htmlString))。例如,在處理HTML模板方面這被認為是最佳實踐。簡單使用文字字串,如$(“<p>Testing</p>”).appendTo(“body”)不會受此影響。

總之:HTML字串傳遞給jQuery(),除了以一個小於號(“<”)字元開始以外的其他字串都將被解釋為一個選擇器。因為字串通常不能被解釋為一個選擇器,最有可能的結果是Sizzle選擇器引擎錯誤丟擲的“無效的選擇器語法”。使用jQuery.parseHTML()來解析任意的HTML。

使用jQuery Migrate(遷移)外掛,如果該字串傳遞給$(),“看起來像HTML”,它會使用舊的規則來確定。

.data()中名稱包含點(“.”)改變

.data()有一個未公開並且令人難以置信的非高效能監控值的設定和獲取,1.9中被移除。這已經影響到了包含點的資料名稱的解析。從1.9開始,呼叫 .data(“abc.def”)只能通過名稱為“abc.def”檢索資料,原本還可以通過“abc”取得的技巧已被取消。需要注意的是較低級別的jQuery.data()方法不支援事件,所以它並沒有改變。即使使用jQuery Migrate(遷移)外掛也恢復不到原來的行為。

脫離文件節點在jQuery集合中的順序

對於許多版本,幾乎所有的jQuery的方法,返回一組新的節點集合,這個集合是一個使用他們在文件中順序排序的結果集。(有幾個方法,如.parents()返回的結果是他們在文件反向順序排序,但在1.9中這些例外情況已經記錄並沒有改變。)

在1.9之前,若jQuery集合中混雜DOM的節點及未放進DOM的脫離文件節點,則可能出現不可預期的隨機排序。從1.9開始,在文件中的連線節點都總是按文件順序放置在集合的開頭,脫離文件節點被放置在他們的後面。即使使用jQuery Migrate(遷移)外掛也恢復不到原來的行為。

載入並且執行HTML內容中的scripts

在1.9之前,任何接受HTML字串的方法(例如,$()、.append()、.wrap())會執行HTML字串中所包含的Script,並且將它們從文件中移除,以防止他們再次被執行。在特殊情況下,使用這些方法一個指令碼可能會被移除並重新插入到文件中,比如.wrap()。從1.9開始,插入到文件的指令碼會執行,但仍然保留在文件中並且標記為已經被執行過的,這樣它們就不會被再次執行,即使它們被刪除並重新插入。

儘管這種變化,在HTML標記中混合可執行的JavaScript是非常不好的習慣;它對設計,安全性,可靠性和效能有影響。例如,外部指令碼標籤包含在HTML中同步地取出,然後評估執行,這可能需要大量的時間。沒有任何介面通知這些指令碼何時何地載入,或者當有錯誤產生的時候獲得糾正提示。

試圖通過克隆一個現有的指令碼標籤載入和注入指令碼,克隆到文件將不再起作用,因為克隆的指令碼標記已經被標記為已執行。要載入一個新的指令碼,建議使用jQuery.getScript()代替。

.attr() 和 .prop()對比

jQuery 1.6 介紹了.prop()方法設定或獲取節點上的物件屬性(property),並且不建議使用.attr()方法設定物件屬性(property)。然而版本一直到1.9,在某些特殊情況下繼續支援使用.attr()方法。當選擇器是用來區分標籤屬性(attributes)和物件屬性(properties)時,這種行為在向後相容的命名方面會引起混亂。

例如,一個複選框的布林標籤屬性(attributes),如checked和disabled受到這種變化的影響。”input[checked]“的正確行為是選擇有checked屬性的複選框,不管是它的字串值,還是它當前的狀態。與此相反, “input:checked” 選擇當前checked屬性的布林值(true或false)為true的複選框,例如當用戶單擊複選框時,會受到影響。1.9之前版本這些選擇器有時不選擇正確的節點。

這裡有一些例子,當在複選框上設定一個checked屬性時正確的和不正確的使用方法;同樣的規則也適用於disabled屬性。請注意只有物件屬性(property)在所有的瀏覽器始終反映和更新的複選框的當前狀態;你很少會需要設定的屬性(attribute)。

1 2 3 4 5 6 7 8 // Correct if changing the attribute is desired $(elem).attr("checked", "checked"); // Correct for checking the checkbox $(elem).prop("checked", true); // Correct if removing the attribute is desired $(elem).removeAttr("checked"); // Correct for clearing the checkbox $(elem).prop("checked", false);

老IE中的$(“input”).attr(“type”, newValue)

在1.9版之前, 在所有的瀏覽器中,任何企圖設定一個input或者button元素的型別(type屬性),jQuery都將丟擲一個異常。這樣做時為了符合最低標準的相容;因為如果你試圖改變input元素的型別,IE6/7/8丟擲一個錯誤。從 jQuery 1.9開始,如果瀏覽器允許的話,我們允許您設定元素的型別。但是,你需要知道自己的程式碼,在老IE(IE6/7/8)下試圖做到這一點還是會丟擲一個錯誤。當你試圖設定型別屬性時,jQuery Migrate(遷移)外掛會發出警告,但不會丟擲一個JavaScript錯誤。

那麼什麼時候使用attr什麼時候使用prop:

1.新增屬性名稱該屬性就會生效應該使用prop();
2.是有true,false兩個屬性使用prop();
3.其他則使用attr();

以下是官方建議attr(),prop()的使用:

Attribute/Property .attr() .prop()
accesskey
align
async
autofocus
checked
class
contenteditable
draggable
href
id
label
location ( i.e. window.location )
multiple
readOnly
rel
selected
src
tabindex
title
type
width ( if needed over .width() )

“hover”偽事件

從1.9開始,事件名稱字串“hover”不再支援為“mouseenter mouseleave”的代名詞縮寫。允許應用程式繫結和觸發自定義的”hover”事件。修改現有的程式碼是一個簡單的查詢/替換,並且jQuery Migrate(延遲)外掛可以恢復”hover”偽事件。

jQuery物件上的.selector屬性

jQuery物件上過時的selector屬性保留的目的是為了支援過時的.live()事件。在1.9中,jQuery不再試圖在鏈方法上保留這個屬性,因為1.9已經移除了.live()事件。不要使用jQuery物件的.selector屬性。jQuery Migrate(遷移)外掛也沒支援這個屬性。

jQuery.attr()

1.9版移除了jQuery.attr(elem, name, value, pass)方法,用jQuery Migrate(遷移)外掛可恢復這個方法。

jQuery.ajax返回一個空字串的JSON結果

1.9之前,一個AJAX呼叫預期返回JSON或JSONP的資料型別,當返回值是一個空字串時會被認為是成功的狀態,但返回一個null給success處理程式或承諾(promise)。從1.9開始,JSON資料返回一個空字串被認為是畸形的JSON(因為它本來就是);這將丟擲一個錯誤。這種情況下,使用error(錯誤)處理程式捕獲。

jQuery.proxy()

1.9版前,$.proxy(null, fn)、$.proxy(undefined, fn)的this會指向window,而$.proxy(false, fn)的this則指向new Boolean(false) ;1.9起若context傳入null/undefined/false,函式的this會維持原先context,不被改變。

.data(“events”)

1.9以前,如果沒有其他的程式碼定義一個名稱為“events”的資料元素,.data(“events”) 可以用來檢索一個元素上,jQuery未公開的內部事件資料結構。這種特殊的情況,在1.9中已被刪除。沒有公共的介面來獲取這個內部資料結構,

它是不公開的。jQuery Migrate(遷移)外掛可以恢復原來的行為。

移除Event物件的部分屬性

Event物件的attrChange、attrName、realtedNote和srcElement屬性自1.7版因無法跨瀏覽器已被宣告過時;從jQuery 1.9開始,它們不再被複制到Event物件傳遞給事件處理程式。在jQuery所有版本中,這些屬性依然可以在支援他們的瀏覽器上通過event.orginalEvent存取,以取代event。jQuery Migrate(遷移)外掛在Event物件有加回了這些屬性。

API方法未公開的引數

1.9之前,幾個API方法未公開改變了他們的行為的引數,並存在潛在的意外誤用。這些引數已經被刪除。受影響的方法包括jQuery.data(),jQuery.removeData(),和jQuery.attr()。jQuery Migrate(遷移)外掛也不支援的程式碼。

其他未公開的屬性和方法

下面的內部屬性和方法從未被收入到文件,並已在1.9中刪除。

  • jQuery.deletedIds

  • jQuery.uuid

  • jQuery.attrFn

  • jQuery.clean()

  • jQuery.event.handle()

  • jQuery.offset.bodyOffset()

遷移外掛

現有的網站和外掛可能會受到這些變化的影響,所以提供一個過渡性的升級路徑—— jQuery Migrate(遷移)外掛。下面的說明中,在1.9中變化或刪除的API,大部分可以使用jQuery Migrate(遷移)外掛恢復。請注意,jQuery 1.9中所有的變化也將應用到jQuery 2.0中,jQuery Migrate(遷移)外掛在jQuery2.0中也是可用的。

未壓縮,開發版本的jQuery Migrate(遷移)外掛使用時會在控制檯中顯示警告資訊,詳細的指出不相容或刪除等資訊及解決方法。這使得它在現有的jQuery程式碼和外掛上查詢和修復問題時非常有用。jQuery Migrate(遷移)外掛包含了1.6.4以來存在但1.9已不支援所有API。

壓縮版本的的jQuery Migrate(遷移)外掛,不會在瀏覽器控制檯中產生任何不相容或刪除等資訊,並且可以在jQuery 1.9或更高版本,或者舊的不相容的jQuery程式碼或外掛中使用。

理想情況下,這將只能作為一個短期的解決方案,但是這要你自己做出決定。

長痛不如短痛啊,有時間就改一下,可憐了那一堆外掛。。。