Запишите элементы в дочерний iframe, используя Javascript или jQuery.

У меня есть что-то вроде этого:

<!doctype html>
<html>
  <body>
     <iframe id="someFrame"></iframe>
  </body>
</html>

И я хотел бы использовать jQuery для написания элементов таким образом, чтобы полный эквивалент HTML был бы таким:

<!doctype html>
<html>
  <body>
    <iframe id="someFrame">
      <!-- inside the iframe's content -->
      <!-- <html><body>  -->
      <div>A</div>
      <div>B</div>
      <div>C</div>
      <!-- </body></html> -->
    </iframe>
  </body>
</html>

В качестве альтернативы подойдет любой старый-добрый Javascript.

Спасибо.

Редактировать. После небольшого исследования я ищу IE-эквивалент свойства contentDocument iframe. contentDocument — это стандарт W3C, который поддерживает FF, а IE — нет. (Сюрприз Сюрприз)


person Jeff Meatball Yang    schedule 15.06.2009    source источник


Ответы (5)


Вы можете сделать и то, и другое, вам просто нужно настроить таргетинг по-разному:

var ifrm = document.getElementById('myIframe');
ifrm = ifrm.contentWindow || ifrm.contentDocument.document || ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write('Hello World!');
ifrm.document.close();
person Mike Robinson    schedule 15.06.2009
comment
ага - окно содержимого. Я действительно обнаружил, что открытие и закрытие необходимы, чтобы начать использовать jquery... - person Jeff Meatball Yang; 16.06.2009
comment
этот метод больше не работает. Я получаю сообщение об ошибке js, в котором говорится, что небезопасный JavaScript пытается получить доступ к фрейму с URL-адресом URL1 из фрейма с URL-адресом URL2. Домены, протоколы и порты должны совпадать. Мостовой подход, приведенный ниже, работает нормально. - person kay am see; 26.08.2012
comment
Я знаю, что это старая тема, но в каком случае у вас когда-нибудь будет ifrm.contentDocument.document.document? - person ars265; 18.09.2013
comment
Почему нельзя писать прямо в тело iframe, а только с помощью этого хака? - person Kiechlus; 24.01.2018
comment
без оператора close() все последующие JS не выполняются, поэтому имеет смысл использовать блок try finally. благодаря. этот ответ помог мне понять, что не так с моей страницей - person user2932688; 23.03.2018

После некоторых исследований и подтверждающего ответа Майка я обнаружил, что это решение:

  var d = $("#someFrame")[0].contentWindow.document; // contentWindow works in IE7 and FF
  d.open(); d.close(); // must open and close document object to start using it!

  // now start doing normal jQuery:
  $("body", d).append("<div>A</div><div>B</div><div>C</div>");
person Jeff Meatball Yang    schedule 15.06.2009
comment
Интересный. Вы знаете, почему вы должны делать открытие и закрытие? - person Nosredna; 16.06.2009
comment
Это было прекрасно! Спасибо Джефф! - person Metropolis; 17.09.2013
comment
Это идеальное решение моей проблемы с codemirrors editor.getValue()! - person hannacreed; 09.08.2019

Есть два надежных метода доступа к элементу document внутри iframe:

1. Свойство window.frames:

var iframeDocument = window.frames['iframeName'].document; // or // var iframeDocument = window.frames[iframeIndex].document;

Демо


2. Свойство contentDocument:

var iframeDocument = document.getElementById('iframeID').contentDocument; // or // var iframeDocument = document.getElementById('iframeID').contentWindow.document;

Демо

person Mori    schedule 13.01.2014
comment
Отлично, JSFiddle был очень полезен. Спасибо! - person dotancohen; 04.12.2014

Я иду на риск и предполагаю, что ответы, предложенные до сих пор, невозможны.

Если этот iframe на самом деле имеет src=somepage.html (который вы должны были указать, а если нет, то какой смысл использовать iframe?), то я не думаю, что Jquery может напрямую манипулировать html через фреймы во всех браузерах. Основываясь на моем опыте работы с подобными вещами, содержащая страница не может напрямую вызывать функции или устанавливать какой-либо контакт Javascript со страницей iframe.

Ваш somepage.html (страница, которая загружается в iframe) должен делать две вещи:

  1. Передайте какой-либо объект на содержащую страницу, которую можно использовать в качестве моста
  2. Есть функция для установки HTML по вашему желанию

Так, например, somepage.html может выглядеть так:

<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
    var bridge={
        setHtml:function(htm) {
            document.body.innerHTML=htm;
        }
    }

    $(function() { parent.setBridge(bridge); });

//--></script>
</head>
<body></body>
</html>

и содержащая страница может выглядеть так:

<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge;
var setBridge=function(br) {
    bridge=br;
    bridge.setHtml("<div>A</div><div>B</div><div>C</div>");
    }
//-->
</script>
</head>
<body><iframe src="somepage.html"></iframe></body>
</html>

Это может показаться немного запутанным, но его можно адаптировать в нескольких направлениях и оно должно работать как минимум в IE, FF, Chrome и, возможно, в Safari и Opera...

person jwl    schedule 15.06.2009
comment
Спасибо за ваш ответ, но я хочу использовать этот iframe для создания HTML, как редактор форматированного текста. Я не устанавливаю атрибут src, так как он будет очищен и перекомпонован из верхнего окна. Кроме того, я думаю, что должна быть возможность добраться до DOM ребенка - см. Мое редактирование в OP. - person Jeff Meatball Yang; 16.06.2009
comment
Есть ли причина, по которой вам нужно использовать iframe, а не div? кажется, что div будет проще и с меньшей вероятностью сломается в браузерах. - person Jeremy Wall; 16.06.2009
comment
Оказывается, есть причина. Вам нужно разместить внешний javascript и не хотите, чтобы он повредил вашу страницу. Но вам также нужен реферер, соответствующий вашему домену верхнего уровня. Это наиболее распространенный способ размещения рекламы на странице: ‹iframe›‹/iframe› + document.write('‹сюда идут теги script›') - person KateYoak; 10.12.2015

Я обнаружил, что это совместимо с несколькими браузерами ... небольшое пересечение предыдущих ответов и немного собственных проб и ошибок. :)

Я использую это для загрузки отчета или, если возникает ошибка (сообщение), оно отображается в iFrame. У большинства пользователей, вероятно, будет скрыт iFrame, я использую его многофункционально.

Дело в том, что мне приходится очищать содержимое iFrame каждый раз, когда я нажимаю кнопку загрузки отчета - пользователь может изменить параметры, и бывает, что нет результатов, которые затем отображаются в iFrame в виде сообщения. Если есть есть результаты, iFrame остается пустым, потому что приведенный ниже код очистил его, а метод window.open(...) создает документ Content-Disposition: attachment;filename=....

var $frm = $("#reportIFrame");
var $doc = $frm[0].contentWindow ? $frm[0].contentWindow.document : $frm[0].contentDocument;
var $body = $($doc.body);
$body.html(''); // clear iFrame contents <- I'm using this...
$body.append('<i>Writing into the iFrame...</i>'); // use this to write something into the iFrame
window.open(Module.PATH + 'php/getReport.php' + Report.queryData, 'reportIFrame');

У меня нет браузера, поддерживающего contentDocument, но я закодировал его таким образом, поэтому я его оставляю. Может быть, у кого-то есть более старые браузеры, и он может опубликовать подтверждение/проблемы совместимости?

person damijank    schedule 14.04.2014