2012-07-24 22 views
5

Estoy tratando de utilizar un userscript Chrome o una secuencia de comandos Tampermonkey modificar una página con esta estructura:¿Cómo accedo a un java de iframe desde un usuario?

<body> 
content up here 

<iframe id="main" src="foo.dat"></iframe> 
</body> 

El marco flotante es del mismo origen.

Necesito acceder a una función que está en iframe#main. I pensó Podría usar unsafeWindow para obtenerlo pero sigo recibiendo nada o undefined devuelto.

que he probado un montón de cosas:

  • intentado crear un nuevo elemento de script en el iframe, pero se une a los padres incluso con $('frame#main').contents().append(script) o $('frame#main').contents()[0].createElement('script')

  • window.frames["#main"].contentWindow rendimientos definidos.

He intentado muchas otras cosas que no recuerdo en este momento, pero me han agotado todas mis ideas y sentir que estoy escribiendo basura más que nada lo que cuenta.
No puedo entender cómo jugar con el unsafeWindow del iFrame.

+0

Todo es el mismo origen – Skinner927

Respuesta

10
  1. unsafeWindow no funciona bien con marcos/iframes en Chrome, Tampermonkey o Firefox.
  2. Intentar acceder a JS global (al marco) con jQuery, de esa manera, no funcionará.
  3. los usuarios se ejecutarán en iframes que cumplan los requisitos @include, @exclude y/o @match.

Por lo tanto, debe tener en cuenta las secuencias de comandos múltiples y, a continuación, tiene dos enfoques básicos, en función de lo que está tratando de lograr. Puede:

(A) Adapte la secuencia de comandos a marcos específicos, como en this answer.

o (B) inyecte su JS y utilice el objeto especial frames para obtener la función específica que desee.

El siguiente script muestra ambos. Instálelo en Tampermonkey (o Firefox Greasemonkey), y luego visite this test page at jsBin.

// ==UserScript== 
// @name  _Calling iframe functions 
// @namespace _pc 
// @include  http://jsbin.com/ugoruz/* 
// @include  http://jsbin.com/okequw/* 
// ==/UserScript== 

console.log ("Script start..."); 

/*--- This next function call will work in Firefox or Tampermonkey ONLY, 
    not pure Chrome userscript. 
*/ 
console.log ("calling functionOfInterest()..."); 
unsafeWindow.functionOfInterest(); 


if (window.top === window.self) { 
    //--- Code to run when page is the main site... 
    console.log ("Userscript is in the MAIN page."); 

    //--- The frames object does not play nice with unsafeWindow. 
    /*--- These next three work in Firefox, but not Tampermonkey, nor pure Chrome. 
    console.log ("1", frames[1].variableOfInterest);    // undefined 
    console.log ("2", unsafeWindow.frames[1].variableOfInterest); // undefined 
    console.log ("3", frames[1].unsafeWindow);      // undefined 
    */ 
    /*--- This next would cause a silent crash, all browsers... 
    console.log ("4", unsafeWindow.frames[1].unsafeWindow.variableOfInterest); 
    */ 

    //--- To get at iFramed JS, we must inject our JS. 
    withPages_jQuery (demoAccessToFramedJS); 
} 
else { 
    //--- Code to run when page is in an iframe... 
    console.log ("Userscript is in the FRAMED page."); 
    console.log ("The frame's ID is:", window.self.frameElement.id); 
} 


function demoAccessToFramedJS ($) { 
    $("body").prepend (
      '<button id="gmMain">Run JS on main window</button>' 
     + '<button id="gmFrame">Run JS on iframe</button>' 
    ); 

    $("#gmMain, #gmFrame").click (function() { 
     if (this.id === "gmMain") { 
      functionOfInterest(); 
     } 
     else { 
      frames[1].functionOfInterest(); 
     } 
     console.log (this.id + "was clicked."); 
    }); 
} 

function withPages_jQuery (NAMED_FunctionToRun) { 
    //--- Use named functions for clarity and debugging... 
    var funcText  = NAMED_FunctionToRun.toString(); 
    var funcName  = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1"); 
    var script   = document.createElement ("script"); 
    script.textContent = funcText + "\n\n"; 
    script.textContent += 'jQuery(document).ready(function() {'+funcName+'(jQuery);});'; 
    document.body.appendChild (script); 
}; 

console.log ("Script end"); 



Usted verá que el script se ejecuta una función tanto de la página principal y desde el marco flotante. La salida de la consola (Tampermonkey) será:

 
Tampermonkey started 
Script start... 
calling functionOfInterest()... 
Userscript is in the MAIN page. 
Script end 
Tampermonkey started 
Script start... 
calling functionOfInterest()... 
Userscript is in the FRAMED page. 
The frame's ID is: iframe2 
Script end 

También funcionará como un userscript cromo recto-para arriba si se quita la línea (s) unsafeWindow.

+0

Bueno, lo que puso no funcionó exactamente para mí, pero esto combinado con su respuesta de referencia funcionó. Básicamente, lo que terminé haciendo fue, como sugirió, incluir la secuencia de comandos en ambos marcos, pero solo ejecutar partes de ella dependiendo de dónde se haya cargado la secuencia de comandos. Una solución un poco torpe, pero en este punto tomaré cualquier cosa. Gracias. – Skinner927

Cuestiones relacionadas