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í?
9 answers
Lo resolví haciendo así:
$('#filecontainer').load(function(){
var iframe = $('#filecontainer').contents();
iframe.find("#choose_pics").click(function(){
alert("test");
});
});
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.
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
});
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);
});
}
});
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.
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
});
});
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:
- espere a que jQuery externo esté listo
- espere a que iframe cargue
- grab interior jQuery
- 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
.)
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>
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);
});
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