2016-01-14 12 views
23
zu bekommen

Hallo, ich brauche eine Liste aller Frames für meine GreaseMonkey Skript, aber in der Tat, ich denke, es ist allgemeine Javascript-Frage. Es wäre großartig, wenn ich zu jedem einzelnen Frame gelangen könnte, der in der Seite verschachtelt ist. Bisher habe ich Probleme bekommen, die Anzahl der Frames in den Hauptdokumenten zu verschachteln.Java Script, Schwierigkeit, Liste aller verschachtelten Frames auf Seite

Seite I mit zu tun habe aus Frameset die Multi-Level- und Frames enthält andere Frames. Ich habe es geschafft, Informationen über Top-Level-Frames des Hauptdokument Frameset (in Code Level 1) zu bekommen, aber auf dieser Ebene bekomme ich Informationen, dass Frame-Anzahl für diese Frames gleich 0 ist, was nicht wahr ist.

kam ich habe oben mit folgendem 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 Ebene 0, die in der Tat Zählung Hauptdokument Rahmen und Ebene 1 Namen oder Hauptdokument Rahmen - diese Dinge sind korrekt gemeldet, aber nicht die Anzahl der Bilder von jedem Level 1 Rahmen. Und ich möchte wissen, ob es daran liegt, dass mein Code Fehler hat oder weil Subframes nicht vollständig geladen sind.

Ich habe versucht, meinen Code aus Tastenkombination aufrufen, wird schließlich wie seine vollständig geladen aussehen, aber hier ein anderes Problem, Code scheint wie folgt scheint nicht mit Seite zu arbeiten, die nur von Frame-Set bestehen

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

Am besten wäre, wenn der Code automatisch alle Frames und Subframes durchkämmt, aber mit seiner aktuellen Form (wo jeder Level seinen eigenen Loop hat) ist das auch gut.

Problem mit der Unfähigkeit, Abkürzungschlüssel zu verwenden, ist sekundär. Hauptsache ist die richtige Anzahl von Frames in Frames des Hauptdokuments und darüber hinaus.

EDIT: Beispielausgabe und Meine Testseite mit verschachteltem Frameset

Ausgabe

Ebene 0> 3

Stufe 1 - 0> main1 - 0

Ebene 1 - 1> Haupt2 - 0

Stufe 1 - 2> MAIN3 - 0

Testseite mit verschachtelten 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> 
+0

Wenn einer Ihrer Frames aus einer anderen Domäne stammt, haben Sie keinen Zugriff auf deren Inhalt (und damit auf Sub-Frames). Außerdem haben Sie einen offensichtlichen Fehler in Ihrem Code: 'frames2 [j] .frames.length'. – jcaron

+0

@jcaron Vielen Dank für das Aufzeigen von Fehlern, obwohl dieser Teil des Codes keine Chance hatte, ausgeführt zu werden, wenn ein Schritt vor der Zählung von 0 Bildern gemeldet wird. Ich bin mir der gleichen Herkunftspolitik bewusst und dies ist hier nicht der Fall. Ich habe immer noch keine Ahnung, warum ich Frames innerhalb von Frames des Hauptdokument-Frame-Sets nicht zählen kann. – MoreThanChaos

+0

Wird Ihr Code überhaupt ausgeführt? Fügen Sie Protokolle (mit Hilfe von 'console.log', die Sie in Ihrer Browser-Konsole sehen können) an verschiedenen Stellen hinzu, um zu sehen, welche Teile ausgeführt werden, und protokollieren Sie relevante Daten. Das wäre viel bequemer als eine "Warnung". – jcaron

Antwort

9

Das Problem ist das Ereignis, auf dem Sie das nennen. $(document).ready() wird ausgelöst, wenn das aktuelle DOM geladen wurde. Es wird also ausgelöst, wenn die 3 Hauptrahmen geladen sind. Aber zu diesem Zeitpunkt haben diese Frames ihre iframes noch nicht geladen. Wenn Sie das Ereignis in window.onload ändern, sollten Sie das erwartete Ergebnis haben. Wie folgt aus:

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

oder

