Вызов кода JavaScript в iframe с родительской страницы



в принципе, у меня есть iframe встроенный в страницу и iframe некоторые JavaScript процедуры, которые мне нужно вызвать с родительской страницы.



теперь наоборот довольно просто, как вам нужно только позвонить parent.functionName(), но, к сожалению, мне нужно именно наоборот.



обратите внимание, что моя проблема не меняется источник URL на iframe, но вызов функции, определенной в iframe.

667   17  

17 ответов:

предположим, что идентификатор вашего iFrame - это "targetFrame", а функция, которую вы хотите вызвать, -targetFunction():

document.getElementById('targetFrame').contentWindow.targetFunction();

вы также можете получить доступ к раме с помощью window.frames вместо document.getElementById.

// this option does not work in most of latest versions of chrome and Firefox
window.frames[0].frameElement.contentWindow.targetFunction(); 

есть некоторые особенности, чтобы быть в курсе здесь.

  1. HTMLIFrameElement.contentWindow вероятно, это более простой способ, но это не совсем стандартное свойство, и некоторые браузеры не поддерживают его, в основном более старые. Это связано с тем, что стандарт DOM Level 1 HTML ничего не говорит о

вызов функции JS из iframe возможно, но только когда и родитель и страница загружены в iframe из того же домена, т. е. abc.com, и оба используют один и тот же протокол, т. е. оба находятся либо на http:// или https://.

вызов не будет выполнен в следующих случаях:

  1. родительская страница и страница iframe находятся в разных доменах.
  2. они используют разные протоколы, один находится на http: / / а другой включен протокол https.//:

любой обходной путь к этому ограничению будет крайне небезопасным.

например, представьте, что я зарегистрировал домен superwinningcontest.com и разослал ссылки на электронные письма людей. Когда они загрузили главную страницу, Я мог скрыть несколько iframes там и читать их фид Facebook, проверить последние транзакции Amazon или PayPal, или-если они использовали сервис, который не реализовал достаточную безопасность-перевести деньги со своих счетов. Вот почему JavaScript ограничен тем же доменом и тем же протоколом.

в IFRAME сделайте свою функцию общедоступной для объекта window:

window.myFunction = function(args) {
   doStuff();
}

для доступа с родительской страницы, Используйте это:

var iframe = document.getElementById("iframeId");
iframe.contentWindow.myFunction(args);

Если iFrame и содержащий его документ находятся в другом домене, ранее опубликованные методы могут не работать, но есть решение:

var o = document.getElementsByTagName('iframe')[0];
o.contentWindow.postMessage('Hello world', 'http://b.example.org/');

, чтобы зарегистрировать обработчик событий для входящих событий, скрипт будет использовать addEventListener() (или аналогичные механизмы). Например, сценарий в документе B может выглядеть следующим образом:

window.addEventListener('message', receiver, false);
function receiver(e) {
  if (e.origin == 'http://example.com') {
    if (e.data == 'Hello world') {
      e.source.postMessage('Hello', e.origin);
    } else {
      alert(e.data);
    }
  }
}

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

через http://dev.w3.org/html5/postmsg/#web-messaging

просто для записи, я столкнулся с той же проблемой сегодня, но на этот раз страница была встроена в объект, а не iframe (так как это был документ XHTML 1.1). Вот как это работает с объектами:

document
  .getElementById('targetFrame')
  .contentDocument
  .defaultView
  .targetFunction();

(извините за уродливые разрывы строк, не вписался в одну строку)

IFRAME должен быть в frames[] коллекция. Используйте что-то вроде

frames['iframeid'].method();

Quirksmode был после этого.

так как страница теперь сломана и доступна только через archive.org, я воспроизвел его здесь:

IFrames

на этой странице Я даю краткий обзор доступа к iframes со страницы, на которой они находятся. Не удивительно, что есть некоторые соображения браузера.

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

кадр или объект?

основной вопрос заключается в том, рассматривается ли iframe как фрейм или как объект.

  • как объяснили на введение в рамки страницы, если вы используете фреймы браузер создает иерархию фреймов для вас (top.frames[1].frames[2] и так далее). Вписывается ли iframe в эту иерархию фреймов?
  • или браузер видит iframe как просто другой объект, объект, который имеет свойство src? В этом случае мы должны использовать стандартный DOM call (типа document.getElementById('theiframe')) чтобы получить к нему доступ. В общем случае браузеры разрешают оба представления на "реальных" (жестко закодированных) iframes, но созданные iframes не могут быть доступны как фреймы.

имя атрибут

самое главное правило-дать любой iframe, который вы создаете name атрибут, даже если вы также используете id.

<iframe src="iframe_page1.html"
    id="testiframe"
    name="testiframe"></iframe>

большинство браузеров нужны name атрибут, чтобы сделать iframe частью иерархии кадров. Некоторые браузеры (особенно Mozilla) нуждаются в id чтобы сделать iframe доступным в качестве объекта. Назначая атрибуты для элемента iframe, который вы держите свои варианты открытыми. Но name гораздо важнее, чем id.

