Доступ к содержимому iframe на странице на javascript

5 (100%) 4 vote[s]

Изменить содержание iframe (добавить стили, новые элементы, получать данные из формы и т.д.), можно двумя способами: используя свойство contentDocument, которое возвращает созданный элементом frame или iframe объект Document, или при помощи метода Window.postMessage().

Пример изменения фона страницы на red, открытой в iframe:

IFrame contentDocument

Политика безопасности браузеров запрещает доступ к содержимому документа из другого документа, если два документа не находятся в одном домене. Таким образом, можно манипулировать содержимым iframe, загруженным только с того же домена, что и родительская страница. Этот метод не будет работать, если вы попробуете открыть файл локально на компьютере, просто дважды по нему щелкнув ЛКМ. В общем, этот метод хорош для манипуляции с собственными фреймами на сайте.

IFrame contentDocument javascript

Вот пример кода на js — родительская страница:

<iframe id="myframe" src="iframe.html"></iframe>
<button id="btn" onclick="myFunction()">Добавить</button>
function myFunction() {
  var x = document.getElementById("myframe");
  var y = (x.contentWindow || x.contentDocument);
  if (y.document)y = y.document;
  var gg = y.getElementById("vid");
  y.head.innerHTML = "<style>body{background :red;border:4px solid green;}.ul{background:rgba(48, 120, 133,0.4);padding:15px;}.big{font-size:20px;}.small{font-size:14px;}</style>";
  gg.innerHTML = '<ul class="ul">Привет со страницы<li class="big">Очень большой привет</li><li class="small">Привет поменьше</li></ul>';
}
iframe.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h2>Фрейм</h2>
<div id="vid"></div>
</body>
</html>

Этот код в работе:

IFrame contentDocument jQuery

Для доступа к элементам iframe с jQuery используется метод .contents() для доступа ко всем непосредственным потомкам iframe. В отличие от метода .children(), .contents() включает текстовые узлы и узлы комментариев, а также элементы HTML.

Этот же пример, но на jQuery:

<iframe id="myframe" src="iframe.html"></iframe>
<button id="FD">Добавить</button>
$('#FD').on('click', function() {
    let iframeHead = $('#myframe').contents().find('head');
	let iframeText = $('#myframe').contents().find('body');
    let iframeCSS = '<style>body{background :red;border:4px solid green;}.ul{background:rgba(48, 120, 133,0.4);padding:15px;}.big{font-size:20px;}.small{font-size:14px;}</style>';
	let iframeTextContent = '<ul class="ul">Привет из окна<li class="big">Очень большой привет</li><li class="small">Привет поменьше</li></ul>';
    $(iframeHead).append(iframeCSS);
	$(iframeText).html(iframeTextContent);
});

Обратите внимание на способ вставки элемента: в примере с JS мы используем .innerHTML=, что заменит полностью содержимое блока. Для добавления стилей используйте .innerHTML+= (с плюсом). То же самое и с jQuery: метод .append добавляет, а .html заменяет содержимое блока.

Обмен данными между IFrame и страницей при помощи Window.postMessage()

Позволяет создавать кроссдоменные запросы.

Отправить данные из iframe в родительское окно:

window.parent.postMessage(message, '*');

Отправить данные из родительского окна в iframe:

frameElem.contentWindow.postMessage(message, '*');

Отправлять можно пакет данных, предварительно кодированных в json:

const message = JSON.stringify({
    message: '<style>.body{...}</style>',
    message2: '<p>Hello<?p>',
});
window.parent.postMessage(message, '*');

Получение сообщений при помощи слушателя событий:

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

Вот рабочий пример обмена сообщениями между родительской страницей и встроенным iframe:

