Как выставить DOM IFrame, используя jQuery? - PullRequest
40 голосов
/ 31 октября 2009

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

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

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

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

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

Ответы [ 3 ]

67 голосов
/ 31 октября 2009

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

var iframewindow= frames['iframe_name'];

Для этого требуется, чтобы вы присвоили атрибуту <iframe> old-school name вместо "или-или-как-хорошо", как id. В качестве альтернативы, если вы знаете порядок размещения фреймов на странице, вы можете индексировать их численно:

var iframewindow= frames[0];

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

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

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

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

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

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

36 голосов
/ 09 августа 2012

Подводя итог

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

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

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

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

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

РЕДАКТИРОВАТЬ: Пример загрузки дочерних 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 нуждается в интервальном блоке.

8 голосов
/ 31 октября 2009

ОБНОВЛЕНИЕ Комментарий @RoyiNamir:

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

для окна в фрейме.

frames["myIframeId"].window

для документа в фрейме

frames["myIframeId"].window.document

для тела в фрейме

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...