竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


411月/130

Iframe高度自适应(兼容IE/Firefox、同域/跨域)

发布在 邵珠庆

在实际的项目进行中,很多地方可能由于历史原因不得不去使用iframe,包括目前正火热的应用开发也是如此。

随之而来的就是在实际使用iframe中,会遇到iframe高度的问题,由于被嵌套的页面长度不固定而显示出来的滚动条,不仅影响美观,还会对用户操作带来不便。于是自动调整iframe的高度就成为本文的重点。

采用JavaScript来控制iframe元素的高度是iframe高度自适应的关键,同时由于JavaScript对不同域名下权限的控制,引发出同域、跨域两种情况。

同域时Iframe高度自适应
下面的代码兼容IE/Firefox浏览器,控制id为“iframeid”的iframe的高度,通过JavaScript取得被嵌套页面最终高度,然后在主页面进行设置来实现。

代码如下,可复制。另外,请注意此解决方案仅供同域名下使用。

<script type="text/javascript">
 function SetCwinHeight(){
  var iframeid=document.getElementById("iframeid"); //iframe id
  if (document.getElementById){
   if (iframeid && !window.opera){
    if (iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight){
     iframeid.height = iframeid.contentDocument.body.offsetHeight;
    }else if(iframeid.Document && iframeid.Document.body.scrollHeight){
     iframeid.height = iframeid.Document.body.scrollHeight;
    }
   }
  }
 }
</script>
<iframe width="100%" id="iframeid" onload="Javascript:SetCwinHeight()" height="1" frameborder="0" src="kimi.php"></iframe>

跨域时Iframe高度自适应
在主页面和被嵌套的iframe为不同域名的时候,就稍微麻烦一些,需要避开JavaScript的跨域限制。

