javascript - síntomas - Detectar evento de clic dentro de iframe
sintomas de cancer de colon avanzado (9)
En mi caso, estaba intentando disparar un evento personalizado desde el documento principal y lo recibí 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);
});
Estoy escribiendo un complemento para TinyMCE y tengo un problema para detectar eventos de clic dentro de un iframe.
De mi búsqueda, se me ocurrió esto:
Cargando iframe:
<iframe src=''resource/file.php?mode=tinymce'' id=''filecontainer''></iframe>
HTML dentro de 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 es así). Pero, aún así, el evento no se detecta.
¿Se puede hacer algo como esto?
En mi caso, había dos jQuery''s , para el HTML interno y externo. Tenía cuatro pasos antes de poder adjuntar eventos internos:
- esperar a que jQuery externo esté listo
- espera a que iframe cargue
- agarrar jQuery interior
- 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 ello. El enfoque $(''iframe'').contents()
en las otras respuestas no funcionó en mi caso porque eso queda con el jQuery externo. (Y por cierto devuelve contentDocument
).
La API de tinymce se ocupa de muchos eventos en el iframe de los editores. Sugiero usarlos. Aquí hay un ejemplo para el manejador 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);
});
}
});
Lo resolví haciendo así:
$(''#filecontainer'').load(function(){
var iframe = $(''#filecontainer'').contents();
iframe.find("#choose_pics").click(function(){
alert("test");
});
});
No estoy seguro, pero es posible que solo puedas usar
$("#filecontainer #choose_pic").click(function() {
// do something here
});
O eso o simplemente podría agregar una etiqueta <script>
en el iframe (si tiene acceso al código dentro), y luego usar window.parent.DoSomething()
en el marco, con el código
function DoSomething() {
// do something here
}
en el padre Si ninguno de esos funciona, intente window.postMessage
. Aquí hay algo de información sobre eso .
Sé que esto es antiguo, pero los ID no coinciden en tu código, uno es choose_pic y el otro es choose_pics :
<input type=button id=choose_pics value=''Choose''>
$("#filecontainer").contents().find("#choose_pic").click(function(){
//do something
});
Si alguien está interesado en una versión "reproducible rápidamente" de la respuesta aceptada , consulte a continuación. Créditos a un amigo que no está en SO. 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://.com/">SOreadytohelp</a>
</body>
</html>
Solo publicando en caso de que ayude a alguien. Para mí, el siguiente código funcionó perfecto:
$(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. De iframe y ''take_payment'' es el botón dentro de 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:
Se bloqueó un marco con el origen " https://www.example.com " al acceder a un marco con origen " https://secure-test.worldpay.com ". Los protocolos, los dominios y los puertos deben coincidir.
$("#iframe-id").load( function() {
$("#iframe-id").contents().on("click", ".child-node", function() {
//do something
});
});