How to load a CSS file based on a URL or client? - html

I have two CSS files in my Sencha touch application. Lets call them A.css and B.css. Based on the URL I want the application to load different CSS.
Lets say URL 1 is www.website.com/#1 so for this I would like to load A.css. similarly URL 2 is www.website.com/#2 so for this I would like to load B.css
Is it possible to load CSS dynamically based on the URL?

You can use JavaScript Regex for this.
Very easy method:
// For www.website.com/#1
if (/www.website.com\/#1/.test(window.location.href)) {
/* Your Code Here For Loading Css */
}
// For www.website.com/#2
if (/www.website.com\/#1/.test(window.location.href)) {
/* Your Code Here For Loading Css */
}
I hope this helps!!!

You can use the follow JavaScript code to load CSS dynamically for your requirement:
if (window.location == "http://www.website.com/#1") {
LoadCSS("A.css")
}
else if(window.location == "http://www.website.com/#2") {
LoadCSS("B.css")
}
function LoadCSS(filename) {
var fileref = document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", filename);
}

Get hashtag value from URL and then depending on value change the link for CSS.
To get hashtag value:
$url = "www.website.com/#1";
$params = parse_url($url);
$value = $params['fragment'];
This will give you hashtag value, then depending on value link CSS file in header:
<?php if ($value == 1) { ?>
<link href="A.css" rel="stylesheet" type="text/css" />
<?php } else { ?>
<link href="B.css" rel="stylesheet" type="text/css" />
<?php } ?>

I assume you have one template available for 2 URLs. Loading CSS using JavaScript is a pretty bad practice because it's slow and it's giving the user a bad experience since nothing is initially styled.
Anyway you can use the append function to add the CSS to the head tag.
$('head')
.append( $('<link rel="stylesheet" type="text/css" />')
.attr('href', 'your_stylesheet_url') );
And for the URL itself simply use the JavaScript window.location like so:
if (window.location == "#1url") {
// load the A.css using the append function like above
}

Related

How can I access elements that are in iframe [duplicate]

