dom - tag - title html w3schools
Inyectar una funciĆ³n de javascript en un iframe (2)
Este enlace ( versión archivada ) describe cómo inyectar código de un script en un iframe:
function injectJS() {
var iFrameHead = window.frames["myiframe"].document.getElementsByTagName("head")[0];
var myscript = document.createElement(''script'');
myscript.type = ''text/javascript'';
myscript.src = ''myscript.js''; // replace this with your SCRIPT
iFrameHead.appendChild(myscript);
}
Está bien, pero ¿qué sucede si quiero insertar un objeto de función en un iframe y ejecutarlo en el contexto iframe ? Digamos que tengo:
function foo () {
console.log ("Look at me, executed inside an iframe!", window);
}
y quiero insertar el código de foo dentro de un iframe? (la función foo podría ser algo cargado dinámicamente, no puedo simplemente envolverlo entre comillas )
Intenté ingenuamente:
var scriptFooString = "<script>" + foo.toString() + "</script>"
para obtener el código dentro de la función, pero
- No sé cómo insertarlo en el iframe HEAD (¿quizás con jquery?)
- No sé si es el camino correcto
- No sé qué sucede cuando la función es mucho más compleja que eso
- No sé lo que sucede con las comillas dobles y simples en
scriptFooString
¿Alguna pista?
Aquí está mi solución. Estoy usando jquery para insertar el contenido, luego uso eval para ejecutar las etiquetas de script en el contexto de ese iframe:
var content = $($.parseHTML(source, document, true));
$("#content").contents().find("html").html(content);
var cw = document.getElementById("content").contentWindow;
[].forEach.call(cw.document.querySelectorAll("script"), function (el, idx) {
cw.eval(el.textContent);
});
En primer lugar, solo puede lograr esto si su marco y la página que lo muestra están dentro del mismo dominio (debido a las reglas de dominio cruzado).
en segundo lugar, puede manipular objetos Dom y Window del marco directamente a través de JS:
frames[0].window.foo = function(){
console.log ("Look at me, executed inside an iframe!", window);
}
para obtener su marco de un objeto DOMElement que puede usar:
var myFrame = document.getElementById(''myFrame'');
myFrame.contentWindow.foo = function(){
console.log ("Look at me, executed inside an iframe!");
}
Tenga en cuenta que el alcance en foo NO se cambia, por lo que la ventana sigue siendo la ventana principal, etc. dentro de foo.
Si desea insertar algún código que deba ejecutarse en el contexto del otro marco, puede inyectar una etiqueta de script o evaluarla:
frames[0].window.eval(''function foo(){ console.log("Im in a frame",window); }'');
Aunque el consenso general es nunca utilizar eval, creo que es una mejor alternativa que la inyección DOM si REALMENTE necesita lograr esto.
Entonces, en su caso específico, podría hacer algo como:
frames[0].window.eval(foo.toString());