web-dev-qa-db-fra.com

Définition du focus sur le contenu iframe

J'ai une page avec un document.onkeydown gestionnaire d'événements, et je le charge dans une iframe dans une autre page. Je dois cliquer à l'intérieur de l'iframe pour que la page de contenu commence à "écouter".

Existe-t-il un moyen d'utiliser JavaScript dans la page externe pour définir le focus sur la page interne afin de ne pas avoir à cliquer à l'intérieur de l'iframe?

EDIT: réponse au commentaire:

Le contexte est que la fenêtre principale est un système de type boîte à lumière, sauf qu'au lieu d'images, il affiche des iframes, et chaque iframe est une page interactive avec des gestionnaires keydown/mousemove. ces gestionnaires ne se déclenchent que lorsque je clique sur l'iframe après avoir montré la boîte à lumière.

Je ne cherche pas à "setFocus" dans le sens traditionnel autant qu'à "activer les gestionnaires d'événements sur l'iframe contentDocument"

40
Jimmy

J'ai eu un problème similaire avec jQuery Thickbox (un widget de dialogue de style lightbox). La façon dont j'ai résolu mon problème est la suivante:

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;
   });
});

Le code ne semble pas fonctionner sans setTimeout (). D'après mes tests, il fonctionne dans Firefox3.5, Safari4, Chrome4, IE7 et IE6.

55
cheeming

En utilisant la méthode contentWindow.focus (), le délai d'attente est probablement nécessaire pour attendre que l'iframe soit complètement chargé.

Pour moi, utiliser également l'attribut onload="this.contentWindow.focus()" fonctionne, avec Firefox, dans la balise iframe

18
danza
document.getElementsByName("iframe_name")[0].contentWindow.document.body.focus();
6
Jaime Febres

Essayez d'écouter les événements dans le document parent et de passer l'événement à un gestionnaire dans le document iframe.

4
Liam

j'ai eu un problème similaire où j'essayais de me concentrer sur une zone txt dans une iframe chargée à partir d'une autre page. dans la plupart des cas, cela fonctionne. Il y avait un problème où il se déclencherait dans FF lorsque l'iFrame était chargé mais avant qu'il ne soit visible. de sorte que la mise au point ne semblait jamais avoir été réglée correctement.

j'ai travaillé autour de cela avec une solution similaire à la réponse de cheeming ci-dessus

    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(); 
3
nate_weldon

Voici le code pour créer un iframe à l'aide de jQuery, l'ajouter au document, l'interroger jusqu'à ce qu'il soit chargé, puis le focaliser. C'est mieux que de définir un délai arbitraire qui peut ou non fonctionner en fonction du temps de chargement de l'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);

Le code pour détecter quand l'iframe est chargé a été adapté de la réponse de Biranchi à Comment vérifier si l'iframe est chargé ou s'il a un contenu?

1

J'ai découvert que FF déclenche l'événement focus pour iframe.contentWindow mais pas pour iframe.contentWindow.document. Chrome par exemple peut gérer les deux cas. Donc, j'avais juste besoin de lier mes gestionnaires d'événements à iframe.contentWindow afin de faire fonctionner les choses. Peut-être que cela aide quelqu'un ...

1
mile

C'est quelque chose qui a fonctionné pour moi, même si ça sent un peu 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. il défile également vers le bas du contenu. Je suppose que je devrais insérer la zone de texte factice en haut.

0
Jimmy