1

I am using two css files.

file1.css, file2.css

Question: when user see my page i need to use file1.css, when user see mypage inside an iframe i need to use only file2.css.

What is possible way to do this?

Mohan Ram
  • 8,345
  • 25
  • 81
  • 130

3 Answers3

4
var fileToUse = (window.location != window.parent.location) ? "file1.css" : "file2.css";
$('<link rel="stylesheet" type="text/css" href="' + fileToUse + '"/>').appendTo("head");

I can't test it right now but that should do it.

Ege Özcan
  • 13,971
  • 2
  • 30
  • 51
  • Or you could test simply `window==window.top`. – Phrogz Dec 24 '10 at 14:29
  • @Phrogz: Probably `window == window.parent`, but it probably comes to the same thing. I was **very** surprised to find that `window.parent` never seems to be `null` (which is even in the most recent spec: http://www.w3.org/TR/Window/), and that IE fails if you use a strict comparator (`===`). – T.J. Crowder Dec 24 '10 at 14:47
2

Here's a slightly different approach: Always include one of the CSS files, without using JavaScript, and then if you see that you're in an iframe, also include the other CSS file. Obviously you'd have to author the files with this in mind, but conflicting settings in the two files will be resolved in favor of the second one if all else is equal, so it can override the first. (This can be tricky and requires testing, "if all else is equal" covers a number of sins.)

My reasoning is that not everyone has JavaScript enabled — it's almost fashionable to browse with NoScript and similar, and only enable scripting on sites you trust. So you want to make sure things look good, iframe or no, if the user has scripting disabled.

First things first, though: How do you check whether you're in a frame? IE has a nasty "gotcha" here, so it's worth saying:

// This works (note the !==):
if (self !== self.parent) {
    // You're in a frame/iframe
}

// This also works (note the !=, NOT !==):
if (window != window.parent) {
    // ...
}

// This FAILS on Internet Explorer (note the !==):
if (window !== window.parent) {
    // ...
}

I have no idea why that last one fails on IE (bobince seems to think he does, though, here; I have to look into it more before I'm convinced), self should === window (and the latest draft spec says it should). But in any case, it does fail on IE. So pick either of the first two and use it.

In terms of actually doing it, here are three versions, all assumed to be inside the head section of a document:

Version 1: Using document.write:

<link rel='stylesheet' type='text/css' href='mainfile.css'>
<script type='text/javascript'>
    if (self !== self.parent) {
        document.write("<link rel='stylesheet' type='text/css' href='framestyle.css'>");
    }
</script>

Some may cringe at the document.write there, but this is the one place where I believe it's acceptable. Note, though, that you can't do this in XHTML, just HTML.

Version 2: Using a dynamically-created link element and jQuery:

(Naturally, this has to be after your script tag loading jQuery.)

<link rel='stylesheet' type='text/css' href='mainfile.css'>
<script type='text/javascript'>
    if (self !== self.parent) {
        jQuery("<link rel='stylesheet' type='text/css' href='framestyle.css'/>").appendTo('head:first');
    }
</script>

I'm always nervous about doing DOM manipulation early in the page parsing, but the above seems to work reliably in IE6 and IE7 on Windows, and Chrome, Firefox, and Opera on Linux. So it may well be fine. Example: http://jsbin.com/osuzo3

Version 3: Using a dynamically-created link element without jQuery:

Perhaps you like to load the jQuery script further down in your document, not in the head, or you just want to make sure the CSS happens as early as possible. The straight DOM manipulation isn't hard:

<link rel='stylesheet' type='text/css' href='mainfile.css'>
<script type='text/javascript'>
    (function() {
        var link, list;
        if (self !== self.parent) {
            link = document.createElement('link');
            link.type = "text/css";
            link.rel = "stylesheet";
            link.href = "framestyle.css";
            list = document.getElementsByTagName('head');
            if (list.length > 0) {
                list[0].appendChild(link);
            }
        }
    })();
</script>

Live example (without the frame detection, just of adding the link element)

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • You give the sexiest answers T.J. – Derek Adair Dec 24 '10 at 15:37
  • 1
    @Derek: Crikey. Now, *that's* something no one's ever said to me before on StackOverflow! – T.J. Crowder Dec 24 '10 at 15:48
  • Every answer i see of yours is like a freaking essay! it's awesome. – Derek Adair Dec 24 '10 at 17:44
  • what does self !== self.parent do? and what is self? – Derek Adair Dec 24 '10 at 17:46
  • @Derek: *"and what is self"* Well, *yesterday* I would have told you that `self` was a synonym for `window`. Apparently not, despite what the [draft W3 spec](http://www.w3.org/TR/Window/#window-basic-attributes) says. But basically, `self` is the current window. Mostly. So `self !== self.parent` is checking to see if this is the top-level window, because the `parent` property points to the parent window or back to the window itself if there is no parent. (Would I have designed it that way? No. But that's how it is.) – T.J. Crowder Dec 24 '10 at 17:51
1
var stylesheet = (top === self) ? "file1.css" : "file2.css";
$('<link rel="stylesheet" type="text/css" href="' + stylesheet + '"/>').appendTo("head");  

or

$('<link rel="stylesheet" type="text/css" href="' + ((top === self) ? "file1.css" : "file2.css") + '"/>').appendTo("head");

here is the jsfiddle of the results:

link text