Main web page in standard mode, iframe in compatib

2019-03-22 16:43发布

问题:

We have some legacy HTML content which we must render in compatibility mode. The requirement comes from our customers who want their HTML-based reports (some of which were created back in IE6 days) to look and print exactly the same, regardless of the browser version or underlying technologies. At the same time, we want to use Standard Mode and HTML5 for the rest of our web app.

An obvious solution is to host the legacy content in an <iframe> in compatibility mode. The following appears to work cross-browser:

main.html (in standard mode):

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title></title>
    <style type="text/css">
        body {
            font-family: Arial;
            font-size: 9pt;
            font-style: italic;
            font-weight: bold;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            info.firstChild.data = "document.compatMode: " + document.compatMode;
            // test frame's HTML5 API: document.getSelection()
            setInterval(function () {
                var selection = document.getElementById("contentFrame").contentDocument.getSelection();
                var selectedNode = selection.focusNode;
                if (selectedNode)
                    info2.firstChild.data = "Selected node: " + selectedNode.nodeName + ", offset: " + selection.focusOffset;
                else
                    info2.firstChild.data = "";
            }, 500);

        }
    </script>
</head>
<body>
    <h1>Standard Mode Page</h1>
    <span>body font</span>
    <table border="1">
        <tr>
            <td>Table font</td>
        </tr>
    </table>
    <span>body font</span>
    <pre id="info">&nbsp;</pre>
    <pre id="info2">&nbsp;</pre>
    <iframe id="contentFrame" style="width: 500px; height: 300px;" src="frame.html"></iframe>
</body>
</html>

frame.html (in compatibility mode):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "">
<html>
<head>
    <title></title>
    <style type="text/css">
        body {
            font-family: Arial;
            font-size: 9pt;
            font-style: italic;
            font-weight: bold;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            info.firstChild.data = "document.compatMode: " + document.compatMode;
            editable.focus();
        }
    </script>
</head>
<body>
    <h1>Compatibility Mode Frame</h1>
    <span>body font</span>
    <table border="1">
        <tr>
            <td>Table font</td>
        </tr>
    </table>
    <span>body font</span>
    <pre id="info">&nbsp;</pre>
    <div id="editable" contentEditable="true" style="border: 1px dotted red">
        Editable
    </div>
</body>
</html>

Note the difference in rendering the table, using the same CSS:


My question to experienced web developers: is this a supported scenario which can be used in production environment (IE8+ mostly, but occasionally Safari/Chrome/Firefox)? Is there a better way of doing this?

I've stumbled upon a related, albeit opposite question, which left me with mixed feelings.

[UPDATE] (based on the comments):

All JavaScript resides inside the main page and appears to work just fine. What's interesting (and great!), the inner frame's view is rendered in compatibility mode, yet standard mode features are available for its DOM (at least, when accessed from the main page). E.g. document.getSelection works (and does cross-browsers, too).

By supported scenario I mean any endorsement by W3C HTML and DOM standards. So far I haven't found a definitive answer to this. This behavior may as well be just a nice side effect, although the fact it works cross-browsers is promising.

MSDN says the following: As of IE9 mode, webpages cannot display multiple document modes. For example, consider a standards-based webpage that contains a frame element that displays content in quirks mode. IE9 mode displays the child frame in standards mode (because the parent document is in standards mode). According to my tests, this is not true; my sample works as desired in IE9: the main page is in standard mode, the frame page is in quirk mode. [EDITED] As pointed out in the comments, it is the Almost Standard Mode (i.e., not the classic quirk mode), with its own rendering rules.

回答1:

As of IE9 mode, webpages cannot display multiple document modes. For example, consider a standards-based webpage that contains a frame element that displays content in quirks mode. IE9 mode displays the child frame in standards mode (because the parent document is in standards mode).

According to my tests, this is not true; my sample works as desired in IE9: the main page is in standard mode, the frame page is in quirk mode.

Not quite; when your sample works as desired it's actually displayed in a single display mode, with quirks mode emulated for the frame content. You shouldn't care about the underlying mechanics as long as the resulting output matches what you were after, although there is some anecdotal evidence of differences between emulated and native modes (mostly to do with js DOM manipulation).

I'd be a bit more concerned about how IE10+ would handle such fringe scenarios:

Starting with IE11 Preview, document modes are deprecated and should no longer be used, except on a temporary basis. Make sure to update sites that rely on legacy features and document modes to reflect modern standards.

Ninja edit: looks like this has already been resolved on SO; modifying the accepted solution to your needs you should omit Doctype and add <meta http-equiv="X-UA-Compatible" content="IE=5" />; X-UA-Compatibility correctly defined as per msdn spec



回答2:

This is a pseudo-answer to your slightly non-specific question;

In regards to your apprehension to rely on this IE feature for "back-compatibility", I feel the same way. Microsoft has provided this option because there are lots of companies out there who take a long time to update their web content. This option is meant to allow them to have a quick and dirty stop-gap, not a permanent solution.

So, what's the permanent solution? If that is your question, then IMO this is the answer; don't rely on the stop-gap and develop the correct output for the reports.

Without knowing what those reports are it is impossible to properly advise you on that part, but here's a stab in the dark:

There are lots of options to convert "HTML" to PDF. (I put HTML in quotations because each rendering engine is bound to require different versions/standards of HTML and you'll need to know those assumptions before you pick one.) If you want output that will format 100% the same on any browser, then you want a format that is meant to be static and not change; like PDF. Plus, then you also have the printing options taken care of as well.