Подтвердить что ты не робот

Почему iframe.contentWindow == null?

Я использую следующий код для динамического создания iframe.

var iframe_jquery = $("<iframe>")
    .addClass("foo")
    .appendTo(container); // container is a jQuery object containing a <div> which already exists

Затем я хочу получить доступ к его контенту contentWindow, но он null:

var iframe = iframe_jquery.get(0);
if (iframe){ // iFrame exists
    console.log(iframe.contentWindow); // Prints "null"
    var doc = iframe.contentWindow.document; // NullpointerException
}

Поэтому я подумал: "Может быть, iframe еще не готов?" Поэтому я попробовал:

iframe_jquery.ready(function(){
    var iframe = iframe_jquery.get(0);
    console.log(iframe.contentWindow); // Prints "null"
    var doc = iframe.contentWindow.document; // NullpointerException
});

Тот же результат.

Что не так?

4b9b3361

Ответ 1

У меня была эта проблема на прошлой неделе во время игры с iFrames (создание редактора rtf), и да, он еще не готов.

Я думал, что если бы я поместил его в .ready(), это сработало бы, но .ready() будет, когда DOM будет готов, а не когда iFrame загрузит его содержимое, поэтому я закончил перенос моего кода с помощью jQuery .load().

Итак, попробуйте следующее:

$(function () {  
    $("#myiframe").load(function () {                        
        frames["myframe"].document.body.innerHTML = htmlValue;
    });
}); 

Надеюсь, что это поможет

Ответ 3

В зависимости от браузера доступ к document или <iframe> может отличаться.

Вот пример того, как с ним обращаться:

if (iframe.contentDocument) // FF Chrome
  doc = iframe.contentDocument;
else if ( iframe.contentWindow ) // IE
  doc = iframe.contentWindow.document;

Ответ 4

Версия прокладок

Просто из любопытства я подумал, что соединить это. Помня, что события iframes и load не хорошо сочетаются друг с другом в разных браузерах (в основном старше, разваливаются, должны быть мертвые браузеры)... плюс не совсем уверен, как jQuery обошел эту проблему... мой мозг решил, что это было бы лучше поддержано (независимо от того, есть оно или нет ни здесь, ни там):

$(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 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');
});

Причиной такого подхода является то, что обычно лучше запускать событие загрузки из самого iframe. Но это означает наличие надлежащего документа, загруженного в iframe, поэтому для динамических фреймов это немного утомительно. Это своего рода смесь между документом, загруженным, а не.

Вышеизложенное работает над всем, что я тестировал до сих пор, и да, вы правы - это немного смехотворные, не относящиеся к будущему и поддерживающие другие вещи, имеющие отрицательные коннотации;)

Одна положительная вещь, которую я скажу об этом сообщении, - это использование .contents() для доступа к документу iframe, который хотя бы немного полезен...

Ответ 5

У меня была аналогичная ситуация, когда contentWindow был пустым (около 50% времени сразу после загрузки документа), но я хотел установить iframe src через element.contentWindow.location.replace.

Чтобы решить эту проблему, я сделал цикл, ожидающий, что contentWindow не будет иметь нуль... например:

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

Ответ 6

Вы также можете создать функцию, которая будет выполняться, когда iframe завершит загрузку, установив атрибут onload.