Как выставить IFrame DOM с помощью jQuery?

У меня есть прототип, представляющий конкретный IFrame. Этот прототип имеет функцию GoToUrl (...), которая открывает данный URL-адрес в IFrame.

Мой вопрос: как мне создать свойство InternalDOM и сделать это свойство ссылкой на объект "window" (корневой объект DOM) внутри IFrame? Таким образом: если мой IFrame предоставляет страницу с объектом X в этом объекте "window", который я мог бы сделать:

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

Любая помощь будет оценена.

PS: Я бы принял ответы, не обязательно связанные с jQuery, но я бы предпочел решение jQuery.

Ответ 1

Чтобы получить объект window для фрейма, вы можете использовать массив window.frames:

var iframewindow= frames['iframe_name'];

Это требует, чтобы вместо id атрибут <iframe> атрибут старой школы name вместо-или-как-хорошо был id. Альтернативно, если вы знаете порядок iframes на странице, вы можете их индексировать численно:

var iframewindow= frames[0];

Как правило, более гибко получать окно iframe из элемента iframe в DOM, но для этого требуется, чтобы код совместимости справлялся с IE:

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

jQuery определяет метод content() для захвата document node, но он не дает вам кросс-браузер путь от document до window, поэтому вы все еще придерживаетесь:

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

что на самом деле не является большой победой.

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

Ответ 2

Подводя итог

Доступ к содержимому iframe с родительской страницы

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

Доступ к родительской странице содержимого из iframe

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

Это применимо только в том случае, если родительская и страница iframe находятся в одном домене.

EDIT: пример загрузки дочерних iframes:

родительский html

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

родительский 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();
    });
});

Все основные браузеры, включая IE9, работают со строками on('load'). Только IE8/7 нуждается в блоке интервалов.

Ответ 3

UPDATE @RoyiNamir комментарий:

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

для окна в iframe.

frames["myIframeId"].window

для документа в iframe

frames["myIframeId"].window.document

для тела в iframe

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

для тела в iframe с jquery

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

ВАЖНО: вы всегда должны проверить, что документ со статусом "завершен" для работы с этим

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