web-dev-qa-db-fra.com

Comment exposer le DOM d'IFrame en utilisant jQuery?

J'ai un prototype représentant un IFrame particulier. Ce prototype a une fonction appelée GoToUrl (...) qui ouvre l'URL donnée dans l'IFrame.

Ma question est: comment créer une propriété "InternalDOM" et faire en sorte que cette propriété se réfère à l'objet "window" (l'objet DOM racine) de l'IFrame à l'intérieur? De telle façon que: Si mon IFrame expose une page qui a un objet X dans son objet "window" je pourrais faire:

MyFrameObject.GoToUrl(pageXurl);
MyFrameObject.InternalDOM.X

Toute aide serait appréciée.

PS: j'accepterais des réponses pas forcément liées à jQuery mais je préférerais une solution jQuery.

40
André Pena

Pour obtenir l'objet window pour un cadre, vous pouvez utiliser le window.frames tableau:

var iframewindow= frames['iframe_name'];

Cela nécessite que vous donniez le <iframe> un attribut name à l'ancienne au lieu de ou aussi bien que le id. Alternativement, si vous connaissez l'ordre des iframes sur la page, vous pouvez les indexer numériquement:

var iframewindow= frames[0];

Il est généralement plus flexible d'obtenir la fenêtre iframe à partir de l'élément iframe dans le DOM, mais cela nécessite du code de compatibilité pour faire face à IE:

var iframe= document.getElementById('iframe_id');
var iframewindow= iframe.contentWindow? iframe.contentWindow : iframe.contentDocument.defaultView;

jQuery définit la méthode contents () pour saisir le nœud document, mais il ne vous donne pas un moyen multi-navigateur pour passer du document au window, vous êtes donc toujours coincé avec:

var iframe= $('#iframe_id')[0];
var iframewindow= iframe.contentWindow? iframe.contentWindow : iframe.contentDocument.defaultView;

ce qui n'est pas vraiment une grosse victoire.

(Remarque: soyez très prudent lorsque vous utilisez jQuery pour l'écriture d'images croisées. Chaque image a besoin de sa propre copie de jQuery et les méthodes de la copie d'une image ne fonctionneront pas nécessairement sur les nœuds de l'autre. L'écriture d'images croisées est un sujet chargé de pièges.)

67
bobince

Résumer

Accéder au contenu iframe à partir de la page parent

var iframe = $('iframe').contents(); // iframe.find('..') ...

Accéder au contenu de la page parent depuis iframe

var parent = $(window.parent.document); // parent.find('..') ...

Cela s'applique uniquement lorsque le parent et les pages iframe sont sur le même domaine.

EDIT: Exemple de chargement des iframes enfants:

parent html

<iframe id="iframe1" src="iframe1.html"></iframe>
<iframe id="iframe2" src="iframe2.html"></iframe>

parent js

$(function () {
    var iframe1 = null,
        iframe2 = null;

    // IE8/7
    var frameInterval = window.setInterval(function () {
        iframe1 = $('#iframe1').contents();
        iframe2 = $('#iframe2').contents();
        if ($('head', iframe1).length && $('head', iframe2).length) {
            window.clearInterval(frameInterval);
        }
    }, 100);

    // on iframe loaded
    $('#iframe1').on('load', function (e) {
        iframe1 = $('#iframe1').contents();
    });
    $('#iframe2').on('load', function (e) {
        iframe2 = $('#iframe2').contents();
    });
});

Tous les principaux navigateurs, y compris IE9, fonctionnent avec les lignes on('load'). Seul IE8/7 a besoin du bloc d'intervalle.

36
simo

MISE À JOUR du commentaire de @RoyiNamir:

var frames = window.frames || window.document.frames;

pour une fenêtre dans un iframe.

frames["myIframeId"].window

pour un document dans un iframe

frames["myIframeId"].window.document

pour le corps dans un iframe

frames["myIframeId"].window.document.body

pour le corps dans un iframe avec jquery

var iframeBody = $(frames["myIframeId"].window.document).contents().find("body");

IMPORTANT: vous devez toujours vérifier que le document a le statut "terminé" pour travailler avec ce

if (frames["myIframeId"].window.document.readyState=="complete")
{
   //ok
}
else
{
   //perform a recursive call until it is complete
}
8
andres descalzo