2008-12-15 15 views
34

Tengo una página con un controlador de eventos document.onkeydown, y la estoy cargando dentro de un iframe en otra página. Tengo que hacer clic dentro del iframe para que la página de contenido comience a "escuchar".Establecer foco en contenido de iframe

¿Hay alguna manera de que pueda usar JavaScript en la página externa para establecer el foco en la página interna, así que no tengo que hacer clic dentro del iframe?

EDIT: respuesta al comentario:

El contexto es la ventana principal es un sistema de luz en forma de caja, excepto que en lugar de las imágenes, se muestra iframes, y cada marco flotante es una página interactiva con keydown manipuladores/mousemove . estos manejadores no disparan hasta que hago clic en el iframe después de mostrar la caja de luz.

No estoy realmente en busca de "setFocus" en el sentido tradicional tanto como "permitir que los controladores de eventos en el marco flotante contentDocument"

+0

¿Puede proporcionar más contexto? ¿Estás escribiendo en la ventana principal y esperando que ese texto aparezca (de una forma u otra) en tu iframe? Esto es relevante porque establecer el foco dentro de su iframe interferiría con los usuarios que escriben en la ventana principal. – cLFlaVA

Respuesta

45

Tuve un problema similar con el jQuery Thickbox (un widget de diálogo de estilo de caja de luz). La forma en que fijo mi problema es el siguiente:

function setFocusThickboxIframe() { 
    var iframe = $("#TB_iframeContent")[0]; 
    iframe.contentWindow.focus(); 
} 

$(document).ready(function(){ 
    $("#id_cmd_open").click(function(){ 
     /* 
     run thickbox code here to open lightbox, 
     like tb_show("google this!", "http://www.google.com"); 
     */ 
     setTimeout(setFocusThickboxIframe, 100); 
     return false; 
    }); 
}); 

El código no parece funcionar sin el setTimeout(). Según mis pruebas, funciona en Firefox3.5, Safari4, Chrome4, IE7 e IE6.

+0

extraño pero cierto - ¡realmente solo funciona con setTimeout! ve figura ... – artur

+0

Supongo que es porque A: el iframe tiene que terminar de cargar y B: safari tiene (¿tenía?) un error al respecto y requiere un setTimeout de al menos 1 – Quickredfox

+0

Gracias por compartir. Funciona genial. –

6
document.getElementsByName("iframe_name")[0].contentWindow.document.body.focus(); 
+0

no parece funcionar para mí – Jimmy

+0

Una pequeña variación de esta solución funcionó en mi proyecto. Mi versión era: 'this.iframe [0] .contentWindow.document.body.focus();' Pero tuve que modificarlo de esa manera para trabajar dentro del complemento que estoy usando. –

4

Trate de escuchar para los eventos en el documento principal y pasar el caso a un manejador en el documento iframe.

0

Esto es algo que funcionó para mí, a pesar de que huele un poco mal:

var iframe = ... 
var doc = iframe.contentDocument; 

var i = doc.createElement('input'); 
i.style.display = 'none'; 
doc.body.appendChild(i); 
i.focus(); 
doc.body.removeChild(i); 

hmmm. también se desplaza al final del contenido. Supongo que debería insertar el cuadro de texto ficticio en la parte superior.

15

Usando el método contentWindow.focus(), probablemente sea necesario esperar para que el iframe se cargue por completo.

Para mí, utilizando también el atributo onload="this.contentWindow.focus()" obras, con Firefox, en la etiqueta de marco flotante

+0

El uso de esta solución combinada con la sugerencia de Jaime a continuación ha resuelto mi problema al menos en los navegadores mozilla y webkit. Todavía estoy revisando IE ... –

1

descubrí que FF activa el evento foco para iframe.contentWindow pero no para iframe.contentWindow.document. Chrome, por ejemplo, puede manejar ambos casos. entonces, solo necesitaba vincular mis manejadores de eventos a iframe.contentWindow para que las cosas funcionen. Quizás esto ayude a alguien ...

3

tuve un problema similar cuando estaba tratando de centrarme en un área de texto en un iframe cargado desde otra página. en la mayoría de los casos, funciona Hubo un problema por el cual se activaría en FF cuando se cargó el iFrame pero antes de que fuera visible. por lo que el foco nunca pareció estar configurado correctamente.

trabajé alrededor de este con una solución para simular la respuesta de Cheeming anterior

var iframeID = document.getElementById("modalIFrame"); 
//focus the IFRAME element 
$(iframeID).focus(); 
//use JQuery to find the control in the IFRAME and set focus 
$(iframeID).contents().find("#emailTxt").focus(); 
1

Aquí está el código para crear un iframe usando jQuery, lo añadirá al documento, sondear hasta que se carga, a continuación, centrarse ella. Esto es mejor que establecer un tiempo de espera arbitrario que puede funcionar o no dependiendo de cuánto tiempo tarde en cargarse el iframe.

var jqueryIframe = $('<iframe>', { 
    src: "http://example.com" 
}), 
focusWhenReady = function(){ 
    var iframe = jqueryIframe[0], 
    doc = iframe.contentDocument || iframe.contentWindow.document; 
    if (doc.readyState == "complete") { 
     iframe.contentWindow.focus(); 
    } else { 
     setTimeout(focusWhenReady, 100) 
    } 
} 
$(document).append(jqueryIframe); 
setTimeout(focusWhenReady, 10); 

El código para detectar cuando se carga el iframe fue adaptado de Biranchi 's respuesta a How to check if iframe is loaded or it has a content?

Cuestiones relacionadas