2009-06-01 3 views
142

Ну, у меня есть IFrame, который вызывает одну и ту же страницу домена. Моя проблема в том, что я хочу получить доступ к некоторой информации из этого родительского iframe с этой вызываемой страницы (из JavaScript). Как я могу получить доступ к этому iframe?Как получить доступ к родительскому iframe из JavaScript

Подробности: Есть несколько IFRAME, как этот, который может иметь одну и ту же страницу, потому что я программирую среду Windows. Я намерен закрыть этот Iframe, поэтому мне нужно знать, что я должен закрыть изнутри. У меня есть массив, содержащий ссылки на эти фреймы.

EDIT: Там плавающие фреймы генерируются динамически

+0

даже если плавающие фреймы генерируются динамически, вы можете присвоить новый уникальный идентификатор, используя какой-то счетчик, в конце концов, вам не нужно знать ID, но вы можете поиск легко, см. мой ответ. –

ответ

13

вы можете использовать parent для доступа к родительской странице. Таким образом, чтобы получить доступ к функции было бы:

var obj = parent.getElementById('foo'); 
+1

Кевин, проблема в том, чтобы ЗНАТЬ идентификатор. У меня есть несколько IFrames, и я хочу получить к ним доступ из кода внутри –

3

Попробуйте это в вашем родительском фрейме настройки вы IFrames, как это:

<iframe id="frame1" src="inner.html#frame1"></iframe> 
<iframe id="frame2" src="inner.html#frame2"></iframe> 
<iframe id="frame3" src="inner.html#frame3"></iframe> 

Обратите внимание, что идентификатор каждого кадра передается в качестве якоря в src.

то в вашем внутреннем HTML вы можете получить доступ к идентификатору кадра он будет загружен в через location.hash:

<button onclick="alert('I am frame: ' + location.hash.substr(1))">Who Am I?</button> 

, то вы можете получить доступ к parent.document.getElementById(), чтобы получить доступ к IFrame тега внутри фрейма

+0

Да, это было бы самым логичным решением, но иногда мне нужно изменить src iframe .. и передать этот хеш или параметр GET, каждый запрос не хорошо .. –

+0

почему это плохо, чтобы передать хэш каждый раз? Он виден только браузеру, а не серверу, и он не влияет на кеширование, как параметр get. –

+0

, но я должен был бы возражать против этого в каждом запросе. –

118

Также вы можете задать имя и идентификатор равных значений

<iframe id="frame1" name="frame1" src="any.html"></iframe> 

так что вы будете иметь возможность использовать следующий код внутри детской страницы

parent.document.getElementById(window.name); 
+14

Возможно, это не очевидно для всех, но с помощью этого метода вы можете получить доступ к объекту библиотеки родителя (только если родитель уже загрузил библиотеку). Пример: доступ к jQuery с родителем. $ ('# Something') – Zsolti

+1

Это решение совместимо с режимом совместимости IE5 +. – Slayner

+2

Водный, ваш ответ 2009 года все еще помогал мне. Thnx – 2016-08-08 14:17:32

28

Старый вопрос, но у меня была эта же проблема и нашла способ получить iframe. Это просто вопрос итерации через массив frames [parent frames] родительского окна и тестирование содержимого contentWindow каждого кадра в окне, в котором работает ваш код. Пример:

var arrFrames = parent.document.getElementsByTagName("IFRAME"); 
for (var i = 0; i < arrFrames.length; i++) { 
    if (arrFrames[i].contentWindow === window) alert("yay!"); 
} 

Или, с помощью JQuery:

parent.$("iframe").each(function(iel, el) { 
    if(el.contentWindow === window) alert("got it"); 
}); 

Этот метод сохраняет присвоив идентификатор для каждого фрейма, который хорош в вашем случае, поскольку они создаются динамически. Я не мог найти более прямой путь, так как вы не можете получить элемент iframe с помощью window.parent - он идет прямо к элементу родительского окна (пропуская iframe). Таким образом, цикл через них кажется единственным способом, если вы не хотите использовать идентификаторы.

+1

Обновление: это не работает точно так, как было объявлено, и мне пришлось использовать contentWindow.document === document. Не знаю, почему. Также в некоторых браузерах я использовал contentDocument. Ну, мне это нравится! – Christophe

+1

Извинения, по общему признанию, я только тестировал его в Firefox. :) Однако у меня был успех с использованием метода jQuery и contentWindow в нескольких браузерах. –

+1

Обновление: я узнал, что вы также можете использовать window.frameElement, но я не уверен, какие браузеры его поддерживают. – Christophe

5

Может просто использовать

window.parent 

в ваш IFRAME, чтобы получить вызывной кадр/окно. Если у вас было несколько кадр вызова, вы можете использовать

window.top 
-1
// just in case some one is searching for a solution 
function get_parent_frame_dom_element(win) 
{ 
    win = (win || window); 
    var parentJQuery = window.parent.jQuery; 
    var ifrms = parentJQuery("iframe.upload_iframe"); 
    for (var i = 0; i < ifrms.length; i++) 
    { 
     if (ifrms[i].contentDocument === win.document) 
      return ifrms[i]; 
    } 
    return null; 
} 
+3

Возможно, объясните свой код немного больше? – cereallarceny

73

Просто позвоните window.frameElement из вашей обрамлении страницы. Если страница отсутствует в рамке, то frameElement будет null.

Другой способ (получение элемента окна внутри фрейма менее тривиально), но для полноты картины:

/** 
* @param f, iframe or frame element 
* @return Window object inside the given frame 
* @effect will append f to document.body if f not yet part of the DOM 
* @see Window.frameElement 
* @usage myFrame.document = getFramedWindow(myFrame).document; 
*/ 
function getFramedWindow(f) 
{ 
    if(f.parentNode == null) 
     f = document.body.appendChild(f); 
    var w = (f.contentWindow || f.contentDocument); 
    if(w && w.nodeType && w.nodeType==9) 
     w = (w.defaultView || w.parentWindow); 
    return w; 
} 
+2

Спасибо! Работает на IE 6+, FF и Chrome! – rustyx

+1

'window.frameElement' возвращает' null', когда окно и iframe имеют разные домены, то есть перекрестные сообщения. – Qwerty

9

После того, как идентификатор фрейма установлен, вы можете получить доступ к IFRAME из внутреннего документа, как показано ниже.

var iframe = parent.document.getElementById(frameElement.id); 

Хорошо работает в IE, Chrome и FF.

+0

Это кажется запутанным способом выполнения 'var iframe = frameElement' – Oriol

+0

frameElement возвращает объект в контексте текущего окна, но parent.document.getElementById (frameElement.id) возвращает объект в контексте родительского окна, вы не можете запускать функции javascript родительского окна с помощью frameElement, попробовать его в jsfiddle и дать мне и пример, если сможете. –

+1

http://jsfiddle.net/pfwcnjev/ – Oriol

64

Я бы рекомендовал использовать postMessage API.

В вашем IFRAME, звоните:

window.parent.postMessage({message: 'Hello world'}, 'http://localhost/'); 

На странице вы включая IFRAME вы можете прослушивать события, как это:

window.addEventListener('message', function(event) { 
     if(event.origin === 'http://localhost/') 
     { 
     alert('Received message: ' + event.data.message); 
     } 
     else 
     { 
     alert('Origin not allowed!'); 
     } 

    }, false); 

Кстати, это также возможно делать вызовы в другие окна, а не только iframes.

Подробнее о PostMessage API на Джона Resigs блоге here

+5

Я думаю, что это, безусловно, лучший ответ, содержимое '