2012-05-26 98 views
2

我只是測試用另一個頁面替換整個頁面使用JavaScript和I found this answerdocument.write。至於爲什麼document.write,我需要用同一頁面替換整個HTML,包括腳本和樣式。document.write和委託事件處理程序持久性

它做我想要的,但我似乎無法與我的事件處理程序保持一致。

$(document).delegate(...); 

目前,我有怪異的結果:我的處理程序使用所有連接到documentIn a fiddle I made,它附加一個處理程序。點擊後,事件觸發,重寫頁面,再次運行該函數 - 但它不附加處理程序。

但是在我的項目中,我正在執行相同的例程(d.w(),然後添加處理程序)。它重新連接一次,處理程序工作,但在完成第二個例程(仍在同一頁面上)之後,它不再連接。

所以我的問題是:

  • 當使用d.w(),執行現有的處理程序得到從document刪除?
  • window以及document以後相同d.w() s?或者它們以某種方式「更新」
  • 已經解析的腳本是否保留在內存中並在後續的d.w()之後運行?或者它們也被擦除?
+1

'的$(document).find( 「跨度」)''返回在1'時'patch'運行這兩種情況下,但不知何故'.delegate'不工作的第二次。 – pimvdb

回答

6

(以下適用於谷歌瀏覽器)

只有document被清除,在內存中的腳本仍保持不變。您可以通過將某些內容設置爲變量並通過.open清除文檔後查看它是否存在來輕鬆進行測試。

舊的本機處理程序因此從文檔中丟失,但jQuery仍然認爲該處理程序存在於其自己的事件模型中。您可以通過編輯日誌,看看它:

console.log('patch', JSON.stringify($.cache)); 

jQuery的永遠只重視每個事件的單個原生處理器,所以如果你有document註冊"click"事件,連接使用jQuery進一步處理不重視新本地處理程序,而是將處理程序推入jQuery內部處理程序數組中。

現在,因爲document.open刪除本機的處理程序,但沒有明確的JavaScript,jQuery的仍然認爲原生處理器存在,並進一步.delegate只到jQuery的內部處理器陣列。如果你用簡單的舊document.onclick替換你的處理程序,你會看到它開始工作。

您還可以,如果你添加$(document).unbind()繼續使用jQuery(或更穩健$.cache = {};,但這是內部的,如有更改)的.delegate之前,讓jQuery的再次同步。否則它不會,因爲它不知道你叫document.open

所以:

  1. 他們仍然是相同的對象,可以通過保存參考,並檢查安劍錚,卓傑document.open
  2. 他們留在記憶測試。

http://jsfiddle.net/wphzt/4/

+0

+1,感謝您的信息發佈。我做了一些調試 - 相關的代碼似乎是[這裏](https://github.com/jquery/jquery/blob/master/src/event.js#L109)。隊列仍然在jQuery的內存中,所以它不會再次調用addEventListener,但實際上處理程序*已被刪除,因爲文檔已被清除。結果,進一步的點擊根本不被註冊。 – pimvdb

+0

啊,我明白了。所以jQuery仍然認爲它是由於它自己的記錄而存在的。這解釋了很多。謝謝! – Joseph

+0

有趣的是,如果我在分配處理程序之前從'jQuery.cache'中刪除'document'條目...'var cache_idx = document [$。expando]; if($ .cache [cache_idx]){delete $ .cache [cache_idx]; }'......下一次嘗試調用處理程序會導致Firefox中出現錯誤'嘗試在已清除的範圍上運行編譯並運行腳本@ jquery.min.js:3'不知道這意味着什麼。 http://jsfiddle.net/wphzt/5/ – 2012-05-26 14:33:04

0

它停止從第二次工作的唯一原因是起因爲你的函數你寫

document.write('<span>'+(++i)+'</span>'); 

在這種情況下,下一次的文檔沒有委託函數遞增跨度值,但只有你在上面突出顯示的代碼段中寫的內容。因此,如你所懷疑的那樣,是的,它們也會被擦除。希望這可以幫助。

相關問題