javascript - create - ¿Por qué iframe.contentWindow== null?
javascript iframe contentwindow (6)
Uso el siguiente código para crear dinámicamente un iframe.
var iframe_jquery = $("<iframe>")
.addClass("foo")
.appendTo(container); // container is a jQuery object containing a <div> which already exists
Entonces, quiero acceder a su contentWindow, pero es nulo:
var iframe = iframe_jquery.get(0);
if (iframe){ // iFrame exists
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
}
Entonces pensé: "¿Quizás el iframe aún no está listo?" Así que lo intenté:
iframe_jquery.ready(function(){
var iframe = iframe_jquery.get(0);
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
});
Mismo resultado.
¿Qué pasa?
Versión de Bookmarklet
Solo por curiosidad, pensé en unir esto. Recordando que los iframes y los eventos de carga no funcionan bien juntos en diferentes navegadores (principalmente navegadores antiguos, cayendo a pedazos, que deberían estar muertos) ... además de no estar completamente seguros de cómo jQuery soluciona este problema ... mi cerebro decidió que esto estaría mejor respaldado (ya sea que esté o no esté ni aquí ni allá) :
$(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 razón para tomar este enfoque es que normalmente es mucho mejor desencadenar su evento de carga desde el propio iframe. Pero esto significa tener un documento apropiado cargado en el iframe, por lo que para iframes dinámicos esto es un poco tedioso. Esto es una especie de mezcla entre tener un documento cargado, y no.
Lo anterior funciona en todo lo que he probado hasta ahora - y sí, estás en lo cierto - es un poco ridículo, no apto para el futuro y, de manera probible, otras cosas que tienen connotaciones negativas;)
Una cosa positiva que diré sobre esta publicación es que introduce el uso de .contents()
para acceder al documento del iframe, que al menos es un poco útil ...
Dependiendo del navegador, el acceso al document
o un <iframe>
puede variar.
Aquí hay un ejemplo de cómo manejarlo:
if (iframe.contentDocument) // FF Chrome
doc = iframe.contentDocument;
else if ( iframe.contentWindow ) // IE
doc = iframe.contentWindow.document;
El problema es que su <iframe>
no será "real" hasta que realmente se agregue al DOM real de la página. Aquí hay un violín para demostrar. .
También puede realizar una función que se ejecutará cuando el iframe haya terminado de cargar configurando su atributo onload.
Tuve este problema la semana pasada mientras jugaba con iFrames (construyendo un editor rtf), y sí, aún no está listo.
Pensé que si lo colocaba en .ready()
funcionaría, pero .ready()
es cuando el DOM está listo, no cuando el iFrame ha cargado sus contenidos, así que terminé envolviendo mi código con jQuery .load()
.
Entonces intente esto:
$(function () {
$("#myiframe").load(function () {
frames["myframe"].document.body.innerHTML = htmlValue;
});
});
Espero que esto ayude
Tuve una situación similar en la que contentWindow
sería nulo (aproximadamente el 50% del tiempo inmediatamente después de cargar el documento), pero quería establecer el src del iframe a través de element.contentWindow.location.replace
.
Para resolverlo, hice un bucle que espera que contentWindow
no sea nulo ... así:
function setIframeLocation(element, value) {
if (element.contentWindow !== null) {
element.contentWindow.location.replace(value);
}
else {
setTimeout(setIframeLocation.bind(this, element, value), 100);
}
}
setIframeLocation(element, ''http://google.com'');