Java脚本,难以获取页面

时间:2016-01-14 02:35:40

标签: javascript jquery html greasemonkey frames

您好我需要获取 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>

3 个答案:

答案 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中,而且都是   图像,脚本,链接和子框架已完成加载。

请参阅https://api.jquery.com/ready/

答案 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不支持

html5

请参阅以下演示:frameset Demo。我修改了htm文件。我们的想法是在onlnoad事件被触发后监听frameset onload事件并访问其内容。

要访问子框架的内容,必须调用Same-Origin policy