Содержание
Изменить содержание 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
<!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>
<!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; } });
Читайте больше по теме: