2012-02-23 17 views
12

我想用自己的話jQuery的專家來解釋爲什麼$(文件)標識符是由別人推薦的jQuery的關於()語句VS只是使用元素本身在()上使用jQuery時,爲什麼使用(文檔)與元素本身?

例1:爲什麼使用$(文檔)在這裏更好然後例2#?

$(document).on("click", ".areaCodeList a", function(){ 
    // do stuff 
}); 

示例2:爲什麼以這種方式使用元素考慮到與示例1相比不太好的做法?

$(".areaCodeList a").on("click", function(){ 
    // do stuff 
}); 
+5

它在哪裏推薦他人? – 2012-02-23 18:32:31

+0

誰說它推薦像例1那樣做?我聽說過相反的情況,直接綁定到子元素的表現比向dom應用事件要好。 – shanabus 2012-02-23 18:33:02

+0

請閱讀[文檔](http://api.jquery.com/on/)我添加到我的答案。深入瞭解該主題。 – gdoron 2012-02-23 18:39:54

回答

18

。這都是有效的。

前者適用於動態添加元素。您使用document是因爲您正在委託文檔對象的子項上的事件,因此事件會冒泡到文檔級別。選擇最近的父母也可以更方便(並且父母在加載時必須存在於頁面上)。

後者仍然有效,並且是將事件簡單地綁定到特定元素的首選方法。

我個人不建議通過document對象委託,而是在頁面加載存在最接近的父。

Hereon()的文檔。

+0

因此,您是否認爲您不建議將事件委託給文檔級別,而是父級別?我對你有正確的理解嗎? – Downpour046 2012-02-23 18:43:35

+2

是的。人們在對功能瞭解不多時使用'document'。我肯定會建議通過最親近的父母進行授權。請記住,父頁*必須*在頁面加載時存在。但這只是委託給動態元素。如果你只是想綁定,選擇你想綁定的元素,並以第一種方式進行。 – Purag 2012-02-23 18:44:54

8

這是不正確的。

這兩行做完全兩回事。

第一個是與".areaCodeList a"選擇委託事件,而第二線是連接到".areaCodeList a"元素的事件。

委託事件將觸發對每個".areaCodeList a"元素,儘管這是在DOM時線執行。

無論如何,不​​建議將代理活動附加到document如寫在live文檔:

由於所有.live()事件在文檔元素連接,它們被處理之前,事件時間最長和最慢的可能路徑

請閱讀ondocs

事件處理程序僅綁定到當前選定的元素;它們必須在代碼調用.on()時存在於頁面上。爲確保元素存在且可以選擇,請在文檔就緒處理程序中爲頁面上HTML標記中的元素執行事件綁定。如果將新的HTML注入頁面,請在將新的HTML放入頁面後選擇元素並附加事件處理程序。或者,使用委託事件來附加事件處理程序,如下所述。

委託事件有優勢,他們可以處理來自被添加到該文件在稍後的時間 後代元素的事件。通過 採摘這是保證出席 委派的事件處理程序連接時的元素,你可以使用委派事件 避免需要頻繁安裝和取下事件處理程序。這 元素可以在一個 模型 - 視圖 - 控制器設計視圖的容器元素,例如,或文檔如果事件 處理程序要監視文檔中的所有冒泡事件。該 文檔元素是文檔的頭部可用之前 裝載任何其他HTML,所以它是安全的,有重視事件,而 等待文件準備就緒。
...
...

+1

即將發佈這件事情。 – 2012-02-23 18:35:02

+0

你好,謝謝你的回答。根本不推薦將附加委託事件附加到文檔的理由是什麼?什麼是陷阱?性能?生活()被認爲是不好的習慣嗎?這就是爲什麼我問了,因爲我看到幾個「堆棧」開發人員說它更好的做法是將(文檔)與父元素或元素本身掛鉤( – Downpour046 2012-02-23 18:44:20

+0

@ Downpour046)。閱讀文檔:'因爲所有.live()事件都附加在文檔元素上,所以事件在處理之前會採用最長和最慢的路徑。因此,如果您使用'on',但將事件附加到文檔,則可以保留使用'活'# – gdoron 2012-02-23 18:46:58

2

這裏沒有任何「推薦」。第一個片段設置了一個「委託」事件,後者是一個「直接」事件。 documentation for on()深入解釋了這些。這將動態創建後的,例如,AJAX調用 - 當你需要監聽事件對於尚不存在的元素

委派的事件是必要的。它們有時也可能具有更好的性能 - 您需要更少的內存來將「真實」事件處理程序附加到文檔對象,而不是1000個按鈕。

我會說,它仍然preferrable時,你可以使用直接事件處理程序,或附加委託事件的元素儘可能接近真實的事件源,您可以。擁有文檔對象上的所有事件處理程序對性能來說可能很糟糕 - 您必須匹配針對所有選擇器的每個事件。如果您需要阻止冒泡事件 - 如果所有事件都在文檔中被捕獲,那麼它們也可能需要,它們已經冒泡到最後。

3

我認爲你很困惑一些概念。不建議綁定到文檔元素,但是有時您希望這樣做,例如將事件綁定到動態添加的元素時。

所有這可能看起來不清晰,所以here是直接使用類選擇並結合一個點擊事件的第一個例子中,元件被動態後面的事件綁定後插入。正如你所看到的,事件永遠不會被解僱,因爲我們選擇了事件綁定時DOM中不存在的元素。這相當於一個.click

現在看第二個例子。在這裏您看到我們將根元素定義爲document。這意味着點擊事件會一直在DOM樹上冒泡,然後在被點擊的元素具有動態類時觸發。這相當於.live

現在,如果一個例子中,在結合事件的元素存在於DOM的時候,該代碼會工作得很好,因爲你可以看到here

話雖這麼說。這是docs的一個例外,它闡明瞭上述行爲。

的事件處理程序僅結合到當前選擇的元素;他們 必須存在於您的代碼打電話給.on()

因此,總結。如果您確定在綁定事件時確保您選擇的元素沒有父元素保證在DOM中,請使用document元素。如果存在父元素,則使用該元素而不是document元素。通過這種方式,活動不需要沿着document一路上升,它只需要短距離旅行。

+0

感謝您的補充說明 – Downpour046 2012-04-10 16:25:10

1

實際上,在這種情況下,最好的解決方案不是使用$(document)也不是像$("selector")這樣的特定元素。

最好的方法是使用元素的容器並在on函數中綁定元素選擇器。通過這樣做可以避免不必要的文件冒泡事件。

因此,代碼應該是這樣的:

$("this_is_the_container").on('event','my_element_selector',function(){ 
// do some stuff here 
}) 
0
$(*selector*).on(*event*, function(){}) 

將僅適用於這已經是在頁面的腳本運行的慣性力矩負荷元素。如果將來會出現新的元素,則事件處理程序將不起作用。

$(document).on(*event*, *selector*, function(){} 

將執行事件處理程序,即使具有相同選擇器的元素將在腳本運行後出現在頁面上。

所以,如果你有一些元素,它可以出現在隨機時間後,用

$(document).on() 

使用別的

$(*selector*).on(); 
相關問題