Window

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#tmlPreviewPane, #tmlPreviewPane1 {
  position: relative;
  height: 50vh;
  overflow: auto;
  width:60%;
  margin-left:20%;
   border:1px solid grey;
}
#tmlPreviewPane iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-width: 0;
  outline-width: 0;
}
.FD {display: block;background:#0b3f93;border:1px solid #0b3f93;border-radius:3px;box-shadow:0 0 5px rgba(0,0,0,0.4);padding:5px;text-align:center;color:white;margin-top:8px;margin-left:auto;margin-right:auto;}
#message {margin:15px;}
</style>
</head>
<body>
<div id="tmlPreviewPane">
  <iframe id="frame" src="iframe.html" ></iframe>
</div>
    <div id="tmlPreviewPane1">
        <h2>Window</h2>
        <button id="sendToIframe" type="button" class="FD">Send to iframe</button>
        <div id="message"></div>
    </div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const messageElem = document.getElementsByTagName('head')[0];
	 const textElem = document.getElementById('message');
    const frameElem = document.getElementById('frame');
    window.addEventListener('message', function(e) {
        const data = JSON.parse(e.data);               
        messageElem.innerHTML += `${data.message}`;
		 textElem.innerHTML = `${data.message1}`;
    });
    document.getElementById('sendToIframe').addEventListener('click', function() {
        const message = JSON.stringify({
            message: '<style>body{background:blue;border:4px solid green;}.ul{background:rgba(48, 120, 133,0.4);padding:15px;}.big{font-size:20px;}.small{font-size:14px;}#inn{color:#910e2a;font-weight:bold;font-size:22px;}</style>',
			message1: '<ul class="ul">Привет из <span id="inn">DIV</span><li class="big">Очень большой привет</li><li class="small">Привет поменьше</li></ul>',          
        });
        frameElem.contentWindow.postMessage(message, '*');
    });
});
</script>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html>
<html lang="ru">
<head>
    <meta charset="UTF-8"> 
<style>   
.FD {display: block;background:#0b3f93;border:1px solid #0b3f93;border-radius:3px;box-shadow:0 0 5px rgba(0,0,0,0.4);padding:5px;text-align:center;color:white;margin-top:8px;margin-left:auto;margin-right:auto;}
#message {margin:15px;}
</style>
</head>
<body>
	 <div>
        <h2>Iframe</h2>
        <button type="button" class="FD" id="sendToWindow">Send to window</button>
        <div id="message"></div>
    </div>
<script>
document.addEventListener('DOMContentLoaded', function() {
    const messageElem = document.getElementsByTagName('head')[0];
	const textElem = document.getElementById('message');

    window.addEventListener('message', function(e) {
        const data = JSON.parse(e.data);
              
        messageElem.innerHTML += `${data.message}`;
		 textElem.innerHTML = `${data.message1}`;
    });
    document.getElementById('sendToWindow').addEventListener('click', function() {
        const message = JSON.stringify({
            message: '<style>#tmlPreviewPane1{background:#910e2a; border:4px solid green;}.ul{background:rgba(48, 120, 133,0.4);padding:15px;}.big{font-size:20px;}.small{font-size:14px;}#inn{color:#0054fc;font-weight:bold;font-size:22px;}</style>',
			message1: '<ul class="ul">Привет из <span id="inn">iframe</span><li class="big">Очень большой привет</li><li class="small">Привет поменьше</li></ul>',            
        });
        window.parent.postMessage(message, '*');
    });
});
</script>
</body>
</html>

Безопасность

Чтобы получать сообщения только из проверенного источника, его нужно указать в строке window.parent.postMessage(message, ‘*’), где вместо ‘*’ указываем имя домена, например, ‘https://www.babulya.com.ua/’ или для локального сервера ‘http://localhost/’. Также можно использовать обработчик, проверяющий источник, отбрасывающий все сообщение из источников, отличных от заданного:

window.addEventListener("message", function(event) {
  if (event.origin != 'http://exemple.com/') {
    return;
  }
});

Читайте больше по теме:

Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments
Просмотры: 368

Популярные записи