открыть

либо вы получаете доступ к iframe как к объекту и меняете его src или вы получаете доступ к iframe в качестве кадра и изменить его location.href.

документ.getElementById ('iframe_id').src = ' newpage.HTML-код'; кадры['iframe_name'].местоположение.href = ' newpage.HTML-код'; Синтаксис фрейма немного предпочтительнее, потому что Opera 6 поддерживает его, но не синтаксис объекта.

доступ к iframe

поэтому для полного кросс-браузерного опыта вы должны дать iframe имя и использовать

frames['testiframe'].location.href

синтаксис. Насколько я знаю, это всегда работает.

доступ к документу

доступ к документу внутри iframe довольно прост, если вы используете . Подсчет количества ссылок в документе в iframe, делать frames['testiframe'].document.links.length.

генерируемые iframes

когда вы создаете iframe через W3C DOM iframe не сразу вводится в frames массив, хотя и frames['testiframe'].location.href синтаксис не будет работать сразу. Браузеру нужно немного времени, прежде чем iframe появится в массиве, время, в течение которого ни один скрипт не может работать.

The document.getElementById('testiframe').src синтаксис отлично работает во всех обстоятельства.

The target атрибут ссылки не работает ни с сгенерированными iframes, за исключением Opera, хотя я дал свой сгенерированный iframe как name и id.

отсутствие target поддержка означает, что вы должны использовать JavaScript для изменения содержимого сгенерированного iframe, но поскольку вам все равно нужен JavaScript, чтобы сгенерировать его в первую очередь, я не вижу в этом большой проблемы.

размер текста в фреймы

любопытный исследователь 6 только ошибка:

при изменении размера текста через меню Вид, размеры текста в iframes правильно изменены. Тем не менее, этот браузер не изменяет разрывы строк в исходном тексте, так что часть текста может стать невидимой, или разрывы строк могут произойти, пока строка все еще может содержать другое слово.

Я нашел довольно элегантное решение.

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

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

пример:

на родителя:

function tunnel(fn) {
    fn();
}

в iframe:

var myFunction = function() {
    alert("This work!");
}

parent.tunnel(myFunction);

когда iframe загружается, он будет вызывать parent.туннель (YourFunctionReference), который будет выполнять функцию, полученную в параметре.

это просто, без необходимости иметь дело со всеми нестандартными методами из различных браузеров.

некоторые из этих ответов не затрагивают проблему CORS или не делают очевидным, где вы размещаете фрагменты кода, чтобы сделать возможным общение.

вот конкретный пример. Скажем, я хочу нажать кнопку на родительской странице и сделать что-то внутри iframe. Вот как бы я это сделал.

parent_frame.HTML-код

<button id='parent_page_button' onclick='call_button_inside_frame()'></button>

function call_button_inside_frame() {
   document.getElementById('my_iframe').contentWindow.postMessage('foo','*');
}

iframe_page.HTML-код

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)
    {
      if(event) {
        click_button_inside_frame();
    }
}

function click_button_inside_frame() {
   document.getElementById('frame_button').click();
}

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

document.getElementById('my_iframe').contentWindow.postMessage('foo','*');

для этого:

window.parent.postMessage('foo','*')

продолжение JoelAnair это ответ:

для большей надежности используйте следующее:

var el = document.getElementById('targetFrame');

if(el.contentWindow)
{
   el.contentWindow.targetFunction();
}
else if(el.contentDocument)
{
   el.contentDocument.targetFunction();
}

работает как шарм :)

следуя ответу Нитина Бансала

и для еще большей надежности:

function getIframeWindow(iframe_object) {
  var doc;

  if (iframe_object.contentWindow) {
    return iframe_object.contentWindow;
  }

  if (iframe_object.window) {
    return iframe_object.window;
  } 

  if (!doc && iframe_object.contentDocument) {
    doc = iframe_object.contentDocument;
  } 

  if (!doc && iframe_object.document) {
    doc = iframe_object.document;
  }

  if (doc && doc.defaultView) {
   return doc.defaultView;
  }

  if (doc && doc.parentWindow) {
    return doc.parentWindow;
  }

  return undefined;
}

и

...
var el = document.getElementById('targetFrame');

getIframeWindow(el).targetFunction();
...
       $("#myframe").load(function() {
            alert("loaded");
        });

же самое, но немного легче будет!--3-->как обновить родительскую страницу со страницы в iframe. Просто вызовите функцию родительской страницы, чтобы вызвать функцию javascript для перезагрузки страницы:

window.location.reload();

или сделать это прямо со страницы в iframe:

window.parent.location.reload();

обе работы.

Если мы хотим вызвать функцию javascript родительской страницы из iframe, который генерируется из кодирования. ex shadowbox или lightbox

попробуйте просто parent.myfunction()

используйте following для вызова функции фрейма в родительской странице

parent.document.getElementById('frameid').contentWindow.somefunction()

Comments

    Ничего не найдено.