最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Java Script, Difficulty getting list of all nested frames in page - Stack Overflow

programmeradmin4浏览0评论

Hello I need to get list of all frames for my GreaseMonkey script but in fact i guess it is general Javascript question. It would be great if I could get to every single frame that is nested in page. So far i got problem getting number of frames nested in main document frames.

Page I'm dealing with consist of frameset that is multilevel and frames contains other frames. I've managed to get information about top-level frames of main document frameset (in code level 1) but at this level i get information that frame count for these frames equals 0 which is not true.

I've came up with following code

$(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);});

So level 0 which is in fact main document frame count and level 1 names or main document frames - these things are reported correctly but not the amount of frames of each level 1 frame. And i want to know if it is because my code got mistakes or maybe because subframes are not yest fully loaded.

I've tried to call my code from keyboard shortcut, after all will look like its completely loaded, but here another problem, seems like following code seems to not to work with page that consist only of 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);})();

Best would be if code automatically comb through all frames and subframes but with its current shape (where each level got it own loop) is also good.

Problem with inability of using shortcut key is secondary. Main thing is getting proper counts of frames inside frames of main document and beyond.

EDIT: Sample output and My test page with nested frameset

Output

level 0 > 3

level 1 - 0 > main1 - 0

level 1 - 1 > main2 - 0

level 1 - 2 > main3 - 0

Test page with nested frameset

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=";>testlink</a>
</body>
</html>

Hello I need to get list of all frames for my GreaseMonkey script but in fact i guess it is general Javascript question. It would be great if I could get to every single frame that is nested in page. So far i got problem getting number of frames nested in main document frames.

Page I'm dealing with consist of frameset that is multilevel and frames contains other frames. I've managed to get information about top-level frames of main document frameset (in code level 1) but at this level i get information that frame count for these frames equals 0 which is not true.

I've came up with following code

$(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);});

So level 0 which is in fact main document frame count and level 1 names or main document frames - these things are reported correctly but not the amount of frames of each level 1 frame. And i want to know if it is because my code got mistakes or maybe because subframes are not yest fully loaded.

I've tried to call my code from keyboard shortcut, after all will look like its completely loaded, but here another problem, seems like following code seems to not to work with page that consist only of 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);})();

Best would be if code automatically comb through all frames and subframes but with its current shape (where each level got it own loop) is also good.

Problem with inability of using shortcut key is secondary. Main thing is getting proper counts of frames inside frames of main document and beyond.

EDIT: Sample output and My test page with nested frameset

Output

level 0 > 3

level 1 - 0 > main1 - 0

level 1 - 1 > main2 - 0

level 1 - 2 > main3 - 0

Test page with nested frameset

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>
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jan 14, 2016 at 2:35 MoreThanChaosMoreThanChaos 2,0925 gold badges22 silver badges40 bronze badges 4
  • If any of your frames are from a different domain, you won't have access to their contents (and hence sub-frames). Also you have an obvious error in your code here: frames2[j].frames.lenght. – jcaron Commented Jan 14, 2016 at 13:58
  • @jcaron Thanks for pointing out mistake, though this part of code doesn't had chance to execute when one step before 0 frame count is reported. I'am aware of same origin policy and this is not the case here. Still i have not a clue why i can't get count of frames inside frames of main document frameset. – MoreThanChaos Commented Jan 14, 2016 at 14:12
  • Is your code executed at all? Add logs (using console.log, which you'll be able to see in your browser console) at different places to see which parts are executed, and log relevant data. That would be a lot more convenient than an alert. – jcaron Commented Jan 14, 2016 at 14:23
  • @jcaron Yes it executes, in this case alert was more convenient for me. I've added sample output and page with nested frameset that i use for testing purposes – MoreThanChaos Commented Jan 14, 2016 at 16:51
Add a comment  | 

3 Answers 3

Reset to default 9 +100

The problem is the event on which you call this. $(document).ready() is fired when the current DOM has been loaded. So it's triggered when the 3 main frames are loaded. But at this point these frames didn't load their iframes yet. By changing the event to window.onload, you should have the expected result. Like this:

$(window).load(function(){
    ...

or

window.onload = function(){
    ...

See window.onload: https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onload

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.

See https://api.jquery.com/ready/

Working Code Solution

Use a recursive function and the window load event, like so (works in latest versions of Chrome, FireFox and Edge; didn't test others. Probably works in IE5+ also).

Use this code in your top level 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>

This writes to the console just to show you what is going on, but of course you can do whatever you want with this information. It creates a flat list (array) of all child frames, but you could structure it hierarchically if you like, or whatever.

HTML 5 Reminder

You are using the HTML5 DOCTYPE, but frameset is not supported by HTML5. But it is up to the browser to decide when to stop supporting this, and many of them still do. I recommend you stop using frameset ASAP. Use iframe instead if you need frame-like behavior (different windows and documents).

frameset is not supported in html5.

Please see the following demo: frameset Demo. I have modified htm files. The idea is to listen to frameset onload event and access its contents after onlnoad event is fired.

In order to access content of child frame, Same-Origin policy must be invoked.

发布评论

评论列表(0)

  1. 暂无评论