很多人還沒開始玩jQuery 1.5,jQuery又再推進到1.6版囉! 依照慣例,還是要對1.6版的特性做個概略了解,所以jQuery 1.6筆記來了!

對於已使用jQuery的開發人員,最需要關注的莫過於更換新版對現有程式的衝擊,所以我看出版公告(Release Note)的焦點都會從Breaking Changes(不再向前相容的部分)開始:

【Breaking Changes】

  1. .data()在取回HTML5 data-boo-foo屬性時,1.5版會傳回{ boo-foo: “…” },1.6則改依HTML5規範傳回{ booFoo: “…” }。如下例,在1.5會得到{ “the-value”: “aa” },1.6則是{ "theValue”: “aa” }
    <span id="x" data-the-value="aa"></span>
    <script type="text/javascript">
        $(function () {
            alert(JSON.stringify($("#x").data()));
        });
    </script>
  2. 明確區分.prop()與.attr()。 DOM的getAttribute("...")只會取回透過HTML標籤(<element attrName=”attrValue”… />設定的值,而它與透過element.prop設定的值有所區別;而在jQuery 1.5之前,當沒有設定<element attrName=”…” />時,.attr(“attrName”)會傳回element.attrName屬性值。如以下範例: 以jQuery 1.6執行會得到空字串(若完全未指定Attribute會傳回null)、true、空字串(未指定時傳回undefined)、true,而1.5則會得到空字串、true、true(沒有.prop())。
    <input type="checkbox" id="x" checked />
    <script type="text/javascript">
        $(function () {
            alert(document.getElementById("x").getAttribute("checked"));
            alert(document.getElementById("x").checked);
            alert($("#x").attr("checked"));
            alert($("#x").prop("checked"));
        });
    </script>
    印象中過去程式有時會依賴.attr("checked")取值,預估此一修正影響頗大,值得留意。
    [2011-05-13更新]jQuery 1.6.1已調整此一Break Change,維持與jQuery 1.5.2版本前的相容

【效能提升】

如同往例,每回改版都會有些效能上的提升,1.6發行公告中特別提及了attr(), val(), .data()等函數的效能改善,由列出的比較圖表來看,webkit幫(Chrome, Safari)的表現較為出色。

【功能強化】

  1. .attr()及.val()可以加掛事件,介入設定及讀取值的時點。在下例中,在設定.attr(“MyData”, “…”)加入事件,判斷設定值為數字呈現綠色(由於需return值回去,故也可從中更動Attribute值),非數字時呈現紅色,故可看到<span>在2秒時變綠、4秒時變紅:
    <span id="x">Darkthread</span>
    <script type="text/javascript">
        $(function () {
            jQuery.attrHooks.MyData = {
                set: function (elem, value) {
                    $(elem).css("color",
                        isNaN(value) ? "red" : "green");
                    return value;
                }
            }
            setTimeout(function () {
                $("#x").attr("MyData", "123");
            }, 2000);
            setTimeout(function () {
                $("#x").attr("MyData", "ABC");
            }, 4000);
        });
    </script>
    PS: valHoosk的用法相似,可掛set, get事件,並可指定掛在不同的<input type="..">上,如: jQuery.valHooks.button, jQuery.valHooks.radio, jQuery.valHooks.checkbox ,不過依我看Source Code的心得,在jQuery核心針對valHooks已有預設事件,改寫可能會影響原有機制,要留意副作用。
  2. jQuery.map(object)可以針對物件的屬性逐一讀出處理並轉成陣列,例如:
    <script type="text/javascript">
        $(function () {
            var stock = { pc: 100, phone: 200 };
            stock = $.map(stock, function (value) {
                return parseInt(value) / 10;
            });
            alert(JSON.stringify(stock));
        });
    </script>
    得到結果為"[10,20]" (PS: 官方公告裡舉的例子return value++;我覺得怪怪的,感覺用++value或value+1較有意義)
  3. 仿效.animate(),1.6起.css()也支援+=, –=的寫法了。例如: $("#myDiv”).css(“width”, “+=10px”);
  4. 新增deferred.always(),可簡化成功或失敗都需呼叫同一callback的寫法: 原本deferred.then(callback, callback) 可直接寫成 deferred.always(callback)。
  5. 新增deferred.pipe(),大幅簡化串接非同步作業時的程式寫法。 參照在1.5筆記中的deferred範例,我改寫了一個用pipe()串接三個$.get()的測試,一樣得到正確的結果。
                function test4() {
                    //Deferred
                    dispLog("Test4");
                    var dv1 = null, dv2 = null, dv3 = null;
                    var ajax = $.get(url, {}, function (resp) {
                        dv1 = parseInt(resp);
                        dispLog("dv1=" + dv1);
                    }).pipe(function () { //利用jQuery 1.6 pipe串接
                        return $.get(url, {}, function (resp) {
                            dv2 = parseInt(resp);
                            dispLog("dv2=" + dv2);
                        });
                    }).pipe(function () {
                        return $.get(url, {}, function (resp) {
                            dv3 = parseInt(resp);
                            dispLog("dv3=" + dv3);
                        });
                    });
                    ajax.done(function () { //串接的三個$.get會完成才會呼叫done
                        dispLog("dv1+dv2+dv3=" + (dv1 + dv2 + dv3));
                    })
                    .fail(function () { //ajax1或ajax2任一者失敗時執行fail
                    });
                }
  6. 改善元素同時播放多種動畫效果時各動畫的同步性,透過requestAnimationFrame(針對FF, Safari, Chrome)提升動畫效果的流暢度。
  7. 效法$.ajax(),$.animate()也開始提供deferred物件,要處理多個動畫效果間的串接連動更加方便。
  8. 提供jQuery.holdReady(true); … jQuery.holdReady(false);可暫停及繼續ready事件,主要用於Plugin開發。
  9. :focus選擇器現在已可跨瀏覽器正確運作。
  10. 過去.find(), .closest(), .is()都只能傳入選擇器(Selector)字串,jQuery 1.6可支援傳入DOM元素或jQuery物件。(以下程式用jQuery-1.5.2第一個alert會得到0,closest部分則會出錯;而在jQuery-1.6下可得到兩個1。)
    <div class="out" id='y'><span class="in" id='x'></span></div>
    <script type="text/javascript">
        $(function () {
            var spn = document.getElementById('x');
            alert($("#y").find(spn).length);
            alert($("#x").closest($("#y")).length);
        });
    </script>

Comments

# by qq0526

昨天才剛寫完一堆.attr("checked"),今天又要改了(掩面)~

# by losewin

<input type="text" id="AAAA"> <input type="text" id="XXXX"> <input type="text" class="BBBB"> <input type="text" class="YYYY"> <input type="text" class="CCCC"> <input type="text" class="ZZZZ"> script type="text/javascript"> $(function () { alert(typeof($("#AAAA").attr("class"))); alert(typeof($("#AAAA").prop("class"))); alert(typeof($(".BBBB").attr("id"))); alert(typeof($(".BBBB").prop("id"))); alert(typeof($(".CCCC").attr("name"))); alert(typeof($(".CCCC").prop("name"))); $("#AAAA").prop("class","AAAA"); $("#XXXX").attr("class","XXXX"); $(".BBBB").prop("id","BBBB"); $(".YYYY").attr("id","YYYY"); $(".CCCC").prop("name","CCCC"); $(".ZZZZ").attr("name","ZZZZ"); alert($(".AAAA").size()); alert($("input[class=AAAA]").size()); alert($("input[class=AAAA]").attr("class")); alert($(".XXXX").size()); alert($("input[class=XXXX]").size()); alert($("input[class=XXXX]").prop("class")); alert($("#BBBB").size()); alert($("input[id=BBBB]").size()); alert($("input[id=BBBB]").attr("id")); alert($("#YYYY").size()); alert($("input[id=YYYY]").size()); alert($("input[id=YYYY]").prop("id")); // alert($("input[name=CCCC]").size()); alert($("input[name=CCCC]").attr("name")); // alert($("input[name=ZZZZ]").size()); alert($("input[name=ZZZZ]").prop("name")); }); </script> 語法蜜糖沒了 不同瀏覽器結果不同 麻煩大了

# by jocosn

謝謝這個按照慣例的筆記,這個慣例真好。大大對其它 javascript framework 有沒有類似的關注? 下面的 recapacha 加了超黑陰影後好難辨識,e 和 o 和 c 時常搞混。

# by mike

感謝大大的筆記,有這個按照慣例的筆記真好,能夠對改版有更方便的認識

# by losewin

麻煩不大了 1.6.1版 http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/

Post a comment