Detectar evento de clic dentro de iframe


Estoy escribiendo un plugin para TinyMCE y tengo un problema con la detección de eventos de clic dentro de un iframe.

De mi búsqueda he llegado con esto:

Cargando iframe:

<iframe src='resource/file.php?mode=tinymce' id='filecontainer'></iframe>

HTML dentro del iframe:

<input type=button id=choose_pics value='Choose'>

JQuery:

//Detect click
$("#filecontainer").contents().find("#choose_pic").click(function(){
    //do something      
}); 

Otras publicaciones que he visto generalmente tienen un problema con diferentes dominios (esto no lo tiene). Pero, aún así, el evento no se detecta.

¿Se puede hacer algo así?

Author: BigDataScientist, 2012-11-18

9 answers

Lo resolví haciendo así:

$('#filecontainer').load(function(){

        var iframe = $('#filecontainer').contents();

        iframe.find("#choose_pics").click(function(){
               alert("test");
        });
});
 51
Author: Philip G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-08 21:26:39

No estoy seguro, pero usted puede ser capaz de utilizar simplemente

$("#filecontainer #choose_pic").click(function() {
    // do something here
});

Ya sea eso o simplemente podría agregar una etiqueta <script> en el iframe (si tiene acceso al código interior), y luego usar window.parent.DoSomething() en el marco, con el código

function DoSomething() {
    // do something here
}

En el padre. Si ninguno de ellos funciona, intente window.postMessage. Aquí hay algo de información sobre eso.

 6
Author: cpdt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 08:07:59

Sé que esto es viejo, pero la IDENTIFICACIÓN no coinciden en el código es choose_pic y uno es choose_pics:

<input type=button id=choose_pics value='Choose'>

$("#filecontainer").contents().find("#choose_pic").click(function(){
    //do something      
}); 
 3
Author: KiwisTasteGood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-30 10:43:40

La API tinymce se encarga de muchos eventos en el iframe de editores. Sugiero encarecidamente usarlos. Aquí hay un ejemplo para el controlador de clics

// Adds an observer to the onclick event using tinyMCE.init
tinyMCE.init({
   ...
   setup : function(ed) {
      ed.onClick.add(function(ed, e) {
           console.debug('Iframe clicked:' + e.target);
      });
   }
});
 2
Author: Thariama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-19 09:30:12

Solo publicando en caso de que ayude a alguien. Para mí, el siguiente código funcionó perfectamente:

$(document).ready(function(){
     $("#payment_status_div").hide();
     var iframe = $('#FileFrame').contents();
     iframe.find("#take_payment").click(function(){
         $("#payment_status_div").show("slow");
     });
});

Donde 'FileFrame' es el id del iframe y 'take_payment' es el botón dentro del iframe. Dado que mi formulario dentro del iframe se publica en un dominio diferente, cuando se usa load, recibí un mensaje de error que decía:

Bloqueado un marco con origen "https://www.example.com" de acceder a un marco con origen "https://secure-test.worldpay.com". Protocolos, dominios y puertos debe coincidir.

 1
Author: Abhijith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-20 13:54:13
$("#iframe-id").load( function() {
    $("#iframe-id").contents().on("click", ".child-node", function() {
        //do something
    });
});
 1
Author: Akash gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-27 11:36:08

En mi caso había dos jQuery, para el HTML interno y externo. Tenía cuatro pasos antes de poder adjuntar eventos internos:

  1. espere a que jQuery externo esté listo
  2. espere a que iframe cargue
  3. grab interior jQuery
  4. espere a que jQuery interno esté listo

$(function() {   // 1. wait for the outer jQuery to be ready, aka $(document).ready
    $('iframe#filecontainer').on('load', function() {   // 2. wait for the iframe to load
        var $inner$ = $(this)[0].contentWindow.$;   // 3. get hold of the inner jQuery
        $inner$(function() {   // 4. wait for the inner jQuery to be ready
            $inner$.on('click', function () {   // Now I can intercept inner events.
                // do something
            });
        });
    });
});

El truco es usar el jQuery interno para adjuntar eventos. Observe cómo obtengo el jQuery interno:

        var $inner$ = $(this)[0].contentWindow.$;

Tuve que salir de jQuery en el modelo de objetos para se. El enfoque $('iframe').contents() en las otras respuestas no funcionó en mi caso porque se queda con el jQuery externo. (Y por cierto devuelve contentDocument.)

 1
Author: Bob Stein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-02 17:25:26

Si alguien está interesado en una versión "reproducible rápida" de la respuesta aceptada, vea a continuación. Créditos a un amigo que no está en TAN. Esta respuesta también se puede integrar en la respuesta aceptada con una edición,... (Tiene que ejecutarse en un servidor (local)).

<html>
<head>
<title>SO</title>
<meta charset="utf-8"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<style type="text/css">
html,
body,
#filecontainer {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<iframe src="http://localhost/tmp/fileWithLink.html" id="filecontainer"></iframe>

<script type="text/javascript">
$('#filecontainer').load(function(){

  var iframe = $('#filecontainer').contents();

  iframe.find("a").click(function(){
    var test = $(this);
    alert(test.html());
  });
});
</script>
</body>
</html>

FileWithLink.html

<html>
<body>
<a href="https://stackoverflow.com/">SOreadytohelp</a>
</body>
</html>
 0
Author: BigDataScientist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-07 10:39:21

En mi caso, estaba tratando de disparar un evento personalizado desde el documento padre, y recibirlo en el iframe hijo, así que tuve que hacer lo siguiente:

var event = new CustomEvent('marker-metrics', {
    detail: // extra payload data here
});
var iframe = document.getElementsByTagName('iframe');
iframe[0].contentDocument.dispatchEvent(event)

Y en el documento iframe:

document.addEventListener('marker-metrics', (e) => {
  console.log('@@@@@', e.detail);
});
 0
Author: stevelacerda7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-19 16:42:43