2012-04-08 50 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