2011-03-28 24 views
7

¿Cuál es la forma correcta de detectar cuándo un iframe obtiene o pierde el foco (es decir, recibirá o no eventos de teclado)? Lo que sigue no está funcionando en Fx4:Detectando cuando un iframe obtiene o pierde el foco

var iframe = /* my iframe */; 
iframe.addEventListener("focus", function() { /* never gets called */ }, false); 
+0

Por favor, eche un vistazo a http://stackoverflow.com/questions/1926861/iframe -onblur-event –

+0

@Uw No tengo control sobre el contenido del iframe (origen diferente) y ese método requiere el acceso a iframe.contentDocument (no permitido para documentos que provienen de un origen diferente) – CAFxX

Respuesta

7

Resulta que no es realmente posible. Tuve que cambiar la lógica de mi página para evitar la necesidad de rastrear si el iframe tiene foco.

+1

Es posible. Ver mi respuesta – Ryan

+0

Las respuestas dadas son posibles con origen cruzado si implementa HTML5 sendMessage para hablar entre los dos – user3036342

0

La solución es inyectar un evento javascript en la página principal de esta manera:

var script = document.createElement('script'); 
script.type = 'text/javascript'; 

script.innerHTML = 
"document.addEventListener('click', function()" + 
"{ if(document.getElementById('iframe')) {" + 
    // What you want 
"}});"; 

head.appendChild(script); 
+0

Como escribí anteriormente en mi respuesta a Uw , No tengo control sobre el contenido del iframe (origen diferente). Esto obviamente significa que no puedo inyectar nada, ya sea de padres a hijos o de hijos a padres. – CAFxX

+0

Lo siento amigo, por lo que será más complicado en este tema puede necesitar pasar por alto el problema del dominio cruzado ... Todo el lote de solución existe pero no está muy limpio ... – Sindar

15

Puede sondear "document.activeElement" para determinar si coincide con el iframe. El sondeo no es ideal, pero funciona:

function checkFocus() { 
    if(document.activeElement == document.getElementsByTagName("iframe")[0]) { 
    console.log('iframe has focus'); 
    } else { 
    console.log('iframe not focused'); 
    } 
} 

window.setInterval(checkFocus, 1000); 
+0

No funciona para mí. Estoy usando cromo en una página con un video de youtube insertado. Hacer clic en el video no cambia document.activeElement, que siempre apunta a la ventana principal –

+0

Funciona en un iframe simple; no estoy seguro de qué hace el video de YouTube incorporado. Cuando hace clic en él, puede usar javascript para establecer el foco en otro lugar. Incluso podría estar usando Flash. – Ryan

+0

Probé más tarde con Chrome. De hecho, tengo diferentes comportamientos en Chrome x Chromium. En Chrome, funciona como dices. En cromo, funciona como dije anteriormente. –

7

Sé que es viejo, pero también tuve el mismo problema.

Terminé usando este pequeño pice de código:

$(document).on('focusout', function(){ 
     setTimeout(function(){ 
     // using the 'setTimout' to let the event pass the run loop 
     if (document.activeElement instanceof HTMLIFrameElement) { 
      // Do your logic here.. 
     } 
    },0); 
}); 
+0

no funcionó para [iframe de youtube] (https://developers.google.com/youtube/iframe_api_reference#Mobile_considerations). cuando llamé a player.nextVideo(), el iframe robó el foco sin llamar a este método – woojoo666

+0

Gracias, esto funcionó para mí. El tiempo de espera fue esencial ya que estaba tratando de ocultar un elemento desplegable cuando el usuario hizo clic en cualquier lugar con un simple clic de ventana evento que en realidad no se dispara cuando cambia el foco a un iframe (como tinymce usa).Este enfoque y tiempo de espera aseguran que puedo cerrar la ventana emergente y asegurarme de que todo lo que haga clic dentro de la ventana emergente también se active. – Johncl

+0

Gran solución. ¡Gracias! – GivP

0

Aquí está el código para detectar cuándo un iframe obtiene o pierde el foco

// This code can be used to verify Iframe gets focus/loses. 

     function CheckFocus(){ 

     if (document.activeElement.id == $(':focus').context.activeElement.id) { 
       // here do something 
      } 
    else{ 
     //do something 
    } 
} 
+0

¿Qué quiere decir con "este código se dispara"? No hay controladores de eventos, eso es solo un ... Como es que no puedo imaginar cómo se supone que funciona, proporcione un códec o similar que demuestre que funciona. – CAFxX

+0

este código se apaga significa que: Este código se puede usar dentro de cualquier evento o función para verificar que el elemento esté enfocado o borroso. Es simple. Hemos modificado el código para una mejor comprensión. –

+1

Claro, gracias, pero de eso no se trataba la pregunta. La pregunta pregunta cómo detectar, es decir, recibir una notificación. Su solución no envía una notificación, requiere un sondeo para el estado. – CAFxX

0

Esto podría funcionar

document.addEventListener('click', function(event) { 
    var frame= document.getElementById("yourFrameID"); 

    var isClickInsideFrame = frame.contains(event.target); 

    if (!isClickInsideFrame) { 
    //exec code 
    } 

}); 
+0

desafortunadamente, no funciona con diferentes dominios (CORS). por ejemplo: https://jsfiddle.net/liadmagen/bxhwv9v1/1/ –

Cuestiones relacionadas