嵌套 iframe,又名 iframe Inception
Posted
技术标签:
【中文标题】嵌套 iframe,又名 iframe Inception【英文标题】:Nested iframes, AKA Iframe Inception 【发布时间】:2013-02-26 22:42:58 【问题描述】:我正在使用 jQuery 访问 div id="element"。
<body>
<iframe id="uploads">
<iframe>
<div id="element">...</div>
</iframe>
</iframe>
</body>
所有 iframe 都在同一个域中,没有 www / non-www 问题。
我已成功选择第一个 iframe 中的元素,但没有选择第二个嵌套 iframe。
我已经尝试了一些东西,这是最近的一次(也是一次非常绝望的尝试)。
var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
// iframeContent is null
编辑: 为了排除时间问题,我使用了点击事件并等待了一段时间。
jQuery().click(function()
var iframe = jQuery('#upload').contents().find('iframe');
console.log(iframe.find('#element')); // [] null
);
有什么想法吗? 谢谢。
更新: 我可以像这样选择第二个 iframe...
var iframe = jQuery('#upload').contents().find('iframe');
现在的问题似乎是 src 是空的,因为 iframe 是用 javascript 生成的。 所以选择了 iframe 但内容长度为 0。
【问题讨论】:
mattgemmell.com/2008/12/08/what-have-you-tried 这可能没用,但我不禁想知道为什么您要操作两次嵌套的 iframe 文档...您是怎么到这里的?可能的 XY 问题。 我正在创建一个使用 CKFinder 和 Amazon S3 的 DRM 应用程序。我试图改变的是CKFinder。我对功能进行了大量更改,但现在我需要更改 UI。 (不能用 CSS 更改,因为有多个实例不需要此特定更改) 根据this的回答,你必须在你想使用DOM遍历的每个iframe
中链接到jQuery。因此,在您的情况下,uploads
必须包含 <script type="text/javascript" src='js/jquery.min.js"></script>
或类似名称。
iframe 盗梦空间!
【参考方案1】:
问题是,您提供的代码不起作用,因为 <iframe>
元素必须具有“src”属性,例如:
<iframe id="uploads" src="http://domain/page.html"></iframe>
使用.contents()
获取内容即可:
$('#uploads).contents()
将允许您访问第二个 iframe,但如果该 iframe 在“内部”,http://domain/page.html
将记录 #uploads iframe 已加载。
为了测试我是对的,我创建了 3 个名为 main.html、iframe.html 和 noframe.html 的 html 文件,然后选择了 div#element 就好了:
$('#uploads').contents().find('iframe').contents().find('#element');
由于您需要等待 iframe 加载资源,因此该元素不可用会出现延迟。此外,所有 iframe 都必须在同一个域中。
希望这会有所帮助...
这是我使用的 3 个文件的 html(将“src”属性替换为您的域和 url):
main.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>main.html example</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function ()
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first
setTimeout( function ()
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
, 2000 );
);
</script>
</head>
<body>
<iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>
iframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>iframe.html example</title>
</head>
<body>
<iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>
noframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>noframe.html example</title>
</head>
<body>
<div id="element">some content</div>
</body>
【讨论】:
我的错。实际上,您可以在 iframe 上不使用“src”属性而仅使用 javascript 编写代码:<script> myHTML = '<p>you should write complete and proper html here, including the html, head and body tags</p>'; myFrame = document.getElementById("uploads").contentDocument; myFrame.open(); myFrame.write(myHTML); myFrame.close(); </script>
这对我有用。而且我在任何地方都没有身份证。我不得不玩课:)
@CarlosCastillo,非常感谢。它也解决了我在引导模式中的 iframe 问题。我正在寻找改变 iframe 内元素的方法,但我的功能总是在 iframe 完全加载之前加载。等待几秒钟是一个解决方案。再次感谢有用的答案,我投票赞成 1+ :)【参考方案2】:
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
iframeInner 包含来自
的元素<div id="element">other markup goes here</div>
并且 iframeContent 将查找位于内部的元素
<div id="element">other markup goes here</div>
(find 不在当前元素上搜索)这就是它返回 null 的原因。
【讨论】:
【参考方案3】:嘿,我得到了一些似乎在做你想做的事。它涉及一些肮脏的复制,但有效。你可以找到工作代码here
所以这里是主要的 html 文件:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
Iframe = $('#frame1');
Iframe.on('load', function()
IframeInner = Iframe.contents().find('iframe');
IframeInnerClone = IframeInner.clone();
IframeInnerClone.insertAfter($('#insertIframeAfter')).css(display:'none');
IframeInnerClone.on('load', function()
IframeContents = IframeInner.contents();
YourNestedEl = IframeContents.find('div');
$('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
);
);
);
</script>
</head>
<body>
<div id="insertIframeAfter">Hello!!!!</div>
<iframe id="frame1" src="Test_Iframe.html">
</iframe>
</body>
</html>
如您所见,加载第一个 iframe 后,我会获取第二个并克隆它。然后我将它重新插入到 dom 中,这样我就可以访问 onload 事件了。加载此内容后,我会从非克隆内容中检索内容(也必须加载,因为它们使用相同的 src)。然后,您可以随心所欲地处理内容。
这是 Test_Iframe.html 文件:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>Test_Iframe</div>
<iframe src="Test_Iframe2.html">
</iframe>
</body>
</html>
和 Test_Iframe2.html 文件:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>I am the second nested iframe</div>
</body>
</html>
【讨论】:
【参考方案4】:您可能遇到了时间问题。您的 document.ready 推荐可能在第二个 iFrame 加载之前触发。您没有足够的信息来提供更多帮助 - 但如果这似乎是可能的问题,请告诉我们。
【讨论】:
我认为这不是时间问题。一分钟后尝试在单击事件上查找元素仍返回 null。见编辑。【参考方案5】:您应该对稍后渲染的元素使用 live 方法,例如颜色框、隐藏字段或 iframe
$(".inverter-value").live("change",function()
elem = this
$.ajax(
url: '/main/invertor_attribute/',
type: 'POST',
aysnc: false,
data: id: $(this).val() ,
success: function(data)
// code
,
dataType: 'html'
);
);
【讨论】:
【参考方案6】:我认为到达您的 div 的最佳方式:
var your_element=$('iframe#uploads').children('iframe').children('div#element');
它应该运作良好。
【讨论】:
$('iframe').children('div') 没有找到任何东西。【参考方案7】:如果浏览器支持 iframe,则 iframe 内的 DOM 来自相应标签的 src 属性。 iframe 标签内的内容用作浏览器不支持 iframe 标签的后备机制。
参考:http://www.w3schools.com/tags/tag_iframe.asp
【讨论】:
【参考方案8】:我猜你的问题是你的 iframe 中没有加载 jQuery。
最安全的方法是依靠纯基于 DOM 的方法来解析您的内容。
或者,从 jQuery 开始,然后在你的 iframe 中,测试一次 typeof window.jQuery == 'undefined'
,如果为真,则在其中未启用 jQuery 并回退到基于 DOM 的方法。
【讨论】:
以上是关于嵌套 iframe,又名 iframe Inception的主要内容,如果未能解决你的问题,请参考以下文章