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.
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.)
var iframe = $('iframe').contents(); // iframe.find('..') ...
var parent = $(window.parent.document); // parent.find('..') ...
Cela s'applique uniquement lorsque le parent et les pages iframe sont sur le même domaine.
<iframe id="iframe1" src="iframe1.html"></iframe>
<iframe id="iframe2" src="iframe2.html"></iframe>
$(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.
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
}