2011-03-07 98 views
17

我一直在玩添加隱藏的iframe元素到頁面,我想操縱這些加載後的DOM。我注意到,在將iframe添加到頁面後,我無法立即開始操作DOM,因爲它尚未加載。這不能用DOMContentLoaded事件完成,因爲這會觸發iframe中不存在的文檔,直到它被添加到頁面,所以我們必須使用load事件。onload的loadrame行爲vs addEventListener('load')

下面是一些測試代碼:

var iframe = document.createElement('iframe'); 
iframe.onload = function() { console.log('loaded!'); }; 
document.getElementsByTagName('body')[0].appendChild(iframe); 

可正常工作,但是當我將其更改爲addEventListener它甚至不被添加到DOM:

var iframe = document.createElement('iframe'); 
iframe.addEventListener('load', function() { console.log('loaded!'); }); 
document.getElementsByTagName('body')[0].appendChild(iframe); 

我的天堂」在IE中測試attachEvent

有人對此有所瞭解嗎?

回答

19

addEventListener()函數需要3個參數!看看https://developer.mozilla.org/en/DOM/element.addEventListener

的第三個參數被標記爲可選的,但後來他們寫:

請注意,此參數不是 在所有瀏覽器版本可選。

我不知道何時何地需要,但在調用addEventListener以2個參數,當我在FF4測試拋出一個異常:

未捕獲的異常:[異常...「沒有足夠的 參數」 nsresult: 「0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)」 位置: 「JS框架:: http://localhost/index.php :: ::第10行」 的數據:無]

順便說一句,你的代碼在Chrome中運行良好[字符串loaded!在控制檯中登錄]。

與FF一樣,IE9需要標準模式中的第三個參數(使用<!DOCTYPE html>)。 IE9是第一個支持W3C事件模型的IE。所以在早期版本中,我們需要嘗試attachEvent。我沒有更早的IE,但它在IE7/8標準模式下工作,甚至在IE9的怪癖模式下工作。這裏是我使用的代碼:

<!DOCTYPE html> 
<html> 
<head><title></title></head> 
<body> 
<script> 
    window.onload=function(){ 
     var iframe = document.createElement('iframe'); 
     var func = function() { console.log('loaded!');}; 
     if(iframe.addEventListener) 
      iframe.addEventListener('load', func, true); 
     else if(iframe.attachEvent) 
      iframe.attachEvent('onload',func); 
     document.body.appendChild(iframe); 
    } 
</script> 
</body> 
</html> 
+0

我相信你關於第三個參數的觀點正是問題所在,我沒有得到你所做的錯誤,但它可能只是被壓制了。我不記得,但很明顯,我沒有在Chrome中測試它(愚蠢的我...)很好,謝謝。 – roryf 2011-05-24 10:15:01

0

第一個例子工作嗎?不知道你尋找什麼,但是當事件工作,這應該闡明:jQuery的的document.ready源

$(document).ready equivalent without jQuery

的addEventListener並不在IE瀏覽器,因此,如果這就是你要測試,那麼在iframe被附加之前,第二個會失敗。

你也可以從頁面本身添加回調,但(例如,使用jQuery,所以你不要重新發明輪子)我懷疑$(iframe).ready() {..}會給你一致的行爲。

+0

不能使用'ready'事件,因爲這需要一個不存在的文檔,除非我遺漏了一些東西。 – roryf 2011-03-07 16:05:53

+0

我建議在iframe元素上使用與jquery document.ready相同的邏輯,例如像這個插件似乎這樣做:http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/但仍不清楚,如果你的第一個代碼片段有什麼問題,你是否試圖鉤在圖像加載之前?另外,假設你控制了iframe中的代碼,你可以使用document.ready來使用parent來回調函數。 – 2011-03-07 16:26:26

+0

第一個代碼片段正常工作(如上所述),但是'onload'屬性是非標準的(AFAIK),我只是想知道爲什麼符合標準的方式(忽略IE)不起作用。 iframe本身並不指向另一個頁面,我想將它加載到空白處並填充DOM。 – roryf 2011-03-07 16:39:11

1

這是爲我工作:

HTML:

iframe source code: <br /> 
<textarea id="output" rows="20" cols="60">loading ...</textarea> 

的JavaScript(上documentReady):

var iframe = document.createElement('iframe'); 
iframe.id = iframe.name = "testframe"; 
iframe.src = "http://fiddle.jshell.net"; 
iframe.width = 400; 
iframe.height = 100; 
iframe.style.display = "none"; 

if (iframe.addEventListener) 
    iframe.addEventListener("load", loaded, false); 
else 
    iframe.attachEvent("onload", loaded); 

function loaded() { 
    var html; 
    if (iframe.contentDocument) 
     html = iframe.contentDocument.getElementsByTagName("HTML")[0].innerHTML; 
    else 
     html = window.frames[iframe.name].document.getElementsByTagName("html")[0].innerHTML; 

    document.getElementById("output").value = html; 
} 

document.getElementsByTagName("body")[0].appendChild(iframe); 

觀看演示在:http://jsfiddle.net/WcKEz/

工程用的addEventListener,但包括attachEvent的後備。當然,只能在同一個域上訪問IFRAME的DOM。