Tengo una página simple que tiene algunas secciones de iframe (para mostrar enlaces RSS). ¿Cómo puedo aplicar el mismo formato CSS desde la página principal a la página que se muestra en el iframe?
Tengo una página simple que tiene algunas secciones de iframe (para mostrar enlaces RSS). ¿Cómo puedo aplicar el mismo formato CSS desde la página principal a la página que se muestra en el iframe?
Respuestas:
Editar: Esto no funciona entre dominios a menos que se establezca el encabezado CORS apropiado .
Aquí hay dos cosas diferentes: el estilo del bloque de marco flotante y el estilo de la página incrustada en el marco flotante. Puede establecer el estilo del bloque de iframe de la forma habitual:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
El estilo de la página incrustada en el iframe debe establecerse incluyéndolo en la página secundaria:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
O se puede cargar desde la página principal con Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
document.getElementById("myframe").contentDocument
. Sin embargo, incrustar el CSS todavía no parece funcionar para mí.
...document.head.appendChild(cssLink)
: Firefox y Safari.
Encontré este problema con Google Calendar . Quería darle un estilo sobre un fondo más oscuro y cambiar la fuente.
Afortunadamente, la URL del código incrustado no tenía restricciones en el acceso directo, por lo que al usar la función PHP file_get_contents
es posible obtener todo el contenido de la página. En lugar de llamar a la URL de Google, es posible llamar a un archivo php ubicado en su servidor, ej. google.php
, que contendrá el contenido original con modificaciones:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Agregar la ruta a su hoja de estilo:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(Esto colocará su hoja de estilo al final justo antes de la head
etiqueta final).
Especifique la url base de la url original en caso de que css y js se llamen relativamente:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
El google.php
archivo final debería verse así:
<?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;
Luego cambia el iframe
código de inserción a:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
¡Buena suerte!
Si el contenido del iframe no está completamente bajo su control o si desea acceder al contenido desde diferentes páginas con diferentes estilos, puede intentar manipularlo usando 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);
Tenga en cuenta que, dependiendo del navegador que utilice, esto podría funcionar solo en las páginas que se envían desde el mismo dominio.
<iframe onload="this.contentDocument.body.style.overflow='hidden';" />
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
La mayoría de los navegadores manejan universalmente un iframe como una página HTML diferente. Si desea aplicar la misma hoja de estilo al contenido del iframe, solo consúltelo desde las páginas utilizadas allí.
Aquí se explica cómo aplicar el código CSS directamente sin usar <link>
para cargar una hoja de estilo adicional.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
Esto oculta el banner en la página del iframe. ¡Gracias por tus sugerencias!
iframe
?
#iframe
con #<id>
o incluso iframe
para seleccionar todos los iframe
s
Si controla la página en el iframe, como dijo Hangy, el enfoque más fácil es crear un archivo CSS compartido con estilos comunes, luego simplemente vincúlelo desde sus páginas html.
De lo contrario, es poco probable que pueda cambiar dinámicamente el estilo de una página desde una página externa en su iframe. Esto se debe a que los navegadores han reforzado la seguridad en los scripts de dom de tramas cruzadas debido al posible uso indebido para la suplantación de identidad y otros hacks.
Este tutorial puede proporcionarle más información sobre secuencias de comandos de iframes en general. Acerca de las secuencias de comandos de marcos cruzados explica las restricciones de seguridad desde la perspectiva de IE.
Lo anterior con un pequeño cambio funciona:
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);
Funciona bien con ff3 y ie8 al menos
dynamic data
Si desea reutilizar CSS y JavaScript desde la página principal, tal vez debería considerar reemplazarlo <IFRAME>
por un contenido cargado de Ajax. Esto es más amigable con SEO ahora cuando los robots de búsqueda pueden ejecutar JavaScript.
Este es un ejemplo de jQuery que incluye otra página html en su documento. Esto es mucho más amigable con SEO que iframe
. Para estar seguro de que los bots no están indexando la página incluida, solo agréguela para no permitirrobots.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>
También puede incluir jQuery directamente desde Google: http://code.google.com/apis/ajaxlibs/documentation/ , esto significa la inclusión automática opcional de versiones más nuevas y un aumento significativo de la velocidad. Además, significa que debe confiar en ellos para entregarle solo jQuery;)
Lo siguiente funcionó para mí.
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
Ampliando la solución jQuery anterior para hacer frente a cualquier retraso en la carga del contenido del marco.
$('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();
});
Mi versión compacta :
<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>
Sin embargo, a veces iframe
no está listo en la ventana cargada, por lo que es necesario usar un temporizador .
Código listo para usar (con temporizador):
<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>
... y enlace jQuery:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
Otras respuestas aquí parecen usar enlaces jQuery y CSS.
Este código usa JavaScript vainilla. Crea un nuevo <style>
elemento. Establece el contenido de texto de ese elemento como una cadena que contiene el nuevo CSS. Y agrega ese elemento directamente a la cabeza del documento del 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);
Cuando dice "doc.open ()" significa que puede escribir cualquier etiqueta HTML dentro del iframe, por lo que debe escribir todas las etiquetas básicas para la página HTML y si desea tener un enlace CSS en su cabeza de iframe simplemente escriba un iframe con enlace CSS en él. Te doy un ejemplo:
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="https://stackoverflow.com/css/print.css"/></head><body><table id="' + gridId + 'Printable' + '" class="print" >' + out + '</table></body></html>');
doc.close();
uso puede intentar esto:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
No podrá diseñar el contenido del iframe de esta manera. Mi sugerencia sería utilizar secuencias de comandos en el servidor (PHP, ASP o una secuencia de comandos Perl) o buscar un servicio en línea que convierta una fuente a código JavaScript. La única otra forma de hacerlo sería si puede incluir un servidor.
En caso de que tenga acceso a la página de iframe y desee que se aplique un CSS diferente solo cuando lo cargue a través de iframe en su página, aquí encontré una solución para este tipo de cosas
esto funciona incluso si el iframe está cargando un dominio diferente
consultar sobre postMessage()
plan es, envíe el CSS al iframe como un mensaje como
iframenode.postMessage('h2{color:red;}','*');
*
es enviar este mensaje independientemente del dominio en el que se encuentre el iframe
y reciba el mensaje en iframe y agregue el mensaje recibido (CSS) al encabezado de ese documento.
código para agregar en la página de iframe
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
Como se escriben muchas respuestas para los mismos dominios, escribiré cómo hacer esto en dominios cruzados.
Primero, debes conocer la API de publicación de mensajes . Necesitamos un mensajero para comunicarnos entre dos ventanas.
Aquí hay un mensajero que creé.
/**
* 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);
}
}
Usar esto en dos ventanas para comunicarse puede resolver su problema.
En las ventanas principales,
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
})
Luego, reciba el evento del Iframe.
En el 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);
}
})
Vea el tutorial completo de Javascript y Iframes para más detalles.
Encontré otra solución para poner el estilo en el html principal como este
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
y luego en iframe hacer esto (ver la carga js)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
y en js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
Puede que no sea la mejor solución, y ciertamente puede mejorarse, pero es otra opción si desea mantener una etiqueta de "estilo" en la ventana principal
Aquí, hay dos cosas dentro del dominio.
Entonces, desea diseñar esas dos secciones de la siguiente manera,
1. Estilo para la sección iFrame
Puede diseñar usando CSS con ese nombre id
o class
nombre respetado . También puede diseñarlo en sus hojas de estilo principales también.
<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. Diseñe la página cargada dentro del iFrame
Estos estilos se pueden cargar desde la página principal con la ayuda de Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
luego establezca ese archivo CSS en la respetada sección de 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);
Aquí, también puede editar la parte principal de la página dentro del iFrame de esta manera.
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
Podemos insertar etiquetas de estilo en iframe. Publicado también aquí ...
<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>
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
aquí?
Creo que la forma más fácil es agregar otro div, en el mismo lugar que el iframe, luego
haga que sea z-index
más grande que el contenedor de iframe, para que pueda diseñar fácilmente su propio div. Si necesita hacer clic en él, simplemente use pointer-events:none
en su propio div, por lo que el iframe estaría funcionando en caso de que necesite hacer clic en él;)
Espero que ayude a alguien;)
Hay un script maravilloso que reemplaza un nodo con una versión de iframe de sí mismo. CodePen Demo
Ejemplos de uso:
// 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">'
});
Como alternativa, puede usar la tecnología CSS-in-JS, como la siguiente lib:
https://github.com/cssobj/cssobj
Puede inyectar objetos JS como CSS a iframe, dinámicamente
¡Esto es solo un concepto, pero no lo implemente sin controles de seguridad y filtrado! De lo contrario, el script podría hackear su sitio.
Respuesta: si controla el sitio de destino, puede configurar el script del receptor como:
1) establezca el enlace iframe con el style
parámetro, como:
http://your_site.com/target.php?color=red
(la última frase está a{color:red}
codificada por urlencode
función.
2) configura la página del receptor de target.php
esta manera:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Bueno, he seguido estos pasos:
iframe
iframe
a la div
.divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
Esto funciona en IE 6. ¡Debería funcionar en otros navegadores, verifique!