返回列表 發帖

jQuery 教學 - delegate 事件委派 (v1.4.2 以上適用)

這次要跟大家介紹的是 jQuery 1.4.2 新增的 delegate (事件委派),適合用在一次要綁定大量元素的事件時,可以減少記憶體的耗費並提昇綁定的效率。

[範例1]


首先請用滑鼠在以下方格上移動,看看這樣的效果:

上面的方格是一個大的 table,裡面每個 td 都被綁定了 hover 的事件,當滑鼠移過去時先漸漸增加透明度至 25%,之後再逐漸恢復。

如果是你會怎麼來處理呢?這樣嗎:
//方法 1
...
<td onmouseover="dosomething();"></td>
<td onmouseover="dosomething();"></td>
<td onmouseover="dosomething();"></td>
...
上面的方式當然是遜斃了,熟悉 jQuery 的人至少會用批次的方式來處理,像是:
//方法 2:找 #mytable 底下所有的 td,全部綁定 hover 事件
$("#mytable td").hover(function () {
    $(this).animate({opacity: 0.25}, 300, function () {
        $(this).animate({opacity: 1}, 300);
    });
});
方法 2 當然比方法 1 高明了一點,至少 code 維持了 jQuery 的風格,相當精簡。但是這樣的做法是讓每一個 td 都綁定了一個事件,缺點有兩個:

  • 綁定時,jQuery 會 loop 去處理,越多的元素要綁定時,會 loop 越多次,越花時間
  • 越多的元素綁定會越浪費記憶體


基於以上的原因,推薦你改用 delegate,綁定速度快,省記憶體,寫法只要稍稍改變一下,請看:
//方法 3:針對 #mytable 綁定 hover 事件,但是只對底下的 td 有效
$("#mytable").delegate("td", "hover", function () {
    $(this).animate({opacity: 0.25}, 300, function () {
        $(this).animate({opacity: 1}, 300);
    });
});
請直接對照方法 2 和方法 3 的程式碼第一行,寫法差異不大,但是效果真的差很多。如果一次有大量的元素需要綁定,建議改用 delegate 的語法。

此外,delegate 還有跟 live 一樣的效用,對於未來產生的新元素也是馬上讓綁定事件生效,以上面的例子,如果我在 table 動態增加兩行,新增的那兩行的所有 td 也會馬上有相同的動畫效果,相當不錯吧。


[範例2]


再來一個簡單的範例,介紹針對不同元素進行不同的處理。先看看 HTML 的部份:
<ul id="links">
    <li><a href="http://jsgears.com/">http://jsgears.com/</a></li>
    <li><a href="http://www.google.com/">http://www.google.com/</a></li>
    <li><a href="http://www.yahoo.com/">http://www.yahoo.com/</a></li>
</ul>
上面是幾個超連結的列表,沒有帶 target 的屬性,如果我要透過 JavaScript 來幫我達到點擊後另開視窗,同樣可以用 delegate 的方式,將事件綁定在 #link 並針對下面所有的 <a>,在事件處理的函式中,則針對個別 <a> 的 href 屬性去另開視窗。JavaScript 的部份如下:
$("#link").delegate("a", "click", function () {
    window.open($(this).attr("href"));
    return false;
});
跟一般事件處理函式一樣,在裡面使用 $(this) 表示被觸發事件的元素,透過讀取該元素的特定屬性,就可以針對不同元素進行不同的處理。

[Ending]


希望以上兩個範例夠清楚,能讓大家明白所謂「事件委派」的奧妙,我只需要把事件綁定在「一個」比較上層的元素,然後針對底下「多個」元素進行事件的處理,寫法和原本的事件綁定並沒有差異很大,但是使用得當的情況下,卻可以省下 client 端 browser 的許多資源。很不錯吧,趕快學起來,有機會用得上的~
To infinity and beyond!

我想應該是綁定在上層元素的事件,會去判斷事件發生的原始點 (透過 e.target, e.srcElement),比對如果是符合要處理的元素,就進行處理。

實做的方法可以直接去看 jQuery 的原始碼。
To infinity and beyond!

TOP

返回列表 回復 發帖