原理:现有iframe主页面main.html、被iframe嵌套页面iframe.html、iframe中介页面agent.html三个,通过main.html(域名为http://www.ccvita.com)嵌套iframe.html(域名为:http://www.phpq.net),当用户浏览时执行iframe.html中的JavaScript代码设置iframeC的scr地址中加入iframe页面的高度,agent.html(域名为:http://www.ccvita.com)取得传递的高度,通过JavaScript设置main.html中iframe的高度。最终实现预期的目标。

演示地址:http://www.ccvita.com/usr/uploads/demo/iframe/main.html
代码下载:http://www.ccvita.com/usr/uploads/demo/iframe/iframe.zip

 

iframe主页面main.html

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>iframe主页面</title></head>
<body>
 
<div style="border:1px solid #ccc;padding:10px;"><iframe id="frame_content"  name="frame_content" src="iframe.html" width="100%" height="0" scrolling="no" frameborder="0"></iframe></div><br />尾部<br /></body>
</html>

iframe嵌套页面iframe.html

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>被iframe嵌套页面</title></head>
<body>
 
文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />文字<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><iframe id="iframeC" name="iframeC" src="" width="0" height="0" style="display:none;" ></iframe>
 
<script type="text/javascript">
function sethash(){
    hashH = document.documentElement.scrollHeight;
    urlC = "agent.html";
    document.getElementById("iframeC").src=urlC+"#"+hashH;
}
window.onload=sethash;
</script>
 
</body>
</html>

iframe中介页面agent.html

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>iframe中介页面</title></head>
 
<body>
 
<script>
function  pseth() {
    var iObj = parent.parent.document.getElementById('frame_content');
    iObjH = parent.parent.frames["frame_content"].frames["iframeC"].location.hash;
    iObj.style.height = iObjH.split("#")[1]+"px";
}
pseth();
</script>
 
</body>
</html>

UPDATE:长期以来一直有网友说方案不能跨域,今天我重新又测试了下,确定在IE6、IE7、IE8、IE9、Firefox全系列、Chrome全系列均可以成功跨域控制高度。请注意以下要点

  • 第一,修改main.html文件中iframe的src地址为需要跨域的域名(比如ccvita.sinaapp.com)
  • 第二,修改iframe.html文件中的urlC值为源域名(比如www.ccvita.com)这点最重要
36月/130

让你的IE6、7、8 都很好的支持HTML5标签

发布在 邵珠庆

 

在旧有的浏览器里面,很多元素都是不支持的,即使解析出来也是内联标签。所以某位外国大牛就写了JS把文本中的一些标记替换成了块标签,从而解决了IE的很多历史遗留问题。这对于HTML5的使用推广来说是一个历史性的变革,也能很好的解决一些兼容性问题。

https://github.com/sebastianbergmann/php-code-coverage/pull/128

JS代码:

001 /**
002 * @preserve HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
003 */
004 ;(function(window, document) {
005 /*jshint evil:true */
006   /** version */
007   var version = '3.6.2pre';
008  
009   /** Preset options */
010   var options = window.html5 || {};
011  
012   /** Used to skip problem elements */
013   var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
014  
015   /** Not all elements can be cloned in IE **/
016   var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
017  
018   /** Detect whether the browser supports default html5 styles */
019   var supportsHtml5Styles;
020  
021   /** Name of the expando, to work with multiple documents or to re-shiv one document */
022   var expando = '_html5shiv';
023  
024   /** The id for the the documents expando */
025   var expanID = 0;
026  
027   /** Cached data for each document */
028   var expandoData = {};
029  
030   /** Detect whether the browser supports unknown elements */
031   var supportsUnknownElements;
032  
033   (function() {
034     try {
035         var a = document.createElement('a');
036         a.innerHTML = '<xyz></xyz>';
037         //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
038         supportsHtml5Styles = ('hidden' in a);
039  
040         supportsUnknownElements = a.childNodes.length == 1 || (function() {
041           // assign a false positive if unable to shiv
042           (document.createElement)('a');
043           var frag = document.createDocumentFragment();
044           return (
045             typeof frag.cloneNode == 'undefined' ||
046             typeof frag.createDocumentFragment == 'undefined' ||
047             typeof frag.createElement == 'undefined'
048           );
049         }());
050     catch(e) {
051       supportsHtml5Styles = true;
052       supportsUnknownElements = true;
053     }
054  
055   }());
056  
057   /*--------------------------------------------------------------------------*/
058  
059   /**
060 * Creates a style sheet with the given CSS text and adds it to the document.
061 * @private
062 * @param {Document} ownerDocument The document.
063 * @param {String} cssText The CSS text.
064 * @returns {StyleSheet} The style element.
065 */
066   function addStyleSheet(ownerDocument, cssText) {
067     var p = ownerDocument.createElement('p'),
068         parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
069  
070     p.innerHTML = 'x<style>' + cssText + '</style>';
071     return parent.insertBefore(p.lastChild, parent.firstChild);
072   }
073  
074   /**
075 * Returns the value of `html5.elements` as an array.
076 * @private
077 * @returns {Array} An array of shived element node names.
078 */
079   function getElements() {
080     var elements = html5.elements;
081     return typeof elements == 'string' ? elements.split(' ') : elements;
082   }
083    
084     /**
085 * Returns the data associated to the given document
086 * @private
087 * @param {Document} ownerDocument The document.
088 * @returns {Object} An object of data.
089 */
090   function getExpandoData(ownerDocument) {
091     var data = expandoData[ownerDocument[expando]];
092     if (!data) {
093         data = {};
094         expanID++;
095         ownerDocument[expando] = expanID;
096         expandoData[expanID] = data;
097     }
098     return data;
099   }
100  
101   /**
102 * returns a shived element for the given nodeName and document
103 * @memberOf html5
104 * @param {String} nodeName name of the element
105 * @param {Document} ownerDocument The context document.
106 * @returns {Object} The shived element.
107 */
108   function createElement(nodeName, ownerDocument, data){
109     if (!ownerDocument) {
110         ownerDocument = document;
111     }
112     if(supportsUnknownElements){
113         return ownerDocument.createElement(nodeName);
114     }
115     if (!data) {
116         data = getExpandoData(ownerDocument);
117     }
118     var node;
119  
120     if (data.cache[nodeName]) {
121         node = data.cache[nodeName].cloneNode();
122     else if (saveClones.test(nodeName)) {
123         node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
124     else {
125         node = data.createElem(nodeName);
126     }
127  
128     // Avoid adding some elements to fragments in IE < 9 because
129     // * Attributes like `name` or `type` cannot be set/changed once an element
130     // is inserted into a document/fragment
131     // * Link elements with `src` attributes that are inaccessible, as with
132     // a 403 response, will cause the tab/window to crash
133     // * Script elements appended to fragments will execute when their `src`
134     // or `text` property is set
135     return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
136   }
137  
138   /**
139 * returns a shived DocumentFragment for the given document
140 * @memberOf html5
141 * @param {Document} ownerDocument The context document.
142 * @returns {Object} The shived DocumentFragment.
143 */
144   function createDocumentFragment(ownerDocument, data){
145     if (!ownerDocument) {
146         ownerDocument = document;
147     }
148     if(supportsUnknownElements){
149         return ownerDocument.createDocumentFragment();
150     }
151     data = data || getExpandoData(ownerDocument);
152     var clone = data.frag.cloneNode(),
153         i = 0,
154         elems = getElements(),
155         l = elems.length;
156     for(;i<l;i++){
157         clone.createElement(elems[i]);
158     }
159     return clone;
160   }
161  
162   /**
163 * Shivs the `createElement` and `createDocumentFragment` methods of the document.
164 * @private
165 * @param {Document|DocumentFragment} ownerDocument The document.
166 * @param {Object} data of the document.
167 */
168   function shivMethods(ownerDocument, data) {
169     if (!data.cache) {
170         data.cache = {};
171         data.createElem = ownerDocument.createElement;
172         data.createFrag = ownerDocument.createDocumentFragment;
173         data.frag = data.createFrag();
174     }
175  
176  
177     ownerDocument.createElement = function(nodeName) {
178       //abort shiv
179       if (!html5.shivMethods) {
180           return data.createElem(nodeName);
181       }
182       return createElement(nodeName, ownerDocument, data);
183     };
184  
185     ownerDocument.createDocumentFragment = Function('h,f','return function(){' +
186       'var n=f.cloneNode(),c=n.createElement;' +
187       'h.shivMethods&&(' +
188         // unroll the `createElement` calls
189         getElements().join().replace(/\w+/g, function(nodeName) {
190           data.createElem(nodeName);
191           data.frag.createElement(nodeName);
192           return 'c("' + nodeName + '")';
193         }) +
194       ');return n}'
195     )(html5, data.frag);
196   }
197  
198   /*--------------------------------------------------------------------------*/
199  
200   /**
201 * Shivs the given document.
202 * @memberOf html5
203 * @param {Document} ownerDocument The document to shiv.
204 * @returns {Document} The shived document.
205 */
206   function shivDocument(ownerDocument) {
207     if (!ownerDocument) {
208         ownerDocument = document;
209     }
210     var data = getExpandoData(ownerDocument);
211  
212     if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
213       data.hasCSS = !!addStyleSheet(ownerDocument,
214         // corrects block display not defined in IE6/7/8/9
215         'article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}'+
216         // adds styling not present in IE6/7/8/9
217         'mark{background:#FF0;color:#000}'
218       );
219     }
220     if (!supportsUnknownElements) {
221       shivMethods(ownerDocument, data);
222     }
223     return ownerDocument;
224   }
225  
226   /*--------------------------------------------------------------------------*/
227  
228   /**
229 * The `html5` object is exposed so that more elements can be shived and
230 * existing shiving can be detected on iframes.
231 * @type Object
232 * @example
233 *
234 * // options can be changed before the script is included
235 * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
236 */
237   var html5 = {
238  
239     /**
240 * An array or space separated string of node names of the elements to shiv.
241 * @memberOf html5
242 * @type Array|String
243 */
244     'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video',
245  
246     /**
247 * current version of html5shiv
248 */
249     'version': version,
250  
251     /**
252 * A flag to indicate that the HTML5 style sheet should be inserted.
253 * @memberOf html5
254 * @type Boolean
255 */
256     'shivCSS': (options.shivCSS !== false),
257  
258     /**
259 * Is equal to true if a browser supports creating unknown/HTML5 elements
260 * @memberOf html5
261 * @type boolean
262 */
263     'supportsUnknownElements': supportsUnknownElements,
264  
265     /**
266 * A flag to indicate that the document's `createElement` and `createDocumentFragment`
267 * methods should be overwritten.
268 * @memberOf html5
269 * @type Boolean
270 */
271     'shivMethods': (options.shivMethods !== false),
272  
273     /**
274 * A string to describe the type of `html5` object ("default" or "default print").
275 * @memberOf html5
276 * @type String
277 */
278     'type''default',
279  
280     // shivs the document according to the specified `html5` object options
281     'shivDocument': shivDocument,
282  
283     //creates a shived element
284     createElement: createElement,
285  
286     //creates a shived documentFragment
287     createDocumentFragment: createDocumentFragment
288   };
289  
290   /*--------------------------------------------------------------------------*/
291  
292   // expose html5
293   window.html5 = html5;
294  
295   // shiv the document
296   shivDocument(document);
297  
298 }(this, document));

然后把html5shiv.js在head里面引入:

01 <!DOCTYPE HTML>
02 <html lang="en-US">
03     <head>
04         <meta charset="UTF-8">
05         <title></title>
06         <script type="text/javascript" src="html5.js"></script>
07         <style type="text/css">
08             nav {
09                 width:200px;
10                 height:100px;
11                 background:#f12;
12             }
13         </style>
14     </head>
15     <body>
16         <nav>Springload</nav>Springload
17     </body>
18 </html>

在IE8中打开查看你就会发现nav这个HTML5元素标签,可以正常使用和显示。

35月/130

使用X-UA-Compatible来设置IE浏览器兼容模式

发布在 邵珠庆

前言

为了帮助确保你的网页在所有未来的IE版本都有一致的外观,IE8引入了文件兼容性。在IE6中引入一个增设的兼容性模式,文件兼容性使你能够在IE呈现你的网页时选择特定编译模式。
新的IE为了确保网页在未来的版本中都有一支的外观,IE8引入了文件兼容性。当你引入一个增设的兼容性模式,
此文章说明文件兼容性的必要性,列出现有版本IE能使用的文件兼容性模式并示范如何选择特定的兼容性模式。
了解文件兼容性的必要性

每个主要版本IE新增的功能都是为了让浏览器更容易使用、增加安全性及更支持业界标准。以这些作为IE的特色,其中一个风险就是旧版本网站无法正确的显示。

为了将这个风险降到最低,IE6允许网页开发人员选择IE编译和显示他们网页的方式。"Quirks mode"为预设,这会使页面以旧版本浏览器的视点显示,"Standards mode"(也称为"strict mode")特点是支持业界标准最为完善。然而要利用这个增强的支持功能,网页必须包含恰当的<!DOCTYPE>指令。

若一个网页没有包含<!DOCTYPE>指令,IE6会将它以quirks mode显示。若网页包含有效的<!DOCTYPE>指令但浏览器无法辨识,IE6会将它以IE6 standards mode显示。因为少数网站已经包含<!DOCTYPE>指令,兼容性模式的切换相当成功。这使网页开发人员能选择将他们的网页转移为standards mode的最佳时机。

随著时间经过,更多网站开始使用standards mode。它们也开始使用IE6的特性和功能来检测IE。举例来说,IE6不支持universal selector(即css之全局选择器 * {}),一些网站便使用它来针对IE做特定的对应。

当 IE7增加了对全域选择器的支持,那些依赖IE6特点的网站便无法侦测出这个新版本的浏览器。因此那些针对IE的特定对应无法应用于IE7,造成这些网站便无法如他们预期的显示。由于<!DOCTYPE>只支持两种兼容性模式,受到影响的网站拥有者被迫更新他们的网站使其能支持IE7。

IE8 比之前的任何版本浏览器都更支持业界标准,因此针对旧版本浏览器设计的网页可能无法如预期般呈现。为了帮助减轻所有问题,IE8引入文件兼容性的概念,使你能选择你的网页设计要对应的特定IE版本。文件兼容性在IE8增加了一些新的模式,这些模式能告诉浏览器如何解析和编译一个网页。若你的网页无法在 ie8正确的显示,你可以更新你的网站使它支持最新的网页标准(优先选项)或在你的页面上新增一个meta元素用于告诉IE8如何依照旧版本浏览器编译你的页面。

这能让你选择将你的网站更新支持IE8新特点的时机。
认识文件兼容性模式

IE8支持几种文件兼容性模式,它们具有不同的特性并影响内容显示的方式。

•Emulate IE8 mode指示IE使用<!DOCTYPE>指令来决定如何编译内容。Standards mode指令会显示成IE8 Standards mode而quirks mode会显示成IE5 mode。不同于IE8 mode,Emulate IE8 mode重视<!DOCTYPE>指令。
•Emulate IE7 mode指示IE使用<!DOCTYPE>指令来决定如何编译内容。Standards mode指令会显示成IE7 Standards mode而quirks mode会显示成IE5 mode。不同于IE7 mode,Emulate IE7 mode重视<!DOCTYPE>指令。对于许多网页来说这是最推荐的兼容性模式。
•IE5 mode 编译内容如同IE7的quirks mode之显示状况,和IE5中显示的非常类似。
•IE7 mode编译内容如同IE7的standards mode之显示状况,无论网页是否含有<!DOCTYPE>指令。
•IE8 mode提供对业界标准的最高支持,包含 W3C Cascading Style Sheets Level 2.1 SpecificationW3C Selectors API,并有限的支持 W3C Cascading Style Sheets Level 3 Specification (Working Draft)
•Edge mode指示IE以目前可用的最高模式显示内容。当使用IE8时其等同于IE8 mode。若(假定)未来放出支持更高兼容性模式的IE,使用Edge mode的页面会使用该版本能支持的最高模式来显示内容。同样的那些页面在使用IE8浏览时仍会照常显示。

由于edge mode使用该IE版本所能支持的最高模式来显示所浏览的网页内容,建议仅使用于测试页及其他非商用页面。
指定文件兼容性模式

要为你的网页指定文件模式,需要在你的网页中使用meta元素放入X-UA-Compatible http-equiv 标头。以下是指定为Emulate IE7 mode 兼容性之范例。

<html>
<head>
<!-- Mimic Internet Explorer 7 -->
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>My Web Page</title>
</head>
<body>
<p>Content goes here.</p>
</body>
</html>

其内容随著指定的页面模式而更改,当要模拟IE7时,指定IE=EmulateIE7,指定IE=5IE=7, 或IE=8来选择其中一种兼容性模式。你也可以指定IE=edge来指示IE8使用它支持的最高模式。

X-UA-compatible标头没有大小写之分。然而除了title元素及其他的meta元素之外,它必须出现在网页header节其它元素之前的位置,
设定网站服务器以指定预设兼容性模式

网站管理员可籍着为网站定义一个自订标头来为他们的网站预设一个特定的文件兼容性模式。这个特定的方法取决于你的网站服务器。举例来说,下列的web.config文件使Microsoft Internet Information Services (IIS)能定义一个自订标头以自动使用IE7 mode来编译所有网页。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="X-UA-Compatible" value="IE=EmulateIE7" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

若你已于网站服务器指定了一个预设的文件兼容性模式,你可以在个别页面上指定不同的文件兼容性模式来盖过它。在网页中指定的模式优先权高于服务器中所指定的模式。

请查阅你的网站服务器关于指定自订标头的资讯,或看更多资料:

Implementing the META Switch on Apache
Implementing the META Switch on IIS
判定文件兼容性模式

要判定网页使用IE8浏览时的文件兼容性模式,使用document object(文档对象)的documentMode功能。例如在IE8的网址列输入下列程式码会显示目前页面的文件模式。

javascript:alert(document.documentMode);

documentMode功能会回传一个数值对应目前页面的文件兼容性模式,举例来说,若网页指定为支持IE8模式,documentMode便会回传值"8"。

在IE6引入的compatMode功能不支持在IE8引入的documentMode功能。目前使用compatMode建立的应用程式还能在IE8中作用,但它们必须更新为使用documentMode。

若你希望使用JavaScript判定一个文件的兼容性模式,引入下面范例的这段程式码可支持旧版本的IE。

engine = null;
if (window.navigator.appName == "Microsoft Internet Explorer")
{
// This is an IE browser. What mode is the engine in?
if (document.documentMode) // IE8
engine = document.documentMode;
else // IE 5-7
{
engine = 5; // Assume quirks mode unless proven otherwise
if (document.compatMode)
{
if (document.compatMode == "CSS1Compat")
engine = 7; // standards mode
}
}
// the engine variable now contains the document compatibility mode.
}

认识内容属性值

内容属性值在接收到异于先前叙述的数值时是具有弹性的。这能使你对于IE如何显示你的网页更有操控性。举例来说,你可以设定内容属性值为IE=7.5。当你这样做的时候,IE尝试将这个值转换为version vector并选择最接近的结果。在这个例子中,IE会将其设定为IE7 mode。下面的范例显示该模式设定为其他值的状况。

<meta http-equiv="X-UA-Compatible" content="IE=4"> <!-- IE5 mode -->
<meta http-equiv="X-UA-Compatible" content="IE=7.5"> <!-- IE7 mode -->
<meta http-equiv="X-UA-Compatible" content="IE=100"> <!-- IE8 mode -->
<meta http-equiv="X-UA-Compatible" content="IE=a"> <!-- IE5 mode --> 

<!-- This header mimics Internet Explorer 7 and uses
<!DOCTYPE> to determine how to display the Web page -->
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">

注意: 前面的范例显示单独的内容值。实际上IE只会执行网页中第一个X-UA-Compatible标头。

你也可以使用内容属性来指定复数的文件兼容性模式,这能帮助确保你的网页在未来的浏览器版本都能一致的显示。欲设定复数的文件模式,请设定内容属性以判别你想使用的模式。使用分号来分开各个模式。

如果一个特定版本的IE支持所要求的兼容性模式多于一种,将採用列于标头内容属性中最高的可用模式。你可以使用这个特性来排除特定的兼容性模式,虽然并不推荐这样做。举例来说,下列标头即会排除IE7 mode。

<meta http-equiv="X-UA-Compatible" content="IE=5; IE=8" />

结论

兼容性对于网页设计师来说是非常重要的顾虑。虽然最好是可以建立一个完全不需依赖任何网页浏览器特性或功能的网站,有时候这是不可能实现的。文件兼容性模式便能将网页限制在某个特定版本的IE中。

使用X-UA-Compatible标头来指定你的页面支持的IE版本。使用document.documentMode判定页面的兼容性模式。

选择支持某个特定版本的IE,你可以确保你的页面在未来的浏览器版本中也能有显示的一致性。