window.onload = function(){ 
    ... 

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

Die Last-Ereignis ausgelöst wird am Ende des Dokuments Ladevorgang. Unter dieser Punkt sind alle Objekte im Dokument im DOM und alle die Bilder, Skripte, Links und Unterrahmen sind fertig geladen.

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

+0

Kannst du auch einen Blick auf Sache werfen, die ich durch den Weg des Versuchens stieß, um mein Problem zu lösen, ich meine 'document.addEventListener' funktioniert nicht während Verwenden Sie ein Dokument, das nur aus einem Frameset besteht, und teilen Sie Ihre Gedanken dazu mit? – MoreThanChaos

+1

Das Problem mit dem Keydown-Listener (oder jedem Ereignis, das Sie auf ein Fenster oder Dokument anwenden) besteht darin, dass diese Ereignisse in einem der Unterframes ausgelöst werden, nicht im obersten Fenster. Sie könnten diese Ereignisse zu diesen Unterframes hinzufügen, aber Sie müssen sie immer noch laden, so dass Sie mit dem gleichen Problem zurückkommen. –

2

frameset nicht in html5 unterstützt.

Bitte beachten Sie die folgende Demo: frameset Demo. Ich habe HTM-Dateien geändert.Die Idee ist, auf das Frameset-Onload-Ereignis zu hören und auf seinen Inhalt zuzugreifen, nachdem das onlnoad-Ereignis ausgelöst wurde.

Um auf den Inhalt des untergeordneten Frames zuzugreifen, muss Same-Origin policy aufgerufen werden.

+0

Danke für die Antwort, Sache ist, dass der Umgang mit 'Frames' nicht an mir liegt, ich versuche, die Benutzer-Seite des bestehenden Systems mit Web-Interface zu verbessern. In der Tat bin ich gezwungen, mit einer Menge verschachtelter 'Frames' umzugehen. – MoreThanChaos

3

Arbeits-Code-Lösung

eine rekursive Funktion verwenden und das windowload Ereignis, wie so (funktioniert in aktuelle Versionen von Chrome, FireFox und Edge-; nicht anderem Test funktioniert wahrscheinlich in IE5 + auch.).

Verwenden Sie diesen Code in Ihre 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> 

Diese auf die Konsole schreibt nur um Ihnen zu zeigen, was los ist, aber natürlich können Sie tun, was Sie wollen mit diese Information. Es erstellt eine flache Liste (Array) aller untergeordneten Frames, aber Sie können es hierarchisch strukturieren, wenn Sie möchten, oder was auch immer.

HTML 5 Erinnerung

Sie verwenden den HTML5 DOCTYPE, aber frameset wird nicht von HTML5 unterstützt. Aber es liegt im Ermessen des Browsers zu entscheiden, wann er aufhören soll, dies zu unterstützen, und viele von ihnen tun es immer noch. Ich empfehle Ihnen, frameset so schnell wie möglich zu verwenden. Verwenden Sie stattdessen iframe, wenn Sie rahmenartiges Verhalten benötigen (verschiedene Fenster und Dokumente).

+0

Ich habe nichts mit dem Shortcut-Key-Handler gemacht, aber Sie sagten, das sei sekundär und ich bin nicht klar, was Sie dort tun .. klingt, als ob Sie es nur zum Testen verwenden wollten, aber lassen Sie mich bitte wissen, wenn Du hast immer noch Probleme damit. Außerdem verwendet diese Lösung natives JavaScript, aber Sie können natürlich bei Bedarf auch jQuery ersetzen. – nothingisnecessary

+0

Danke für deine Antwort, ich verbessere eine existierende Web App, die auf Frames basiert - ich habe keinen Zugriff auf die Source selbst, nur so kann ich es verbessern mit GreaseMonkey und benutzerdefiniertem Skript - deshalb bin ich bin darauf beharrlich, mit "Frames" statt mit "iframes" umzugehen. Und ja, wegen der Flexibilität von jQuery werde ich es stattdessen native JS verwenden. Noch einmal vielen Dank! – MoreThanChaos

+0

Macht Sinn - Ich bin selbst in ähnliche Situationen geraten, wenn ich Legacy-Produkte aktualisiert habe. Danke, dass du meine Neugierde befriedigt hast. Lassen Sie mich wissen, wenn Sie Probleme mit der Lösung haben. – nothingisnecessary