У меня есть простая страница с несколькими разделами iframe (для отображения RSS-ссылок). Как я могу применить тот же формат CSS с главной страницы к странице, отображаемой в iframe?
gawpertron, просто чтобы прояснить, вы говорите, что если я использую содержимое iFrame из какого-то другого домена, который я не контролирую, у меня нет возможности контролировать CSS для этого содержимого?
Можете ли вы указать ссылку на страницу, чтобы мы могли просто просмотреть наши изменения.
Домен, порт и протокол должны быть одинаковыми, с поддоменами тоже не работает.






Iframe универсально обрабатывается большинством браузеров как другая HTML-страница. Если вы хотите применить ту же таблицу стилей к содержимому iframe, просто укажите на нее ссылки со страниц, которые там используются.
@hangry, но ... как?
Включение файла CSS снова в iframe
Если вы управляете страницей в iframe, как сказал Хэппи, самый простой подход - создать общий файл CSS с общими стилями, а затем просто связать его со своими HTML-страницами.
В противном случае маловероятно, что вы сможете динамически изменять стиль страницы с внешней страницы в вашем iframe. Это связано с тем, что браузеры ужесточили безопасность кросс-фрейм-сценариев из-за возможного неправильного использования для спуфинга и других взломов.
Этот учебник может предоставить вам дополнительную информацию о скриптах iframe в целом. О кросс-фреймовом скриптинге объясняет ограничения безопасности с точки зрения IE.
Если содержимое iframe не полностью находится под вашим контролем или вы хотите получить доступ к содержимому с разных страниц с разными стилями, вы можете попробовать управлять им с помощью JavaScript.
var frm = frames['frame'].document;
var otherhead = frm.getElementsByTagName("head")[0];
var link = frm.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "style.css");
otherhead.appendChild(link);
Обратите внимание, что в зависимости от того, какой браузер вы используете, это может работать только на страницах, обслуживаемых из того же домена.
Возможно, стоит отметить, что та же политика происхождения перестанет работать, если страница находится в другом домене.
В том же духе, но более лаконично: <iframe onload = "this.contentDocument.body.style.overflow='hidden';" />
Даже Firefox перешел на CORS
Фрагмент <iframe id = "iframe-payment2" onload = "this.style.height = '1600px';" frameborder = "0" scrolling = "no" height = "1800" src = "<? php echo" // ". $ _SERVER ['HTTP_HOST'];?> / payment /"> </iframe> работал у меня.
var frm = frames['frame'].document; должен быть var frm = window.frames['frame'].document;. Тем не менее, по-прежнему не работает, документ возвращается как неопределенный.Редактировать: Это не работает в междоменном режиме, если не установлен соответствующий Заголовок CORS.
Здесь есть две разные вещи: стиль блока iframe и стиль страницы, встроенной в iframe. Вы можете установить стиль блока iframe обычным способом:
<iframe name = "iframe1" id = "iframe1" src = "empty.htm"
frameborder = "0" border = "0" cellspacing = "0"
style = "border-style: none;width: 100%; height: 120px;"></iframe>
Стиль страницы, встроенной в iframe, должен быть установлен путем включения его в дочернюю страницу:
<link type = "text/css" rel = "Stylesheet" href = "Style/simple.css" />
Или его можно загрузить с родительской страницы с помощью Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
Обратите внимание, мне кажется, что некоторые из опубликованных ранее примеров теперь недействительны для html5. Вы можете получить доступ к содержимому фрейма следующим образом: document.getElementById("myframe").contentDocument. Однако встраивание css все еще не работает для меня.
ссылка может появиться только в ГОЛОВЕ
Работал у меня только тогда, когда я делал ...document.head.appendChild(cssLink) - Firefox и Safari.
Это действительно работает междоменно? Я так не думаю.
Просто так, что никто другой не должен тестировать это, чтобы узнать: правильно, это не работает в междоменном режиме. Сразу после выполнения фреймов ['name'] вы получаете «Небезопасная попытка JavaScript получить доступ к фрейму с URL-адресом blah из фрейма с URL-адресом blah. Домены, протоколы и порты должны совпадать».
Насколько я могу судить, не работает для IE8 (независимо от того, добавлен ли он в тело или в голову).
Это может быть глупый вопрос, но разве нельзя использовать встроенный CSS вместо атрибута href, чтобы обойти проблему междоменного доступа?
Отвечаю себе: нет, так как ошибка возникает "сразу после выполнения frames['name']".
такой взлом, правда, никогда не думал, что кто-нибудь придумает ответ. отличная работа!
Обновление с конца 2014 года ... Кажется, это не работает с Chrome 38. CSS загружается в голову, но не стили. Кроме того, вставка элемента <link> в тело вручную также не приводит к появлению стилей. Интересно, связано ли это с безопасностью Chrome.
Я не пробовал, но это может сработать, если мы будем использовать абсолютный URL-адрес файла CSS, добавленный javascript в iframe, что-то вроде - example.com/css/style.css
он показывает ошибку, то есть TypeError: frames.frame1 is undefined
В моем случае это показывает эту ошибку: frames.frame1.document is undefined
не работает для меня, я добавил правила стиля CSS в тег заголовка. любое решение?
Вы не сможете стилизовать содержимое iframe таким образом. Я предлагаю использовать серверные сценарии (PHP, ASP или Perl-сценарий) или найти онлайн-сервис, который преобразует канал в код JavaScript. Единственный другой способ сделать это - включить серверную часть.
Будьте осторожны, когда говорите, что что-то нельзя сделать, когда на самом деле это просто сложно
Вышеупомянутое с небольшими изменениями работает:
var cssLink = document.createElement("link")
cssLink.href = "pFstylesEditor.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
//Instead of this
//frames['frame1'].document.body.appendChild(cssLink);
//Do this
var doc=document.getElementById("edit").contentWindow.document;
//If you are doing any dynamic writing do that first
doc.open();
doc.write(myData);
doc.close();
//Then append child
doc.body.appendChild(cssLink);
Прекрасно работает как минимум с ff3 и ie8
Что такое myData и откуда они
@Tigran это для dynamic data
Если вы хотите повторно использовать CSS и JavaScript с главной страницы, возможно, вам стоит подумать о замене <IFRAME> загруженным контентом Ajax. Теперь это больше подходит для SEO, когда поисковые боты могут выполнять JavaScript.
Это пример jQuery, который включает другую страницу html в ваш документ. Это намного удобнее для SEO, чем iframe. Чтобы быть уверенным, что боты не индексируют включенную страницу, просто добавьте ее для запрета в robots.txt.
<html>
<header>
<script src = "/js/jquery.js" type = "text/javascript"></script>
</header>
<body>
<div id='include-from-outside'></div>
<script type='text/javascript'>
$('#include-from-outside').load('http://example.com/included.html');
</script>
</body>
</html>
Вы также можете включить jQuery прямо из Google: http://code.google.com/apis/ajaxlibs/documentation/ - это означает необязательное автоматическое включение более новых версий и некоторое значительное увеличение скорости. Кроме того, это означает, что вы должны доверять им, поскольку они предоставят вам только jQuery;)
Следует отметить, что это решение не работает, если содержимое страницы каким-либо образом является динамическим.
Когда вы говорите «doc.open ()», это означает, что вы можете написать любой HTML-тег внутри iframe, поэтому вам следует написать все основные теги для HTML-страницы, и если вы хотите иметь ссылку CSS в заголовке iframe, просто напишите iframe со ссылкой CSS в нем. Приведу пример:
doc.open();
doc.write('<!DOCTYPE html><html><head><meta charset = "utf-8"/><meta http-quiv = "Content-Type" content = "text/html; charset=utf-8"/><title>Print Frame</title><link rel = "stylesheet" type = "text/css" href = "/css/print.css"/></head><body><table id = "' + gridId + 'Printable' + '" class = "print" >' + out + '</table></body></html>');
doc.close();
Что ж, я выполнил следующие шаги:
iframeiframe в div.divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
Это работает в IE 6. Если работает в других браузерах, проверьте!
нужно управлять div внутри iframe, это не
Следующее сработало для меня.
var iframe = top.frames[name].document;
var css = '' +
'<style type = "text/css">' +
'body{margin:0;padding:0;background:transparent}' +
'</style>';
iframe.open();
iframe.write(css);
iframe.close();
Ошибка: Uncaught TypeError: Cannot read property 'open' of undefined
Я встретил эту проблему с Календарь Google. Я хотел стилизовать его на более темном фоне и изменить шрифт.
К счастью, URL-адрес из встроенного кода не имел ограничений на прямой доступ, поэтому с помощью функции PHP file_get_contents можно получить
весь контент со страницы. Вместо вызова URL-адреса Google можно вызвать файл php, расположенный на вашем сервере, например. google.php, который будет содержать исходный контент с изменениями:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Добавление пути к вашей таблице стилей:
$content = str_replace('</head>','<link rel = "stylesheet" href = "http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(Это поместит вашу таблицу стилей последней перед закрывающим тегом head.)
Укажите базовый URL-адрес из исходного URL-адреса в случае, если css и js вызываются относительно:
$content = str_replace('</title>','</title><base href = "https://www.google.com/calendar/" />', $content);
Окончательный файл google.php должен выглядеть так:
<?php
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
$content = str_replace('</title>','</title><base href = "https://www.google.com/calendar/" />', $content);
$content = str_replace('</head>','<link rel = "stylesheet" href = "http://www.yourwebsiteurl.com/google.css" /></head>', $content);
echo $content;
Затем вы меняете код внедрения iframe на:
<iframe src = "http://www.yourwebsiteurl.com/google.php" style = "border: 0" width = "800" height = "600" frameborder = "0" scrolling = "no"></iframe>
Удачи!
Прежде всего, хочу сказать, что это отличное решение, но оно не всегда работает. Если вы попробуете его с YouTube, он будет навсегда буферизован. Есть идеи, почему?
Вы можете назвать это взломом по определению, если хотите. Но вы не предложили лучшего решения ... Это решение не способ навредить сервису Google или обмануть людей, чтобы использовать их слабости.
Я бы убил за способ заставить это решение работать с документами google. Он выдает всевозможные ошибки javascript. «Uncaught TypeError: Невозможно прочитать свойство 'a' из undefined»
Неважно, я понял это, разместил решение здесь: stackoverflow.com/questions/25395279/…
@ChrisHoughton К вашему сведению, в основном это не так. Однако это может сделать весь iframe бессмысленным (одна из причин использования iframe, например, связана с соображениями безопасности, например, с платежами по картам, и если вы сделаете то, что предлагается здесь, вы, вероятно, вызовете проблемы).
Это будет работать только для полностью статического контента, например, что-либо динамическое, например форма, не будет работать.
В моем случае file_get_contents() не захватывает раздел <head>, не знаете почему?
Делая это, вы всегда получаете календарь как не вошедший в систему пользователь. С обычным iframe html пользователь будет видеть свой личный календарь, если он вошел в Google, но поскольку ваш PHP-код не может знать идентификатор сеанса пользователя Google, он не может получить их личный календарь.
Если TOS позволяет это, и разработчик был достаточно решителен, они, вероятно, могли бы использовать CURL для этого и заставить все работать. IFRAME не требуется. (TOS большинства сервисов этого не допускает).
Я не думаю, что ты больше сможешь это делать (2018)
Приходилось делать аналогичные вещи с Oracle Taleo, чтобы переопределить их интерфейс и внедрить CSS. Когда вы делаете что-то для клиентов, вы должны делать то, что должны.
так можно ли показывать новости Google на нашем сайте, используя эту технику.
Для тех, кого беспокоят файлы cookie, в некоторых случаях вы можете использовать stream_context_create () для создания контекста для передачи в file_get_contents (), который позволит вам передавать файлы cookie, например, файл cookie сеанса, если вы знаете, что это такое и какие значения нужны. быть.
@DavidScherer Кроме того, вы можете использовать заголовки для отправки информации cookie и любой другой информации о сеансе.
FWIW просто используйте URL-адрес календаря с компонентом календаря js
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
@deweydb Я использовал его специально с междоменным iframe. но я могу только просить прощения!
@ramie, а вы тестировали это в нескольких браузерах? большинство браузеров выдают ошибку безопасности.
Я видел эту идею раньше, но добавлю ссылку на файл, это действительно здорово и профессионально ... + вверх
Мой компактная версия:
<script type = "text/javascript">
$(window).load(function () {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
});
</script>
Однако иногда iframe не готов к загрузке окна, поэтому необходимо использовать таймер.
Готовый код (с таймером):
<script type = "text/javascript">
var frameListener;
$(window).load(function () {
frameListener = setInterval("frameLoaded()", 50);
});
function frameLoaded() {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
clearInterval(frameListener); // stop the listener
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
}
</script>
... и ссылка jQuery:
<script src = "https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type = "text/javascript"></script>
Расширение вышеупомянутого решения jQuery, чтобы справиться с любыми задержками при загрузке содержимого фрейма.
$('iframe').each(function(){
function injectCSS(){
$iframe.contents().find('head').append(
$('<link/>', { rel: 'stylesheet', href: 'iframe.css', type: 'text/css' })
);
}
var $iframe = $(this);
$iframe.on('load', injectCSS);
injectCSS();
});
«$ This» должен быть «$ (this)», чтобы он работал. Приятно, когда есть :)
Вот как применить код CSS напрямую, не используя <link> для загрузки дополнительной таблицы стилей.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type = "text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
Это скрывает баннер на странице iframe. Спасибо вам за ваши предложения!
Нужен ли для этого iframe с идентификатором iframe?
@jmalais Просто замените #iframe на #<id> или даже iframe, чтобы выбрать все iframe.
Похоже, у меня это не работает. У iframe, который я пытаюсь редактировать, также нет головы прямо под ним в dom. Значит ли это, что мне нужно получить доступ к заголовку внутри html-документа, или это то, что функция поиска jquery должна делать сама?
Проверил консоль, и похоже, что доступ к содержимому iframe заблокирован из-за несоответствия домена. В настоящее время я использую Chrome и размещаю свою среду разработки локально.
Uncaught DOMException: заблокирован кадр с источником, он дает мне эту ошибку
Я думаю, что самый простой способ - добавить еще один div в том же месте, что и iframe, а затем
сделайте его z-index больше, чем контейнер iframe, чтобы вы могли легко стилизовать свой собственный div. Если вам нужно щелкнуть по нему, просто используйте pointer-events:none в своем собственном div, чтобы iframe работал, если вам нужно щелкнуть по нему;)
Надеюсь, это кому-то поможет;)
Мы можем вставить тег стиля в iframe.
<style type = "text/css" id = "cssID">
.className
{
background-color: red;
}
</style>
<iframe id = "iFrameID"></iframe>
<script type = "text/javascript">
$(function () {
$("#iFrameID").contents().find("head")[0].appendChild(cssID);
//Or $("#iFrameID").contents().find("head")[0].appendChild($('#cssID')[0]);
});
</script>
Это не работает. Кажется, тег стиля вставлен правильно, но внутри него нет содержимого и идентификатора.
Я нашел другое решение, чтобы поместить стиль в основной html следующим образом
<style id = "iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
а затем в iframe сделайте это (см. js onload)
<iframe onload = "iframe.document.head.appendChild(ifstyle)" name = "log" src = "/upgrading.log"></iframe>
и в js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
Возможно, это не лучшее решение, и его, безусловно, можно улучшить, но это еще один вариант, если вы хотите сохранить тег стиля в родительском окне.
Если у вас есть доступ к странице iframe и вы хотите, чтобы к ней применялся другой CSS, только когда вы загружаете его через iframe на свою страницу, здесь я нашел решение для таких вещей.
это работает, даже если iframe загружает другой домен
проверить про postMessage()
план: отправить CSS в iframe в виде сообщения, например
iframenode.postMessage('h2{color:red;}','*');
* должен отправлять это сообщение независимо от того, в каком домене оно находится в iframe.
и получите сообщение в iframe и добавьте полученное сообщение (CSS) в заголовок этого документа.
код для добавления на страницу iframe
window.addEventListener('message',function(e){
if (e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
В других ответах здесь используются ссылки jQuery и CSS.
Этот код использует ванильный JavaScript. Он создает новый элемент <style>. Он устанавливает текстовое содержимое этого элемента как строку, содержащую новый CSS. И он добавляет этот элемент непосредственно в заголовок документа iframe.
var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
'.some-class-name {' +
' some-style-name: some-value;' +
'}'
;
iframe.contentDocument.head.appendChild(style);
Существует замечательный сценарий, который заменяет узел собственной версией iframe. CodePen Демо
Примеры использования:
// Single node
var component = document.querySelector('.component');
var iframe = iframify(component);
// Collection of nodes
var components = document.querySelectorAll('.component');
var iframes = Array.prototype.map.call(components, function (component) {
return iframify(component, {});
});
// With options
var component = document.querySelector('.component');
var iframe = iframify(component, {
headExtra: '<style>.component { color: red; }</style>',
metaViewport: '<meta name = "viewport" content = "width=device-width">'
});
Почему вы хотите это сделать?!
Это всего лишь концепция, но не реализуйте ее без проверки безопасности и фильтрации! В противном случае скрипт может взломать ваш сайт!
Ответ: если вы контролируете целевой сайт, вы можете настроить скрипт-приемник следующим образом:
1) установите ссылку iframe с параметром style, например:
http://your_site.com/target.php?color=red
(последняя фраза - a{color:red}, закодированная функцией urlencode.
2) настроить страницу ресивера target.php так:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Предупреждение: это лучшая инъекция.
yap, НЕ делайте этого, за исключением того, что вы хотите, чтобы на вашем сервере была загружена загрузка ботов для проверки на проникновение и скриптовых детей =) ...
Я обновил ответ сейчас с добавленным предупреждением безопасности
var link1 = document.createElement('link');
link1.type = 'text/css';
link1.rel = 'stylesheet';
link1.href = "../../assets/css/normalize.css";
window.frames['richTextField'].document.body.appendChild(link1);Я много раз проверял этот ответ, что здесь richTextField?
это имя iframe
Я не пробовал, но думаю, не будет, потому что это против песочницы
Здесь есть две вещи внутри домена
Итак, вы хотите стилизовать эти два раздела следующим образом:
1. Стиль раздела iFrame
Он может стилизовать с использованием CSS с уважаемым именем id или class. Вы также можете просто стилизовать его в родительских таблицах стилей.
<style>
#my_iFrame{
height: 300px;
width: 100%;
position:absolute;
top:0;
left:0;
border: 1px black solid;
}
</style>
<iframe name='iframe1' id = "my_iFrame" src = "#" cellspacing = "0"></iframe>
2. Стиль страницы, загруженной в iFrame.
Эти стили можно загрузить с родительской страницы с помощью Javascript.
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
затем установите этот файл CSS в уважаемый раздел iFrame
//to Load in the Body Part
frames['my_iFrame'].document.body.appendChild(cssFile);
//to Load in the Head Part
frames['my_iFrame'].document.head.appendChild(cssFile);
Здесь вы можете редактировать головную часть страницы внутри iFrame, используя также этот способ
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
В качестве альтернативы вы можете использовать технологию CSS-in-JS, как показано ниже в lib:
https://github.com/cssobj/cssobj
Он может динамически внедрять объект JS как CSS в iframe.
использование может попробовать это:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
Если ваш iframe поступает из другого источника, механизм CORS не разрешит это обходное решение.
Что, если для iframe-url включен CORS для всех местоположений?
Поскольку для одних и тех же доменов написано много ответов, я напишу, как это сделать в кросс-доменах.
Во-первых, вам нужно знать Post Message API. Нам нужен мессенджер для связи между двумя окнами.
Вот созданный мной мессенджер.
/**
* Creates a messenger between two windows
* which have two different domains
*/
class CrossMessenger {
/**
*
* @param {object} otherWindow - window object of the other
* @param {string} targetDomain - domain of the other window
* @param {object} eventHandlers - all the event names and handlers
*/
constructor(otherWindow, targetDomain, eventHandlers = {}) {
this.otherWindow = otherWindow;
this.targetDomain = targetDomain;
this.eventHandlers = eventHandlers;
window.addEventListener("message", (e) => this.receive.call(this, e));
}
post(event, data) {
try {
// data obj should have event name
var json = JSON.stringify({
event,
data
});
this.otherWindow.postMessage(json, this.targetDomain);
} catch (e) {}
}
receive(e) {
var json;
try {
json = JSON.parse(e.data ? e.data : "{}");
} catch (e) {
return;
}
var eventName = json.event,
data = json.data;
if (e.origin !== this.targetDomain)
return;
if (typeof this.eventHandlers[eventName] === "function")
this.eventHandlers[eventName](data);
}
}
Использование этого в двух окнах для общения может решить вашу проблему.
В главных окнах
var msger = new CrossMessenger(iframe.contentWindow, "https://iframe.s.domain");
var cssContent = Array.prototype.map.call(yourCSSElement.sheet.cssRules, css_text).join('\n');
msger.post("cssContent", {
css: cssContent
})
Затем получите событие от Iframe.
В iframe:
var msger = new CrossMessenger(window.parent, "https://parent.window.domain", {
cssContent: (data) => {
var cssElem = document.createElement("style");
cssElem.innerHTML = data.css;
document.head.appendChild(cssElem);
}
})
См. Подробное руководство по Javascript и iframe.
Это возможно, но только если домен iframe совпадает с родительским