How can you force IE to render in standards mode if you only have control of the contents of body?
Asked Answered
C

3

6

I have a peculiar situation where I am only given control of the contents of a document's <body>. The host, I assume in an effort to remain flexible, is not declaring a doctype which will throw IE into quirks mode immediately. With my limited control over the document, what can I do to force IE to render the page in standards mode?

Congruent answered 1/8, 2010 at 22:29 Comment(0)
C
4

I believe you can't do anything about it unless you say, rewrite the contents of the page dynamically with JS and forcefully insert a doctype.

Can you go into specifics of how much control you have over the <body>? Are you allowed to do JS/scripting?

EDIT: Here's an attempt but I didn't test it in IE. It may give you ideas. I document.write() the outerHTML of document.documentElement and it turns the compatMode into CSS1Compat.

You may need to strip out the script block upon rewrite. Like I said, I wouldn't really recommend trying this...

http://medero.org/first-line.html

EDIT #2: It seems to surprisingly work in IE6. But upon refresh, IE caches it somehow and it permanently stays in its .document.write()ed form. To counter that, append it with a query string, eg ?203984234.

Again, I'm not sure what your situation is, but I hope this gives you ideas or helps.

EDIT #3: I rewrote it and bound the document.write to window.onload. You will need to append a unique query string every time you visit it to see the effect, because it caches it after it .write's it.

http://medero.org/rewrite.html?f30324433322111

If you need something more instantaneous you can probably jack jQuery's DOM ready function to rewrite it before the window loads.


Miscellaneous Notes:

  • You could probably hide the entire html document through CSS until the document.write is invoked if visually it matters
  • You should probably strip the <script> document.write before saving outerHTML so that the newly written page doesn't have the script block.
Cheesy answered 1/8, 2010 at 22:33 Comment(12)
I doubt this will work. The page has already rendered. If you dynamically add a doctype, IE will have to detect that and choose to rerender the page. If IE was capable of doing that, I would think it's document.documentMode property would not be read only.Gleesome
Interesting, it looks like it actually works, as scary as that is. Add a div with margin and padding and watch it change size as IE's box model changes.Gleesome
Wow! Horrible, but magnificent! ;-)Camphor
Turns out document.write may be useful for something after all, eh?Cheesy
That is one magnificent hack. I can do anything I want in the body, but unfortunately the html is being hosted in an iframe, and I have no control over the source URL, so querystring cache busting is out.Congruent
I'm confused now. Please provide an example?Cheesy
Ah I see now, I should've actually tested it in IE before commenting. :) What is cached is the state I want so being able to control the url for cache busting is not necessary. Correct?Congruent
For testing you'll need the query string to see the difference, but once the document.write is done the first time, it becomes cached om OE so in further refreshing it "sticks" so you don't need to do the query string anymore because the cached file now has the DOCTYPE.Cheesy
Ok, so I've come up with an example page that includes a show-stopper: gould.in:8081/quirks.html In IE, $ (jQuery) will be undefined after the compatMode change.Congruent
It's defined for me. Are you sure? Screenshot please.Cheesy
imgur.com/2RCnl.png You should see the "jQuery Lives" alert twice, with the original compatMode, once after. You'll notice you don't even get the 2nd compatMode alert because IE broke on jQuery before it got to it.Congruent
Conflicts with jQuery somehow. So my jQuery code is run twice. Any fix for that?Selfsufficient
I
1

Have a look at this Defining Document Compatibility article on MSDN. Perhaps writing out the X-UA-Compatible meta tag will work.

Icing answered 1/8, 2010 at 22:39 Comment(1)
Late to the party, but I just tried the X-UA-Compatible meta and it worked. I got lucky when I tried it though… apparently you have to put it near the beginning of your HEAD tag ("The X-UA-Compatible header is not case sensitive; however, it must appear in the header of the webpage (the HEAD section) before all other elements except for the title element and other meta elements." goo.gl/xe3Ff). Also, IE "caches" the rendering mode for as long as the browser window is open, so try closing and opening your window. I have control over the HEAD tag though… original poster didn't.Classicism
S
0

Here's how I managed to solve it, based on meder's answer.

I first tried writing out the X-UA-Compatible meta but that didn't work.

At the end of the document (or in the head, but I didn't have access to that either):

<script type="text/javascript">
if (navigator.appName == 'Microsoft Internet Explorer'){
    window.onload=function(){
        if (document.documentMode == 5){
            contents = document.documentElement.outerHTML;
            newdoc = document.open("text/html", "replace");
            newdoc.writeln('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'); 
            newdoc.write(contents);
            newdoc.close();
        }
    };
}
</script>

The inner if is to prevent an infinite loop. It would probably better to strip out the code itself, say by putting it in a function and removing the function call with string.replace(), but I couldn't get that to work so had to settle for this.

Skolnik answered 1/12, 2011 at 15:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.