I have a simple page that has some iframe sections (to display RSS links). How can I apply the same CSS format from the main page to the page displayed in the iframe?
Edit: This does not work cross domain unless the appropriate CORS header is set.
There are two different things here: the style of the iframe block and the style of the page embedded in the iframe. You can set the style of the iframe block the usual way:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
The style of the page embedded in the iframe must be either set by including it in the child page:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
Or it can be loaded from the parent page with Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
I met this issue with Google Calendar. I wanted to style it on a darker background and change font.
Luckily, the URL from the embed code had no restriction on direct access, so by using PHP function file_get_contents it is possible to get the
entire content from the page. Instead of calling the Google URL, it is possible to call a php file located on your server, ex. google.php, which will contain the original content with modifications:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Adding the path to your stylesheet:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(This will place your stylesheet last just before the head end tag.)
Specify the base url form the original url in case css and js are called relatively:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
The final google.php file should look like this:
<?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;
Then you change the iframe embed code to:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
Good luck!
If the content of the iframe is not completely under your control or you want to access the content from different pages with different styles you could try manipulating it using 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);
Note that depending on what browser you use this might only work on pages served from the same domain.
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
Here is how to apply CSS code directly without using <link> to load an extra stylesheet.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
This hides the banner in the iframe page. Thank you for your suggestions!
If you control the page in the iframe, as hangy said, the easiest approach is to create a shared CSS file with common styles, then just link to it from your html pages.
Otherwise it is unlikely you will be able to dynamically change the style of a page from an external page in your iframe. This is because browsers have tightened the security on cross frame dom scripting due to possible misuse for spoofing and other hacks.
This tutorial may provide you with more information on scripting iframes in general. About cross frame scripting explains the security restrictions from the IE perspective.
An iframe is universally handled like a different HTML page by most browsers. If you want to apply the same stylesheet to the content of the iframe, just reference it from the pages used in there.
The above with a little change works:
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);
Works fine with ff3 and ie8 at least
The following worked for me.
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();
Expanding on the above jQuery solution to cope with any delays in loading the frame contents.
$('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();
});
use can try this:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
If you want to reuse CSS and JavaScript from the main page maybe you should consider replacing <IFRAME> with a Ajax loaded content. This is more SEO friendly now when search bots are able to execute JavaScript.
This is jQuery example that includes another html page into your document. This is much more SEO friendly than iframe. In order to be sure that the bots are not indexing the included page just add it to disallow in 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>
You could also include jQuery directly from Google: http://code.google.com/apis/ajaxlibs/documentation/ - this means optional auto-inclusion of newer versions and some significant speed increase. Also, means that you have to trust them for delivering you just the jQuery ;)
My compact version:
<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>
However, sometimes the iframe is not ready on window loaded, so there is a need of using a timer.
Ready-to-use code (with timer):
<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>
...and jQuery link:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
As many answers are written for the same domains, I'll write how to do this in cross domains.
First, you need to know the Post Message API. We need a messenger to communicate between two windows.
Here's a messenger I created.
/**
* 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);
}
}
Using this in two windows to communicate can solve your problem.
In the main windows,
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
})
Then, receive the event from the Iframe.
In the 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);
}
})
See the Complete Javascript and Iframes tutorial for more details.
Other answers here seem to use jQuery and CSS links.
This code uses vanilla JavaScript. It creates a new <style> element. It sets the text content of that element to be a string containing the new CSS. And it appends that element directly to the iframe document's head.
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);
When you say "doc.open()" it means you can write whatever HTML tag inside the iframe, so you should write all the basic tags for the HTML page and if you want to have a CSS link in your iframe head just write an iframe with CSS link in it. I give you an example:
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();
You will not be able to style the contents of the iframe this way. My suggestion would be to use serverside scripting (PHP, ASP, or a Perl script) or find an online service that will convert a feed to JavaScript code. The only other way to do it would be if you can do a serverside include.
Incase if you have access to iframe page and want a different CSS to apply on it only when you load it via iframe on your page, here I found a solution for these kind of things
this works even if iframe is loading a different domain
check about postMessage()
plan is, send the css to iframe as a message like
iframenode.postMessage('h2{color:red;}','*');
* is to send this message irrespective of what domain it is in iframe
and receive the message in iframe and add the received message(CSS) to that document head.
code to add in iframe page
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
I think the easiest way is to add another div, in the same place as the iframe, then
make its z-index bigger than the iframe container, so you can easly just style your own div. If you need to click on it, just use pointer-events:none on your own div, so the iframe would be working in case you need to click on it ;)
I hope It will help someone ;)
I found another solution to put the style in the main html like this
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
and then in iframe do this (see the js onload)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
and in js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
It may not be the best solution, and it certainly can be improved, but it is another option if you want to keep a "style" tag in parent window
Here, There are two things inside the domain
iFrame Section
Page Loaded inside the iFrame
So you want to style those two sections as follows,
1. Style for the iFrame Section
It can style using CSS with that respected id or class name. You can just style it in your parent Style sheets also.
<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. Style the Page Loaded inside the iFrame
This Styles can be loaded from the parent page with the help of Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
then set that CSS file to the respected iFrame section
//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);
Here, You can edit the Head Part of the Page inside the iFrame using this way also
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
We can insert style tag into 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>
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);
This is how I'm doing in production. It's worth bearing in mind that if the iframe belongs to other website, it will trigger the CORS error and will not work.
var $iframe = document.querySelector(`iframe`);
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
In some cases you may also want to attach a load event to the iframe:
var $iframe = document.querySelector(`iframe`);
$iframe.addEventListener("load", function() {
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
});
There is a wonderful script that replaces a node with an iframe version of itself.
CodePen Demo
Usage Examples:
// 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">'
});
As an alternative, you can use CSS-in-JS technology, like below lib:
https://github.com/cssobj/cssobj
It can inject JS object as CSS to iframe, dynamically
This is just a concept, but don't implement this without security checks and filtering! Otherwise script could hack your site!
Answer: if you control target site, you can setup the receiver script like:
1) set the iframe link with style parameter, like:
http://your_site.com/target.php?color=red
(the last phrase is a{color:red} encoded by urlencode function.
2) set the receiver page target.php like this:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Well, I have followed these steps:
Div with a class to hold iframe
Add iframe to the div.
In CSS file,
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
This works in IE 6. Should work in other browsers, do check!

How to override CSS in nested HTML document? [duplicate]

I have a simple page that has some iframe sections (to display RSS links). How can I apply the same CSS format from the main page to the page displayed in the iframe?
Edit: This does not work cross domain unless the appropriate CORS header is set.
There are two different things here: the style of the iframe block and the style of the page embedded in the iframe. You can set the style of the iframe block the usual way:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
The style of the page embedded in the iframe must be either set by including it in the child page:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
Or it can be loaded from the parent page with Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
I met this issue with Google Calendar. I wanted to style it on a darker background and change font.
Luckily, the URL from the embed code had no restriction on direct access, so by using PHP function file_get_contents it is possible to get the
entire content from the page. Instead of calling the Google URL, it is possible to call a php file located on your server, ex. google.php, which will contain the original content with modifications:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Adding the path to your stylesheet:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(This will place your stylesheet last just before the head end tag.)
Specify the base url form the original url in case css and js are called relatively:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
The final google.php file should look like this:
<?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;
Then you change the iframe embed code to:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
Good luck!
If the content of the iframe is not completely under your control or you want to access the content from different pages with different styles you could try manipulating it using 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);
Note that depending on what browser you use this might only work on pages served from the same domain.
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
Here is how to apply CSS code directly without using <link> to load an extra stylesheet.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
This hides the banner in the iframe page. Thank you for your suggestions!
If you control the page in the iframe, as hangy said, the easiest approach is to create a shared CSS file with common styles, then just link to it from your html pages.
Otherwise it is unlikely you will be able to dynamically change the style of a page from an external page in your iframe. This is because browsers have tightened the security on cross frame dom scripting due to possible misuse for spoofing and other hacks.
This tutorial may provide you with more information on scripting iframes in general. About cross frame scripting explains the security restrictions from the IE perspective.
An iframe is universally handled like a different HTML page by most browsers. If you want to apply the same stylesheet to the content of the iframe, just reference it from the pages used in there.
The above with a little change works:
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);
Works fine with ff3 and ie8 at least
The following worked for me.
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();
Expanding on the above jQuery solution to cope with any delays in loading the frame contents.
$('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();
});
use can try this:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
If you want to reuse CSS and JavaScript from the main page maybe you should consider replacing <IFRAME> with a Ajax loaded content. This is more SEO friendly now when search bots are able to execute JavaScript.
This is jQuery example that includes another html page into your document. This is much more SEO friendly than iframe. In order to be sure that the bots are not indexing the included page just add it to disallow in 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>
You could also include jQuery directly from Google: http://code.google.com/apis/ajaxlibs/documentation/ - this means optional auto-inclusion of newer versions and some significant speed increase. Also, means that you have to trust them for delivering you just the jQuery ;)
My compact version:
<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>
However, sometimes the iframe is not ready on window loaded, so there is a need of using a timer.
Ready-to-use code (with timer):
<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>
...and jQuery link:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
As many answers are written for the same domains, I'll write how to do this in cross domains.
First, you need to know the Post Message API. We need a messenger to communicate between two windows.
Here's a messenger I created.
/**
* 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);
}
}
Using this in two windows to communicate can solve your problem.
In the main windows,
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
})
Then, receive the event from the Iframe.
In the 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);
}
})
See the Complete Javascript and Iframes tutorial for more details.
Other answers here seem to use jQuery and CSS links.
This code uses vanilla JavaScript. It creates a new <style> element. It sets the text content of that element to be a string containing the new CSS. And it appends that element directly to the iframe document's head.
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);
When you say "doc.open()" it means you can write whatever HTML tag inside the iframe, so you should write all the basic tags for the HTML page and if you want to have a CSS link in your iframe head just write an iframe with CSS link in it. I give you an example:
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();
You will not be able to style the contents of the iframe this way. My suggestion would be to use serverside scripting (PHP, ASP, or a Perl script) or find an online service that will convert a feed to JavaScript code. The only other way to do it would be if you can do a serverside include.
Incase if you have access to iframe page and want a different CSS to apply on it only when you load it via iframe on your page, here I found a solution for these kind of things
this works even if iframe is loading a different domain
check about postMessage()
plan is, send the css to iframe as a message like
iframenode.postMessage('h2{color:red;}','*');
* is to send this message irrespective of what domain it is in iframe
and receive the message in iframe and add the received message(CSS) to that document head.
code to add in iframe page
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
I think the easiest way is to add another div, in the same place as the iframe, then
make its z-index bigger than the iframe container, so you can easly just style your own div. If you need to click on it, just use pointer-events:none on your own div, so the iframe would be working in case you need to click on it ;)
I hope It will help someone ;)
I found another solution to put the style in the main html like this
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
and then in iframe do this (see the js onload)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
and in js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
It may not be the best solution, and it certainly can be improved, but it is another option if you want to keep a "style" tag in parent window
Here, There are two things inside the domain
iFrame Section
Page Loaded inside the iFrame
So you want to style those two sections as follows,
1. Style for the iFrame Section
It can style using CSS with that respected id or class name. You can just style it in your parent Style sheets also.
<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. Style the Page Loaded inside the iFrame
This Styles can be loaded from the parent page with the help of Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
then set that CSS file to the respected iFrame section
//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);
Here, You can edit the Head Part of the Page inside the iFrame using this way also
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
We can insert style tag into 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>
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);
This is how I'm doing in production. It's worth bearing in mind that if the iframe belongs to other website, it will trigger the CORS error and will not work.
var $iframe = document.querySelector(`iframe`);
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
In some cases you may also want to attach a load event to the iframe:
var $iframe = document.querySelector(`iframe`);
$iframe.addEventListener("load", function() {
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
});
There is a wonderful script that replaces a node with an iframe version of itself.
CodePen Demo
Usage Examples:
// 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">'
});
As an alternative, you can use CSS-in-JS technology, like below lib:
https://github.com/cssobj/cssobj
It can inject JS object as CSS to iframe, dynamically
This is just a concept, but don't implement this without security checks and filtering! Otherwise script could hack your site!
Answer: if you control target site, you can setup the receiver script like:
1) set the iframe link with style parameter, like:
http://your_site.com/target.php?color=red
(the last phrase is a{color:red} encoded by urlencode function.
2) set the receiver page target.php like this:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Well, I have followed these steps:
Div with a class to hold iframe
Add iframe to the div.
In CSS file,
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
This works in IE 6. Should work in other browsers, do check!

Checking the internet connection and reading the files on/off line [duplicate]

I am linking to the jQuery Mobile stylesheet on a CDN and would like to fall back to my local version of the stylesheet if the CDN fails. For scripts the solution is well known:
<!-- Load jQuery and jQuery mobile with fall back to local server -->
<script src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
document.write(unescape("%3Cscript src='jquery-1.6.3.min.js'%3E"));
}
</script>
I would like to do something similar for a style sheet:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />
I am not sure if a similar approach can be achieved because I am not sure whether the browser blocks in the same way when linking a script as it does when loading a script (maybe it is possible to load a stylesheet in a script tag and then inject it into the page) ?
So my question is: How do I ensure a stylesheet is loaded locally if a CDN fails ?
One could use onerror for that:
<link rel="stylesheet" href="cdn.css" onerror="this.onerror=null;this.href='local.css';" />
The this.onerror=null; is to avoid endless loops in case the fallback it self is not available. But it could also be used to have multiple fallbacks.
However, this currently only works in Firefox and Chrome.
Update: Meanwhile, this seems to be supported by all common browsers.
Not cross-browser tested but I think this will work. Will have to be after you load jquery though, or you'll have to rewrite it in plain Javascript.
<script type="text/javascript">
$.each(document.styleSheets, function(i,sheet){
if(sheet.href=='http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css') {
var rules = sheet.rules ? sheet.rules : sheet.cssRules;
if (rules.length == 0) {
$('<link rel="stylesheet" type="text/css" href="path/to/local/jquery.mobile-1.0b3.min.css" />').appendTo('head');
}
}
})
</script>
Assuming you are using the same CDN for css and jQuery, why not just do one test and catch it all??
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1/themes/start/jquery-ui.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
document.write(unescape('%3Clink rel="stylesheet" type="text/css" href="../../Content/jquery-ui-1.8.16.custom.css" /%3E'));
document.write(unescape('%3Cscript type="text/javascript" src="/jQuery/jquery-1.6.4.min.js" %3E%3C/script%3E'));
document.write(unescape('%3Cscript type="text/javascript" src="/jQuery/jquery-ui-1.8.16.custom.min.js" %3E%3C/script%3E'));
}
</script>
I guess the question is to detect whether a stylesheet is loaded or not. One possible approach is as follows:
1) Add a special rule to the end of your CSS file, like:
#foo { display: none !important; }
2) Add the corresponding div in your HTML:
<div id="foo"></div>
3) On document ready, check whether #foo is visible or not. If the stylesheet was loaded, it will not be visible.
Demo here -- loads jquery-ui smoothness theme; no rule is added to stylesheet.
this article suggests some solutions for the bootstrap css
http://eddmann.com/posts/providing-local-js-and-css-resources-for-cdn-fallbacks/
alternatively this works for fontawesome
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
(function($){
var $span = $('<span class="fa" style="display:none"></span>').appendTo('body');
if ($span.css('fontFamily') !== 'FontAwesome' ) {
// Fallback Link
$('head').append('<link href="/css/font-awesome.min.css" rel="stylesheet">');
}
$span.remove();
})(jQuery);
</script>
You might be able to test for the existence of the stylesheet in document.styleSheets.
var rules = [];
if (document.styleSheets[1].cssRules)
rules = document.styleSheets[i].cssRules
else if (document.styleSheets[i].rules)
rule= document.styleSheets[i].rules
Test for something specific to the CSS file you're using.
Here's an extension to katy lavallee's answer. I've wrapped everything in self-executing function syntax to prevent variable collisions. I've also made the script non-specific to a single link. I.E., now any stylesheet link with a "data-fallback" url attribute will automatically be parsed. You don't have to hard-code the urls into this script like before. Note that this should be run at the end of the <head> element rather than at the end of the <body> element, otherwise it could cause FOUC.
http://jsfiddle.net/skibulk/jnfgyrLt/
<link rel="stylesheet" type="text/css" href="broken-link.css" data-fallback="broken-link2.css">
.
(function($){
var links = {};
$( "link[data-fallback]" ).each( function( index, link ) {
links[link.href] = link;
});
$.each( document.styleSheets, function(index, sheet) {
if(links[sheet.href]) {
var rules = sheet.rules ? sheet.rules : sheet.cssRules;
if (rules.length == 0) {
link = $(links[sheet.href]);
link.attr( 'href', link.attr("data-fallback") );
}
}
});
})(jQuery);
Do you really want to go down this javascript route to load CSS in case a CDN fails?
I haven't thought all the performance implications through but you're going to lose control of when the CSS is loaded and in general for page load performance, CSS is the first thing you want to download after the HTML.
Why not handle this at the infrastructure level - map your own domain name to the CDN, give it a short TTL, monitor the files on the CDN (e.g. using Watchmouse or something else), if CDN fails, change the DNS to backup site.
Other options that might help are "cache forever" on static content but there's no guarantee the browser will keep them of course or using the app-cache.
In reality as someone said at the top, if your CDN is unreliable get a new one
Andy
Look at these functions:
$.ajax({
url:'CSS URL HERE',
type:'HEAD',
error: function()
{
AddLocalCss();
},
success: function()
{
//file exists
}
});
And here is vanilla JavaScript version:
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status!=404;
}
if (!UrlExists('CSS URL HERE') {
AddLocalCss();
}
Now the actual function:
function AddLocalCss(){
document.write('<link rel="stylesheet" type="text/css" href=" LOCAL CSS URL HERE">')
}
Just make sure AddLocalCss is called in the head.
You might also consider using one of the following ways explained in this answer:
Load using AJAX
$.get(myStylesLocation, function(css)
{
$('<style type="text/css"></style>')
.html(css)
.appendTo("head");
});
Load using dynamically-created
$('<link rel="stylesheet" type="text/css" href="'+myStylesLocation+'" >')
.appendTo("head");
Load using dynamically-created <style>
$('<style type="text/css"></style>')
.html('#import url("' + myStylesLocation + '")')
.appendTo("head");
or
$('<style type="text/css">#import url("' + myStylesLocation + '")</style>')
.appendTo("head");
I'd probably use something like yepnope.js
yepnope([{
load: 'http:/­/ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
complete: function () {
if (!window.jQuery) {
yepnope('local/jquery.min.js');
}
}
}]);
Taken from the readme.
//(load your cdn lib here first)
<script>window.jQuery || document.write("<script src='//me.com/path/jquery-1.x.min.js'>\x3C/script>")</script>

How to disable CSS on a specific page?

I am using 3 stylesheets (style1, style2, style3) for many pages.
style1 for my web header,
style2 for my contents and
style3 for footer
Now I want to apply a new stylesheet on my home page and disable style2 for only home page.
I added new classes for different elements but at some places it is still detecting my previous stylesheets. How can I disable CSS on a specific page?
Since you did not include the code to see how you doing it, and considering you are having the header as an include file:
USE PHP:
In your Home page before including header:
<?php $homepage = 1; ?>
//include your header//
In your header where you are referencing CSS:
<link href="css/style1.css" rel="stylesheet" type="text/css" />
<link href="css/style3.css" rel="stylesheet" type="text/css" />
<link href="<?php if($homepage == 1){ echo "css/Home-style.css";}else{ echo "css/style2.css";}?>" rel="stylesheet" type="text/css" />
Your files should be in PHP for this to work.
change "Home-style.css" to your new CSS file for home page.
Check for page then grab the dom stylesheets array object and disable anything you want .
if(window.location.href.indexOf("<name in page url >") > -1) {
//Next line will disable the 2nd stylsheet in the document .
document.styleSheets[1].disabled = true;
}
Also fyi you can view all style sheets in the dom with:
console.log(document.styleSheets)
This should give you the appropriate index of whatever stylesheet you want to remove.
You have to use jQuery to disable a stylesheet like :
<script>
$(function () {
if (location.pathname.indexOf('/pagename') >= 0) {
$('link[href*="/media/css/csspagename.css"]').prop('disable', true);
}
});
</script>

How to apply CSS to iframe?

I have a simple page that has some iframe sections (to display RSS links). How can I apply the same CSS format from the main page to the page displayed in the iframe?
Edit: This does not work cross domain unless the appropriate CORS header is set.
There are two different things here: the style of the iframe block and the style of the page embedded in the iframe. You can set the style of the iframe block the usual way:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
The style of the page embedded in the iframe must be either set by including it in the child page:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
Or it can be loaded from the parent page with Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
I met this issue with Google Calendar. I wanted to style it on a darker background and change font.
Luckily, the URL from the embed code had no restriction on direct access, so by using PHP function file_get_contents it is possible to get the
entire content from the page. Instead of calling the Google URL, it is possible to call a php file located on your server, ex. google.php, which will contain the original content with modifications:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Adding the path to your stylesheet:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(This will place your stylesheet last just before the head end tag.)
Specify the base url form the original url in case css and js are called relatively:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
The final google.php file should look like this:
<?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;
Then you change the iframe embed code to:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
Good luck!
If the content of the iframe is not completely under your control or you want to access the content from different pages with different styles you could try manipulating it using 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);
Note that depending on what browser you use this might only work on pages served from the same domain.
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
Here is how to apply CSS code directly without using <link> to load an extra stylesheet.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
This hides the banner in the iframe page. Thank you for your suggestions!
If you control the page in the iframe, as hangy said, the easiest approach is to create a shared CSS file with common styles, then just link to it from your html pages.
Otherwise it is unlikely you will be able to dynamically change the style of a page from an external page in your iframe. This is because browsers have tightened the security on cross frame dom scripting due to possible misuse for spoofing and other hacks.
This tutorial may provide you with more information on scripting iframes in general. About cross frame scripting explains the security restrictions from the IE perspective.
An iframe is universally handled like a different HTML page by most browsers. If you want to apply the same stylesheet to the content of the iframe, just reference it from the pages used in there.
The above with a little change works:
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);
Works fine with ff3 and ie8 at least
The following worked for me.
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();
Expanding on the above jQuery solution to cope with any delays in loading the frame contents.
$('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();
});
use can try this:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
If you want to reuse CSS and JavaScript from the main page maybe you should consider replacing <IFRAME> with a Ajax loaded content. This is more SEO friendly now when search bots are able to execute JavaScript.
This is jQuery example that includes another html page into your document. This is much more SEO friendly than iframe. In order to be sure that the bots are not indexing the included page just add it to disallow in 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>
You could also include jQuery directly from Google: http://code.google.com/apis/ajaxlibs/documentation/ - this means optional auto-inclusion of newer versions and some significant speed increase. Also, means that you have to trust them for delivering you just the jQuery ;)
My compact version:
<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>
However, sometimes the iframe is not ready on window loaded, so there is a need of using a timer.
Ready-to-use code (with timer):
<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>
...and jQuery link:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
As many answers are written for the same domains, I'll write how to do this in cross domains.
First, you need to know the Post Message API. We need a messenger to communicate between two windows.
Here's a messenger I created.
/**
* 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);
}
}
Using this in two windows to communicate can solve your problem.
In the main windows,
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
})
Then, receive the event from the Iframe.
In the 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);
}
})
See the Complete Javascript and Iframes tutorial for more details.
Other answers here seem to use jQuery and CSS links.
This code uses vanilla JavaScript. It creates a new <style> element. It sets the text content of that element to be a string containing the new CSS. And it appends that element directly to the iframe document's head.
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);
When you say "doc.open()" it means you can write whatever HTML tag inside the iframe, so you should write all the basic tags for the HTML page and if you want to have a CSS link in your iframe head just write an iframe with CSS link in it. I give you an example:
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();
You will not be able to style the contents of the iframe this way. My suggestion would be to use serverside scripting (PHP, ASP, or a Perl script) or find an online service that will convert a feed to JavaScript code. The only other way to do it would be if you can do a serverside include.
Incase if you have access to iframe page and want a different CSS to apply on it only when you load it via iframe on your page, here I found a solution for these kind of things
this works even if iframe is loading a different domain
check about postMessage()
plan is, send the css to iframe as a message like
iframenode.postMessage('h2{color:red;}','*');
* is to send this message irrespective of what domain it is in iframe
and receive the message in iframe and add the received message(CSS) to that document head.
code to add in iframe page
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
I think the easiest way is to add another div, in the same place as the iframe, then
make its z-index bigger than the iframe container, so you can easly just style your own div. If you need to click on it, just use pointer-events:none on your own div, so the iframe would be working in case you need to click on it ;)
I hope It will help someone ;)
I found another solution to put the style in the main html like this
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
and then in iframe do this (see the js onload)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
and in js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
It may not be the best solution, and it certainly can be improved, but it is another option if you want to keep a "style" tag in parent window
Here, There are two things inside the domain
iFrame Section
Page Loaded inside the iFrame
So you want to style those two sections as follows,
1. Style for the iFrame Section
It can style using CSS with that respected id or class name. You can just style it in your parent Style sheets also.
<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. Style the Page Loaded inside the iFrame
This Styles can be loaded from the parent page with the help of Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
then set that CSS file to the respected iFrame section
//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);
Here, You can edit the Head Part of the Page inside the iFrame using this way also
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
We can insert style tag into 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>
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);
This is how I'm doing in production. It's worth bearing in mind that if the iframe belongs to other website, it will trigger the CORS error and will not work.
var $iframe = document.querySelector(`iframe`);
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
In some cases you may also want to attach a load event to the iframe:
var $iframe = document.querySelector(`iframe`);
$iframe.addEventListener("load", function() {
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
});
There is a wonderful script that replaces a node with an iframe version of itself.
CodePen Demo
Usage Examples:
// 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">'
});
As an alternative, you can use CSS-in-JS technology, like below lib:
https://github.com/cssobj/cssobj
It can inject JS object as CSS to iframe, dynamically
This is just a concept, but don't implement this without security checks and filtering! Otherwise script could hack your site!
Answer: if you control target site, you can setup the receiver script like:
1) set the iframe link with style parameter, like:
http://your_site.com/target.php?color=red
(the last phrase is a{color:red} encoded by urlencode function.
2) set the receiver page target.php like this:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Well, I have followed these steps:
Div with a class to hold iframe
Add iframe to the div.
In CSS file,
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
This works in IE 6. Should work in other browsers, do check!