Как выставить 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
}