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?

3
  • JavaScript is by no means needed to do this. Is there a reason why you are looking for a jQuery solution for this? why not just include the different files in the actual iFrame? Commented Dec 24, 2010 at 15:02
  • @Derek: Perhaps he's not in control of the iframe. I mean, I can put Google in an iframe... Commented Dec 24, 2010 at 15:06
  • right, that's why I asked. it could be anything! Commented Dec 24, 2010 at 15:07

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Or you could test simply window==window.top.
@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: w3.org/TR/Window), and that IE fails if you use a strict comparator (===).
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)

5 Comments

You give the sexiest answers T.J.
@Derek: Crikey. Now, that's something no one's ever said to me before on StackOverflow!
Every answer i see of yours is like a freaking essay! it's awesome.
what does self !== self.parent do? and what is self?
@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 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.)
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.