前端面霸系列(1):doctype 、Quirks Mode & Standards Mode 、document.compatMode

  近几日,气压猛降,雾霾铺天盖地,眼看一场腥风血雨就要在前端江湖爆发,这场战争不仅是百度、腾讯、阿狸、搜狐网易新浪等江湖豪门抢夺人才的大战,也是诸位江湖人士重新洗牌的好时机。每年10月,江湖的波动胜过华山论剑、五岳争主。如今这江湖人才济济,新门派如雨后春笋,江湖高手更是各个身怀绝技。在博客园这个擂台上更是齐聚各路高手。本人wisdomoon是一名懒人,没有"汤姆大叔"的盖世神功,也没有"T2噬菌体"的严谨细腻,更没有"Aaron"的精益求精,因此本人为大家献上的不是怒秀技巧的《葵花宝典》、不是移花接木的《辟邪剑谱》、也不是磨砺内力的《易筋经》而是"投机取巧"的《前端面霸系列》。阅完此系列,诸位会略知各门派开山祖师的入门绝技,如果运用自如,能顺利潜入任何门派,到时学一家之长不在话下。

  由于是第一篇,以上所述就当引言。本秘籍将采用Q&A(Question and Answer)的方式带大家一览各派问题。本文更适合前端的浪子阅读,如大师偶读此文,可多赐教。

  Q:doctype的作用是什么,你知道多少种类型的doctype

  A: 最简单也最常见的回答是:doctype是DocumentType的简称即文档类型,常见的有 Strict、Transitional 以及 Frameset 三种。一般一个问题后面会有"为什么"、"会导致什么",这才是这道题目的关键。文档为什么要分类型?如果文档不分类型,各浏览器就会形成多种写法,假如IE用<title>标签作为标题、火狐浏览器用<caption>标签作为标题,而另一种浏览器可能采用<mytitle>,这对于开发者和用户来说简直是灾难。这时候神僧W3C(万维网联盟World Wide Web Consortium)已经把自己偷偷熬夜制作的对所有方面都平衡的分歧解决方案拿了出来,各浏览器一看内心计算片刻之后纷纷表示没有异议。于是我们用<!doctype>(注意:作为一个特殊的标签,它是不需要闭合的)标签来引入W3C的dtd文件,以达到规范页面的效果。此举壮大了w3c组织,同时、浏览器的文档标准的统一也为开发人员和用户带了了便利。 这里需要提出的是html5不是基于SGML实现的,因此html不需要引入DTD,所以html5可以简单的声明一下<!doctype html>。

  Q:如果不声明doctype?

  A:这也就是上面所述的"会导致什么"。如果不声明doctype,浏览器不引入w3c的标准,那么早期的浏览器会按照自己的解析方式渲染页面。我们把不使用w3c标准解析,采用自身方式解析页面的行为称为"quirks mode",相反的,采用w3c方式解析就是"strict mode"也就是我们说的"standards mode"。我们知道凡事不可能太完美,如果完全采用strictmode那么不允许出任何的差错,这样会降低程序的容错率,加重开发人员的难度,因此在standards mode 里面我们又分出来 Almost Standards Mode(接近标准模式),如下图:

  

   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN "http://www.w3.org/TR/html4/loose.dtd">在html4中我们引入最多的就是接近标准的Transitional 文档类型。这两个问题考察了我们是否深入理解doctype的类型,是否理解浏览器的解析和渲染规则。还请多多揣摩。

  这个问题的最直接答案是:不写doctype,浏览器会进入quirks mode (混杂模式)

  Q:如何判断浏览使用哪种方式解析css

  A:这其实是上面问题的复习和延伸。直接给出答案:

    1、没有doctype声明的采用quirks mode解析

    2、对于有doctype的大多数采用standard mord(这里为什么用大多数,请读者思考,请参考http://hsivonen.iki.fi/doctype/

    3、特殊情况:

      a、对于那些浏览器不能识别的doctype ,浏览器采用quirks mode

      b、没有声明DTD或者html版本声明低于4.0采用quirks mode其他使用standard mode

      c、你能看到的现在的大多数网页采用的是standard mode

      d、ie6中,如果在doctype声明前有一个xml声明(比如:<?xml version="1.0" encoding="iso-8859-1"?>),则采用quirks mode解析。(这点估计连面试官都没       注意)

  Q:说出quirks mode 和 strict mode 在浏览器上的表现差异?

  A:他们最大的不同是对盒模型(由于本人对盒模型理解模糊,再加上盒模型是笔试、面试常见题目,后面会专门来一期一期探讨)的解析。

    在strict mode中 :width是内容宽度 ,也就是说,元素真正的宽度 = margin-left + border-left-width + padding-left + width + padding-right + border-right- width +  margin-right;

    在quirks mode中 :width则是元素的实际宽度 ,内容宽度 = width - (margin-left + margin-right + padding-left + padding-right + border-left-width +  border-right-width)

  Q:js如何判断浏览器正在以何种方式解析?

  A:这道问题的答案很简答,但是重要的往往不是答案。重要的是要知道为什么?"到底是为什们呢?"这是我和朋友最喜欢开玩笑的口语,再以后的文中会经常遇到。好了,回归正传,这里打算用一个例子说明。

jiathis的源代码中有如下细节:

    

     var d = document,
         isStrict = d.compatMode == "CSS1Compat",
         dd = d.documentElement,
         db = d.body
         /*省略一部分无关代码*/
      return {
            h: (isStrict ? dd : db).clientHeight,
            w: (isStrict ? dd : db).clientWidth
       }    

看到这里本题的答案也出来了使用 document.compatMode来判断浏览器的解析方式,代码如下

function getMode{
    var _cm = docoment.compatMode;
    if(_cm == 'CSS1Compat'){
         return "strict"
    } 
    if(_cm == 'BackCompat' ){
         return  'quirks'
    } 
}

      在quirks 模式下,下document.documentElement无法正确取到clietHeight scrollHeight等值,比如clietHeight=0,此时计算页面高度的时候需要用document.body来代替

document.documentElement. 如果页面开发者忘了写<!doctype>或者书写有误,那么计算页面可见区域高度时最好做如上判断。很多源代码计算页面高度的时候都使用了和jiathis类似的处理方式。

  补充一下document.body是DOM中Document对象里的body节点, document.documentElement是文档对象根节点(html)的引用。 document.body.scrollHeight是body元素的滚动高度,document.documentElement.scrollHeight为页面的滚动高度。

  Q:何时使用document.body 何时使用document.documentElement

  A:这是免费送大礼,看了上面的同志都轻而易举。

   转载请说明出处:http://www.cnblogs.com/wisdomoon/p/interview1.html

posted on 2013-10-01 17:02  wisdomoon  阅读(2618)  评论(10编辑  收藏  举报

导航