您好我需要获取 GreaseMonkey 脚本的所有帧列表,但实际上我猜它是一般Javascript问题。如果我能够到达嵌套在页面中的每一个帧,那将是很棒的。到目前为止,我在获取嵌套在主文档框架中的帧数时遇到了问题。
我正在处理的页面包含多层的框架集,而框架包含其他框架。我已经设法获得有关主文档框架集的顶级框架的信息(代码级别1 ),但在此级别,我得到的信息是这些框架的帧计数等于0,这是不正确的。
我想出了以下代码
$(document).ready(function(){
var frames = window.frames;
var i,j;
var reportText = "level 0 > " + frames.length +"\r\n";
for (i = 0; i < frames.length; i++) {
var frames2 = frames[i].frames;
reportText += "level 1 - " + i + " > " + frames[i].name + " - " + frames2.length +"\r\n";
for (j = 0; j < frames2.length; j++) {
var frames3 = frames2[j].frames;
reportText += "level 2 - " + i + " - " + j + " > " + frames2[j].name + " - " + frames3.length +"\r\n";
}
}
alert(reportText);});
所以 0级实际上是主文档框数和 1级名称或主文档框架 - 这些都是正确报告但不是每个框架的帧数量 1级框架。我想知道是不是因为我的代码出错了,也可能是因为子帧没有完全加载。
我试图从键盘快捷键调用我的代码,毕竟看起来像是完全加载了,但是这里有另一个问题,好像下面的代码似乎不适用于只包含frameset的页面
(function(){
document.addEventListener('keydown', function(e) {
if (e.keyCode == 72 && !e.shiftKey && !e.ctrlKey && e.altKey && !e.metaKey) {
//...my previous code inside document.ready...
}
}, false);})();
如果代码自动梳理所有帧和子帧但其当前形状(每个级别都有自己的循环)也是好的。
无法使用快捷键的问题是次要问题。 主要是在主文档及其他框架内获得适当的帧数。
编辑: 示例输出和带嵌套框架集的我的测试页
输出
0级&gt; 3
1 - 0级&gt; main1 - 0
1 - 1级&gt; main2 - 0
1 - 2级&gt; main3 - 0
具有嵌套框架集的测试页
frame0.htm
<!DOCTYPE html>
<html>
<frameset cols="25%,*,25%">
<frame id="frmain1" name="main1" src="frame0_1.htm">
<frame id="frmain2" name="main2" src="frame0_2.htm">
<frame id="frmain3" name="main3" src="frame0_3.htm">
</frameset>
</html>
frame0_1.htm
<!DOCTYPE html>
<html>
<frameset rows="25%,*">
<frame id="frsub11" name="sub11" src="frame0_1_1.htm">
<frame id="frsub12" name="sub12" src="frame0_1_2.htm">
</frameset>
</html>
frame0_1_1.htm
<!DOCTYPE html>
<html>
<body style="background: darkorange;">
</body>
</html>
frame0_1_2.htm
<!DOCTYPE html>
<html>
<body style="background: lightyellow;">
</body>
</html>
frame0_2.htm
<!DOCTYPE html>
<html>
<frameset rows="25%,*,25%">
<frame id="frsub21" name="sub21" src="frame0_2_1.htm">
<frame id="frsub22" name="sub22" src="frame0_2_2.htm">
<frame id="frsub23" name="sub23" src="frame0_2_3.htm">
</frameset>
</html>
frame0_2_1.htm
<!DOCTYPE html>
<html>
<body style="background: skyblue;">
</body>
</html>
frame0_2_2.htm
<!DOCTYPE html>
<html>
<body style="background: cornflowerblue;">
</body>
</html>
frame0_2_3.htm
<!DOCTYPE html>
<html>
<body style="background: slateblue;">
</body>
</html>
frame0_3.htm
<!DOCTYPE html>
<html>
<frameset rows="25%,*">
<frame id="frsub31" name="sub31" src="frame0_3_1.htm">
<frame id="frsub32" name="sub32" src="frame0_3_2.htm">
</frameset>
</html>
frame0_3_1.htm
<!DOCTYPE html>
<html>
<body style="background: darkgreen;">
</body>
</html>
frame0_3_2.htm
<!DOCTYPE html>
<html>
<body style="background: lightgreen;">
<a id="test" href="http://www.google.com">testlink</a>
</body>
</html>
答案 0 :(得分:9)
问题是您调用此事件的事件。加载当前DOM时会触发$(document).ready()
。所以当加载3个主要帧时会触发它。但此时这些帧还没有加载iframes
。通过将事件更改为 window.onload ,您应该具有预期的结果。像这样:
$(window).load(function(){
...
或
window.onload = function(){
...
请参阅 window.onload :https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onload
加载事件在文档加载过程结束时触发。在 至此,文档中的所有对象都在DOM中,而且都是 图像,脚本,链接和子框架已完成加载。
答案 1 :(得分:3)
工作代码解决方案
使用递归函数和window
load
事件,就像这样(适用于Chrome,FireFox和Edge的最新版本;不测试其他版本。也可能适用于IE5 +)。
在顶级frameset
, frame0.htm 中使用此代码:
<!DOCTYPE HTML Frameset DTD>
<html>
<head>
<script>
window.onload = function()
{
var allFrames = [];
function recursFrames(context)
{
for(var i = 0; i < context.frames.length; i++)
{
console.log(context.frames[i].name + " -- " + context.frames[i].location.href);
allFrames.push(context.frames[i]);
recursFrames(context.frames[i]);
}
}
recursFrames(window);
console.log("Frames count: " + allFrames.length);
}
</script>
</head>
<frameset cols="25%,*,25%">
<frame id="frmain1" name="main1" src="frame0_1.htm">
<frame id="frmain2" name="main2" src="frame0_2.htm">
<frame id="frmain3" name="main3" src="frame0_3.htm">
</frameset>
</html>
这写入控制台只是为了向您显示正在发生的事情,但当然您可以使用此信息执行任何操作。它创建了一个包含所有子框架的平面列表(数组),但如果您愿意,可以按层次结构进行构造。
HTML 5提醒
您使用的是HTML5 DOCTYPE
,但HTML5不支持frameset
。但是由浏览器决定何时停止支持这一点,并且其中许多人仍然这样做。我建议您尽快停止使用frameset
。如果您需要类似框架的行为(不同的窗口和文档),请使用iframe
。
答案 2 :(得分:2)
请参阅以下演示:frameset Demo。我修改了htm文件。我们的想法是在onlnoad事件被触发后监听frameset onload事件并访问其内容。
要访问子框架的内容,必须调用Same-Origin policy。