Pregunta Invocar código JavaScript en un iframe desde la página principal


Básicamente, tengo un iframe incrustado en una página y el iframe Tiene algunos JavaScript rutinas que necesito invocar desde la página principal.

Ahora todo lo contrario es bastante simple ya que solo necesita llamar parent.functionName(), pero desafortunadamente, necesito exactamente lo opuesto a eso.

Tenga en cuenta que mi problema no está cambiando la fuente URL del iframe, pero invocando una función definida en iframe.


555
2017-10-30 19:27


origen


Respuestas:


Suponga que su id de iFrame es "targetFrame" y que la función a la que desea llamar es targetFunction():

document.getElementById('targetFrame').contentWindow.targetFunction();

También puedes acceder al marco usando window.frames en lugar de document.getElementById.

// this option does not work in most of latest versions of chrome and Firefox
window.frames[0].frameElement.contentWindow.targetFunction(); 

495
2017-10-30 19:35



Hay algunas peculiaridades para tener en cuenta aquí.

  1. HTMLIFrameElement.contentWindow es probablemente la manera más fácil, pero no es una propiedad estándar y algunos navegadores no lo admiten, principalmente los más antiguos. Esto se debe a que el estándar de HTML DOM Nivel 1 no tiene nada que decir sobre la window objeto.

  2. También puedes probar HTMLIFrameElement.contentDocument.defaultView, que un par de navegadores más antiguos permiten pero IE no. Aun así, el estándar no dice explícitamente que obtienes la window Objeto de nuevo, por la misma razón que (1), pero puede recoger algunas versiones de navegador adicionales aquí si le importa.

  3. window.frames['name'] devolver la ventana es la interfaz más antigua y, por lo tanto, la más confiable. Pero luego debes usar un name="..." atributo para poder obtener un marco por nombre, que es ligeramente feo /obsoleto/transicional. (id="..." sería mejor, pero a IE no le gusta eso).

  4. window.frames[number] también es muy confiable, pero conocer el índice correcto es el truco. Puedes salirte con la tuya, por ejemplo. si sabes que solo tienes un iframe en la página.

  5. Es muy posible que el iframe hijo todavía no se haya cargado, o que algo haya salido mal para hacerlo inaccesible. Es posible que le resulte más fácil revertir el flujo de comunicaciones: es decir, haga que el iframe hijo notifique a su window.parent script cuando ha terminado de cargarse y está listo para ser devuelto. Al pasar uno de sus propios objetos (por ejemplo, una función de devolución de llamada) al script principal, ese padre puede comunicarse directamente con el script en el iframe sin tener que preocuparse de con qué HTMLIFrameElement está asociado.


140
2017-10-30 20:27



Llamando a una función padre JS desde iframe es posible, pero solo cuando tanto el padre como la página cargados en iframe son del mismo dominio, es decir, abc.com, y ambos están utilizando el mismo protocolo, es decir, ambos están en http:// o https://.

La llamada fallará en los casos mencionados a continuación:

  1. La página padre y la página iframe son de dominio diferente.
  2. Están usando diferentes protocolos, uno está en http: // y otro está en https: //.

Cualquier solución a esta restricción sería extremadamente insegura.

Por ejemplo, imagine que registré el dominio superwinningcontest.com y envié enlaces a los correos electrónicos de las personas. Cuando cargaron la página principal, pude esconder algunos iframes allí y lea su información de Facebook, verifique transacciones recientes de Amazon o PayPal, o - si usaron un servicio que no implementó seguridad suficiente - transferir dinero de sus cuentas. Es por eso que JavaScript está limitado al mismo dominio y al mismo protocolo.


62
2018-04-18 17:11



En el IFRAME, haz que tu función sea pública para el objeto ventana:

window.myFunction = function(args) {
   doStuff();
}

Para acceder desde la página principal, usa esto:

var iframe = document.getElementById("iframeId");
iframe.contentWindow.myFunction(args);

29
2017-10-30 19:39



Si el iFrame y el documento que lo contiene están en un dominio diferente, es posible que los métodos publicados anteriormente no funcionen, pero existe una solución:

Por ejemplo, si el documento A contiene un elemento de iframe que contiene el documento B y el script en el documento A llama a postMessage () en el objeto de ventana del documento B, se activará un evento de mensaje en ese objeto, marcado como originario de la ventana de documento A. La secuencia de comandos en el documento A podría ser similar a:

var o = document.getElementsByTagName('iframe')[0];
o.contentWindow.postMessage('Hello world', 'http://b.example.org/');

Para registrar un controlador de eventos para eventos entrantes, el script usaría addEventListener () (o mecanismos similares). Por ejemplo, la secuencia de comandos en el documento B podría verse así:

window.addEventListener('message', receiver, false);
function receiver(e) {
  if (e.origin == 'http://example.com') {
    if (e.data == 'Hello world') {
      e.source.postMessage('Hello', e.origin);
    } else {
      alert(e.data);
    }
  }
}

Esta secuencia de comandos comprueba primero que el dominio es el esperado y luego mira el mensaje, que muestra al usuario o responde enviando un mensaje al documento que envió el mensaje en primer lugar.

vía http://dev.w3.org/html5/postmsg/#web-messaging


15
2017-10-29 10:22



Solo para el registro, me he encontrado con el mismo problema hoy, pero esta vez la página estaba incrustada en un objeto, no en un iframe (ya que era un documento XHTML 1.1). Así es como funciona con los objetos:

document
  .getElementById('targetFrame')
  .contentDocument
  .defaultView
  .targetFunction();

(perdón por los feos saltos de línea, no cabían en una sola línea)


8
2018-06-30 12:48



El IFRAME debe estar en el frames[] colección. Usa algo como

frames['iframeid'].method();

8
2017-10-30 19:36