J'utilise le code suivant pour créer dynamiquement un iframe.
var iframe_jquery = $("<iframe>")
.addClass("foo")
.appendTo(container); // container is a jQuery object containing a <div> which already exists
Ensuite, je veux accéder à son contentWindow, mais c'est nul:
var iframe = iframe_jquery.get(0);
if (iframe){ // iFrame exists
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
}
Alors j'ai pensé: "Peut-être que l'iframe n'est pas encore prêt?" J'ai donc essayé:
iframe_jquery.ready(function(){
var iframe = iframe_jquery.get(0);
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
});
Même résultat.
Qu'est-ce qui ne va pas?
J'ai eu ce problème la semaine dernière en jouant avec des iFrames (construction d'un éditeur rtf), et oui ce n'est pas encore prêt.
Je pensais que si je le mettais dans une .ready()
ça marcherait, mais .ready()
c'est quand le DOM est prêt, pas quand l'iFrame a chargé son contenu, donc j'ai fini par envelopper mon code avec jQuery .load()
.
Essayez donc ceci:
$(function () {
$("#myiframe").load(function () {
frames["myframe"].document.body.innerHTML = htmlValue;
});
});
J'espère que cela t'aides
Le problème est que votre <iframe>
ne sera pas "réel" tant qu'il ne sera pas vraiment ajouté au DOM réel de la page. Voici un violon à démontrer. .
Selon le navigateur, accéder à document
ou à <iframe>
peut varier.
Voici un exemple de la façon de le gérer:
if (iframe.contentDocument) // FF Chrome
doc = iframe.contentDocument;
else if ( iframe.contentWindow ) // IE
doc = iframe.contentWindow.document;
Par simple curiosité, j'ai pensé que j'allais mettre ça ensemble. Se souvenir que les iframes et les événements de chargement ne fonctionnent pas bien ensemble sur différents navigateurs (principalement les plus anciens, en train de s'effondrer, les navigateurs devraient être morts) ... en plus de ne pas être entièrement sûr de la façon dont jQuery contourne ce problème ... mon cerveau a décidé que ce serait mieux pris en charge (que ce soit ou non n'est ni ici ni là):
$(function(){
/// bind a listener for the bespoke iframeload event
$(window).bind('iframeload', function(){
/// access the contents of the iframe using jQuery notation
iframe.show().contents().find('body').html('hello');
});
/// create your iframe
var iframe = $('<iframe />')
/// by forcing our iframe to evaluate javascript in the path, we know when it's ready
.attr('src', 'javascript:(function(){try{p=window.parent;p.jQuery(p).trigger(\'iframeload\');}catch(ee){};})();')
/// insert the iframe into the live DOM
.appendTo('body');
});
La raison de cette approche est qu'il est généralement préférable de déclencher votre événement de chargement depuis l'iframe lui-même. Mais cela signifie avoir un bon document chargé dans l'iframe, donc pour les iframes dynamiques, c'est un peu fastidieux. C'est une sorte de mélange entre le chargement d'un document et non.
Ce qui précède fonctionne sur tout ce que j'ai testé jusqu'à présent - et oui, vous avez raison - c'est un peu ridicule, non pérenne et probablement d'autres choses qui ont des connotations négatives;)
Une chose positive que je dirai à propos de cet article est qu'il introduit l'utilisation de .contents()
pour accéder au document de l'iframe, ce qui est au moins un peu utile ...
Vous pouvez également créer une fonction qui sera exécutée lorsque l'iframe aura fini de se charger en définissant son attribut onload.