2016-01-14 5 views
23

Ciao ho bisogno di ottenere l'elenco di tutti i frame per la mia GreaseMonkey sceneggiatura, ma in realtà credo che sia generale domanda Javascript. Sarebbe bello se potessi arrivare a ogni singolo frame che è annidato nella pagina. Finora ho avuto problemi a ottenere il numero di fotogrammi annidati nei fotogrammi del documento principale.Java Script, difficoltà di ottenere l'elenco di tutti i frame nidificati in pagina

pagina ho a che fare sono costituiti da frame cioè multilivello e cornici contiene altri fotogrammi. Sono riuscito a ottenere informazioni sui frame di primo livello del set di frame del documento principale (nel codice livello 1) ma a questo livello ottengo informazioni che il numero di frame per questi frame è uguale a 0 che non è vero.

ho si avvicinò con seguente codice

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

Così livello 0 che è in realtà principale conteggio dei fotogrammi del documento e livello 1 nomi o nei quadri di documenti - queste cose sono riportati in modo corretto, ma non la quantità di frame di ciascun frame livello 1. E voglio sapere se è perché il mio codice ha degli errori o forse perché i sottoframe non sono stati caricati completamente.

Ho provato a chiamare il mio codice da scorciatoia da tastiera, dopo tutto avrà un aspetto come il suo stato caricato completamente, ma qui un altro problema, sembra come seguente codice sembra non funzionare con la pagina che consistono solo di frame

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

Il meglio sarebbe se il codice si pettina automaticamente attraverso tutti i fotogrammi e i sottoframe ma con la sua forma attuale (dove ogni livello ha il proprio ciclo) è anche un bene.

Il problema con l'impossibilità di utilizzare il tasto di scelta rapida è secondario. La cosa principale è ottenere conteggi corretti dei fotogrammi all'interno dei fotogrammi del documento principale e oltre.

EDIT: uscita del campione e la mia pagina di prova con nidificato frame

uscita

livello 0> 3

Livello 1 - 0> Principale1 - 0

livello 1 - 1> main2 - 0

livello 1 - 2> main3 - 0

pagina di prova con frame nidificato

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

Se uno dei frame proviene da un dominio diverso, non sarà possibile accedere ai relativi contenuti (e quindi ai sub-frame). Inoltre hai un evidente errore nel tuo codice qui: 'frames2 [j] .frames.lenght'. – jcaron

+0

@jcaron Grazie per aver segnalato l'errore, sebbene questa parte di codice non abbia avuto la possibilità di eseguire quando viene segnalato un passo prima del conteggio di 0 fotogrammi. Sono a conoscenza della stessa politica di origine e questo non è il caso qui. Ancora non ho idea del perché non riesco a ottenere il conteggio dei frame all'interno dei frames del set di frame del documento principale. – MoreThanChaos

+0

Il tuo codice è stato eseguito? Aggiungi registri (utilizzando 'console.log', che potrai vedere nella console del tuo browser) in diversi punti per vedere quali parti sono eseguite e registrare i dati rilevanti. Sarebbe molto più conveniente di un "allarme". – jcaron

risposta

9

Il problema è l'evento su cui si chiama questo. $(document).ready() viene generato quando il DOM corrente è stato caricato. Quindi viene attivato quando vengono caricati i 3 frame principali. Ma a questo punto questi frame non hanno ancora caricato il loro iframes. Modificando l'evento su window.onload, si dovrebbe avere il risultato previsto. Come questo:

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

o

window.onload = function(){ 
    ... 

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

Il carico generato l'evento al termine del processo di caricamento del documento. A questo punto, tutti gli oggetti nel documento sono nel DOM e tutte le immagini, script, collegamenti e sub-frame hanno terminato il caricamento.

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

+0

Puoi anche dare un'occhiata a qualcosa che ho trovato nel modo di provare a risolvere il mio problema, voglio dire che "document.addEventListener' non funziona mentre utilizzare su un documento composto solo da set di frame e condividere i tuoi pensieri a riguardo? – MoreThanChaos

+1

Il problema con il listener di keydown (o qualsiasi evento applicato sulla finestra o sul documento), è che questi eventi verranno attivati ​​su uno dei sub-frame, non sulla finestra in alto. Potresti aggiungere questi eventi su questi sottos frame, ma avrai ancora bisogno che siano caricati, quindi la tua schiena con lo stesso problema. –

2

frameset non è supportata in html5.

Vedere la seguente dimostrazione: frameset Demo. Ho modificato i file htm.L'idea è di ascoltare l'evento onload del frameset e accedere ai suoi contenuti dopo che l'evento onlnoad è stato attivato.

Per accedere al contenuto del frame secondario, è necessario richiamare Same-Origin policy.

+0

Grazie per la risposta, la cosa è che trattare con 'frames' non dipende da me, cerco di migliorare il lato utente del sistema esistente con l'interfaccia web. Quindi in effetti sono costretto ad occuparmi di un mucchio di 'frame' nidificati. – MoreThanChaos

3

codice di lavoro Soluzione

Utilizzare una funzione ricorsiva e il windowload evento, in questo modo (funziona in tutte le versioni di Chrome, FireFox ed Edge, non prova gli altri funziona Probabilmente in IE5 + anche.).

Utilizzare questo codice nel tuo livello superiore 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> 

Questo scrive alla console solo per mostrare ciò che sta succedendo, ma naturalmente si può fare quello che vuoi con questa informazione. Crea una lista piatta (array) di tutti i frame figli, ma è possibile strutturarla gerarchicamente se lo si desidera, o qualsiasi altra cosa.

HTML 5 Reminder

Si utilizza l'HTML5 DOCTYPE, ma frameset non è supportato da HTML5. Ma spetta al browser decidere quando smettere di supportarlo, e molti lo fanno ancora. Vi consiglio di smettere di usare frameset al più presto. Utilizzare invece iframe se si desidera un comportamento simile al frame (finestre e documenti diversi).

+0

Non ho fatto niente con il gestore di tasti di scelta rapida, ma hai detto che era secondario e non sono chiaro su cosa stai facendo lì .. sembra che stavi solo provando a usarlo per i test, ma per favore fammi sapere se stai ancora avendo problemi con questo. Inoltre, questa soluzione utilizza il javascript nativo, ma puoi ovviamente sostituirlo con jQuery se lo desideri. – nothingisnecessary

+0

Grazie per la tua risposta, la cosa è che sto migliorando qualche app web esistente che si basa sui frame - non ho accesso alla fonte stessa solo il modo in cui posso migliorarla è con GreaseMonkey e script definito dall'utente - ecco perché io insistiamo nel trattare con 'frames' invece di' iframe'. E sì a causa della flessibilità di jQuery lo userò invece come JS nativo. Grazie ancora! – MoreThanChaos

+0

Ha senso: mi sono imbattuto in situazioni simili durante l'aggiornamento di prodotti legacy. Grazie per aver soddisfatto la mia curiosità. Fammi sapere se hai qualche problema con la soluzione. – nothingisnecessary

Problemi correlati