Desencadenar evento personalizado de iframe a documento principal

3 minutos de lectura

avatar de usuario
marco c

Tengo algunos problemas para activar un evento personalizado dentro de un iframe y detectarlo desde el documento principal. Tanto el iframe como el documento principal tienen el mismo origen (mismo protocolo, mismo host, mismo puerto).

¿Algún consejo?

  • Por favor escriba más claramente de lo que es the same source.

    –Alvin Wong

    19 de octubre de 2012 a las 5:05

  • puede llamar a parent.functionname() desde su iframe.

    – usuario10

    19 de octubre de 2012 a las 5:07

  • mismo protocolo, mismo host, mismo puerto

    – Marco C.

    19 de octubre de 2012 a las 5:09

  • ¿Qué pasa si la ventana principal está en un dominio diferente, entonces no puede generar eventos en la ventana principal desde iframes secundarios?

    -Raju Putchala

    24 de septiembre de 2021 a las 8:33

avatar de usuario
ryan safarian

Me encontré con un problema similar y usé window.postMessage resolver.

Actualmente, la API solo admite pasar una cadena, pero si modifica su solución, puede ser poderosa. Más detalles aquí

Desde la página de origen (siendo consumida por un iframe):
postMessage API espera 2 parámetros: mensaje, destino

ex: window.parent.postMessage("HELLO_PARENT", 'http://parent.com');

Desde la página principal (contiene iframe. Por ejemplo, contenedor):

  1. Agregue un detector de eventos como lo haría normalmente

     window.addEventListener('message', handleMessage, false);
    
  2. Defina su función con event.origen check (por seguridad) \

     function handleMessage(event) {  
         if (event.origin != "http://child.com") { return; }  
         switch(event.data) {   
              case "HELLO_PARENT":  
                 alert("Hello Child");  
                 break;  
         } 
     }
    

  • Tuve problemas para pasar objetos en cada IE y Edge

    – migueloop

    22 de junio de 2017 a las 6:36

  • @FarzadYZ – Su comentario parece contradecir lo que dice MDN: “Los window.postMessage() El método permite de forma segura la comunicación de origen cruzado”.

    – Juan S.

    24 de agosto de 2017 a las 0:53

  • JSON.stringify(yourObject) para enviarlo a través de postMessage

    – distopiandev

    30 de julio de 2018 a las 23:52

  • Necesito hacer lo mismo, pero el dominio del marco interno es diferente al del documento principal. ¿Cómo puedo lograr esto?

    – tarekahf

    21 de julio de 2020 a las 6:37

avatar de usuario
marco c

Esto funciona:

parent.$('body').trigger('eventName');

el evento desencadenado dentro del iframe se detectará en el documento principal.

  • ¿Qué sucede si la página principal no incluye jQuery?

    – Meekohi

    14/09/2017 a las 15:19

  • Puedes usar window.addEventListener como se sugiere a continuación.

    – Marco C.

    14/09/2017 a las 23:26

avatar de usuario
Farzad Yousefzadeh

Una respuesta coherente que admita iframes del mismo dominio y entre dominios es usar el sistema de eventos.

El objetivo es enviar un evento personalizado desde iframe al padre.

En el archivo fuente iframe:

var myCustomData = { foo: 'bar' }
var event = new CustomEvent('myEvent', { detail: myCustomData })
window.parent.document.dispatchEvent(event)

Y agregue esto en el archivo principal que contiene el iframe:

window.document.addEventListener('myEvent', handleEvent, false)
function handleEvent(e) {
  console.log(e.detail) // outputs: {foo: 'bar'}
}

  • ¿Puedo verificar cómo funciona esto para iframe entre dominios? window.parent.document arroja un error CORS (en caso de iframe de dominio cruzado).

    – silent_grave

    23 de julio de 2019 a las 8:24

  • No funcionó para mí. Estoy en un entorno angular 6. Quizás hay algo que bloquea esta comunicación, no estoy seguro.

    – MrBoJangles

    5 sep 2019 a las 18:02

También encontré mi manera de resolver este problema con jquery:

en el archivo principal:

<body>
        <iframe src="https://stackoverflow.com/questions/12967616/something.html"></iframe>

</body>

<script>
 window.document.addEventListener('event', function(e){
            console.log("event:" + e.detail);
            $("iframe").contents().find(".class[title="" + e.detail + ""]").css(someChanges);
</script>

vos tambien no es necesario agregar ningún otro EventListener en tus iFrames.

por supuesto, tal vez quieras ver mi CustomEvent:

var test  = "1";
var event = new CustomEvent('event', { detail: test })
                window.document.dispatchEvent(event);

Espero poder ayudar a alguien…

¿Ha sido útil esta solución?