2012-04-08 56 views
7

如果我運行下面的代碼,主體和頭標籤被刪除。爲什麼jQuery在使用樣式標籤填充iframe時刪除body和head標籤?

<iframe src='blank.htm'> 
    <html> 
    <head> 
     <style type="text/css"> 

     </style> 
    </head> 
    <body> 
     test 
    </body> 
    </html> 
</iframe> 
<script> 
    $('iframe').load(function() { 
     var contents = $('iframe').text(); 
     $('iframe').contents().find('html').html(contents); 
    }); 
</script> 

如果我然後刪除樣式標籤,一切都顯示正確。爲什麼會這樣,我怎樣才能讓它停止去除頭部和身體的標籤?我希望內容按原樣填充,無需任何操作。

+0

您爲什麼要這樣做?你能詳細說明嗎?想到的快速膝蓋反應是「不要這樣做」,但我懷疑你爲什麼這樣做的原因是你不告訴我們的? :)如果你告訴我們你的目標是什麼,我想我們可以做得更好。祝你好運! – jmort253 2012-04-08 04:57:48

+0

我創建了一個沙箱,可以讓我爲最終用戶正確顯示html模板。考慮預覽電子郵件,您需要查看最終結果在另一個Web窗口中的內容。如果沒有沙箱,你會施加不屬於消息內容的其他樣式和格式,反之亦然。此代碼允許我在頁面上放置iframe,而不會影響我的代碼或頁面本身的其餘部分。 – Middletone 2012-04-08 05:05:14

+0

這是一個預覽窗格,因此內容不一定在當時的任何其他地方,因此爲什麼我不只是用信息加載另一頁。 – Middletone 2012-04-08 05:07:52

回答

3

下面是您可以按照步驟瞭解如何將iframe內容複製到字符串,修改它並將其替換到iframe中的步驟。這些步驟旨在在您的Chrome調試器中執行,僅用於教育/演示目的。一旦你瞭解了這個過程,你就可以嘗試在你的網站上覆制代碼。

運行每一個功能在Chrome的調試時間:

// test iframe I loaded in a sandbox also at http://example.com 
$('body div:first').before('<iframe src="http://example.com/company"></iframe>'); 

// retrieved the body of the iframe - I cloned it so I could perform operations 
    // on the copy without bothering the iframe content. 
iBody = $('iframe:first').contents().find('body').clone(); 

// got the head 
iHead = $('iframe:first').contents().find('head').html(); 

// if there is script in the body, it really messes things up. So in my tests, 
    // I had to remove it before adding it back to the iframe. 
iBody.find("script").remove(); 

// verify there are no script elements 
ibody.html(); 

// replace the iframe head 
$('iframe:first').contents().find('head').html(iHead); 

// replace the iframe body first with a placeholder. The body is the sensitive 
    // part. If you destroy the DOM, it can make the entire page, including 
    // the parent, turn completely white. 
$('iframe:first').contents().find('body').html('<div></div>'); 

// ** inserted something in the copy to prove we modified it!! 
iBody.append("<div style='position:absolute;z-index:5000; color:red; " + 
    "background-color:white;'>JAMES WAS HERE</div>"); 

// now replace the body 
$('iframe:first').contents().find('body').html(iBody); 

在網站的底部,iframe中,我看到了我的留言紅色在白色背景上。我還可以看到它的來源:

$('iframe:first').contents().find('body').html(); 

我在匿名網站上進行這些操作,使用Chrome的調試器控制檯運行的命令。第一條命令會在主頁中使用iframe中的網站公司頁面創建一個iframe。其餘的命令獲取該iframe的頭部和主體,克隆主體,向主體克隆中添加一些內容,例如「JAMES WAS HERE」消息,然後用該副本替換iframe主體。

我還在我的瀏覽器中加載了http://getsatisfaction.com,並在iframe中加載http://getsatisfaction.com/explore/product-innovation,以此驗證了結果。通過重複上述步驟,我看到了我的消息,「JAMES在這裏」。

**我遇到的最嚴重的問題是無法在副本中保留JavaScript或CSS樣式標籤。樣式的解決方案是在之前將所有樣式修改添加到iframe。 **

由於某種原因,瀏覽器試圖運行JavaScript並拋出錯誤。這些錯誤的上下文讓我認爲JavaScript正在頂層上下文中運行,而不是iframe上下文!這對你來說可能是個不錯的選擇。您可能需要制定另一個在彈出窗口或內聯中顯示預覽的計劃。而且,這可能會在具有不同JavaScript的不同網站上表現不同。它也可能在IE中表現得很奇怪。

總之,實際上我沒有看到這個解決方案是支持生產網站的東西,因爲JavaScript必須在iframe中刪除;但是,根據您的需要,如果您不需要iframe DOM來使用任何JavaScript,則可以在生產中進行此項工作。

儘管如此,這是一個有趣的探索問題!

16

我有同樣的問題,並從this SO question瞭解到,其實它是不會剝離,作爲其innerHTML財產,這是jQuery.html()內部使用的解析部分瀏覽器。

相反,問題實際上是jQuery使用了一箇中間新的DIV,我認爲它不允許包含某些標籤,導致剝離。

然後解決方案。這是因爲直接設置html元素的innerHTML財產,像這樣簡單:

// This forcibly removes head, body, and other tags, since it internally uses an empty DIV and its innerHTML property 
jQuery(targetElement).html(exitHtml); 

// This works fine 
h = document.getElementsByTagName('html')[0]; 
h.innerHTML = htmlString; 

爲您的特定情況下,只需將html元素目標內iframe。 您的最終代碼可能是:

<script> 
    $('iframe').load(function() { 
     var contents = $('iframe').text(); 
     iframeHtml = $('iframe').contents().find('html').get(0); 
     iframeHtml.innerHTML = contents; 
    }); 
</script> 
+3

偉大的答案..我也是撓我的腦袋... – idragosalex 2015-02-13 07:48:35

+3

@Middletone恕我直言,這應該被接受的答案。 – 2015-09-23 08:15:31

+1

同意。這回答了問題,而接受的答案是一個技術上有趣的旅程,但不是答案。 – toxaq 2016-07-11 12:55:26