1. 程式人生 > >瀏覽器有關的寬高詳解

瀏覽器有關的寬高詳解

簡介

window物件表示瀏覽器開啟的視窗(可以省略,全域性變數掛載在window物件下,alert,confirm等方法)。document物件是HTML文件,是window物件的一部分(document.body可以寫成window.document.body)。

與window有關的寬高介紹

window.innerHeight和window.outerHeight的區別在於,前者是瀏覽器內部文件的高度,後者是整個瀏覽器視窗的高度。window.innerWidth和window.outerWidth一般相同。
window.screen代表使用者的螢幕。window.screen.height代表整個螢幕的高度,window.screen.availHeight代表螢幕中可利用的高度(比前者少了一個選單欄)。window.screen.width和window.screen.availWidth相同。
screenTop代表瀏覽器距離螢幕頂部的距離,screenLeft為瀏覽器距離螢幕左邊的距離.

相容性問題

window.innerHeight和window.innerWidth(可視區域)在IE8及其以下瀏覽器是不支援的。所以我們要使用這樣的相容方案

   var seeWidth = document.ducumentElement.clientWidth ||
      document.body.clientWidth;
   var seeHeight = document.ducumentElement.clientHeight ||
      document.body.clientHeight;

documentElement

document是文件元素,nodeType = 9,nodeName = #document。documentElement的nodeType = 1, nodeName = HTML。
body既可以通過document.body拿到,也可以通過documentElement的childNodes得到。

document的寬高

這裡我們分成三部分:

  • 與client相關的寬高
  • 與offset相關的寬高
  • 與scroll相關的寬高

與client相關的寬高

元素.clientWidth和元素.clientHeight指的是元素的可視部分寬度和高度,即padding + content。(注意如果元素被隱藏了,他的寬高就沒有值)。如果沒有滾動條,即為元素設定的高度和寬度。如果出現滾動條(比如元素overflow: scroll),那麼該屬性就是其本來寬高減去滾動條的寬高。舉一個栗子:

   body {
      border: 20px solid #ccc;
      margin: 10
px; padding: 40px; background: red; height: 350px; width: 500px; overflow: scroll; } //430(350 + 80) console.log(document.body.clientHeight); //580,不包含border console.log(document.body.clientWidth);

那麼我們再來看一個div

   #main {
      width: 200px;
      height: 200px;
      background: red;
      border: 1px solid #000;
      overflow: auto;
   }
   //我們在div中不斷新增文字直到出現滾動條
   var div = document.getElementById('main');
   //200
   console.log(div.clientHeight);
   //在windows下是183,在mac下是200(滾動條沒顯示的時候)
   console.log(div.clientWidth);

那麼我們總結一下

   //假如無padding無滾動
   clientWidth = style.width
   //假如有padding無滾動
   clientWidth = style.width + style.padding * 2;
   //假如有padding有滾動,且滾動是顯示的
   clientWidth = style.width + style.padding * 2 - 滾動軸寬度

IE6以上瀏覽器都支援clientHeight和clientWidth。
元素的clientLeft和clientTop這兩個返回的是元素周圍邊框的厚度,如果不指定一個邊框或者不定位該元素,它的值就是0

    body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //20, clientTop = border-top的border-width
   console.log(document.body.clientLeft);
   //20,clientLeft = border-left的border-width
   console.log(document.body.clientTop);

與offset相關的寬高

offsetWidth和offsetHeight指的是元素的border + padding + content的寬度和高度,該屬性和內部的內容是否超出元素大小無關,只和本來設定的border以及width和height有關,還是上面的栗子

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //470(350 + 80 + 40)
   console.log(document.body.offsetHeight);
   //620
   console.log(document.body.offsetWidth);

offsetWidth和offsetHeight所有瀏覽器的支援一致。
offsetLeft和offsetTop是基於offsetParent的。對於offsetParent,如果當前元素的父級元素沒有進行CSS定位(position為absolute或relative),offsetParent為body,如果當前元素的父級元素中有CSS定位,offsetParent就取最近的那個父級元素。

   //在IE6/7中
   offsetLeft = (offsetParent的padding-left) + (當前元素的margin-left);
   //在IE8/9/10及Chrome中
   offsetLeft = (offsetParent的margin-left) + (offsetParent的border寬度) + (offsetParent的padding-left) + (當前元素的margin-left);
   //在firefox中
   offsetLeft = (offsetParent的margin-left) + (offsetParent的padding-left) + (當前元素的margin-left)

還是剛才的栗子

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   #main {
      width: 400px;
      height: 200px;
      background: red;
      padding: 20px;
      margin: 10px;
      border: 20px solid #000;
      overflow: auto;
   }
   //我們在div中不斷新增文字直到出現滾動條
   var div = document.getElementById('main');
   //在IE6/7中
   console.log(div.offsetLeft);  //50
   console.log(div.offsetTop);   //50
   //在IE8/9/10及Chrome中
   console.log(div.offsetLeft);   //80
   console.log(div.offsetTop);    //80
   //在firefox中
   console.log(div.offsetLeft);  //60
   console.log(div.offsetTop);   //60

與scroll相關的寬高

document.body的scrollWidth和scrollHeight與普通元素如div的scollWidth和scrollHeight是有點區別的

   body {
      border: 20px solid #ccc;
      margin: 10px;
      padding: 40px;
      background: red;
      height: 350px;
      width: 500px;
      overflow: scroll;
   } 
   //瀏覽器高度
   document.body.scrollHeight 
   //瀏覽器寬度
   document.body.scrollWidth 

當給定的寬高小於瀏覽器視窗,document.body.scrollWidth通常是瀏覽器視窗的寬度,document.body.scrollHeight 通常是瀏覽器視窗的高度。如果給定寬高大於瀏覽器視窗,且內容小於給定寬高,document.body.scrollWidth = 給定的寬度 + 其所有的padding、margin和border。如果給定寬高大於瀏覽器視窗,且內容大於給定寬高,document.body.scrollWidth = 內容的寬度 + 其所有的padding、margin和border。(有相容性問題,上述是Chrome瀏覽器中)
接下來我們看一下普通元素如div中的scrollWidth

   #main {
      width: 400px;
      height: 200px;
      background: red;
      padding: 20px;
      margin: 10px;
      border: 20px solid #000;
      overflow: auto;
   }
   var div = document.getElementById('main');
   //200 + 20 * 2 = 240
   console.log(div.scrollWidth);
   //440 + 20 * 2 = 440
   console.log(div.scrollHeight);
   //接下來我們填充div的內容使其出現滾動軸

我們得出這樣一個結論

   //在無滾動軸的情況 
   scrollWidth = clientWidth = style.width + style.padding * 2;
   //在有滾動軸的情況下(實際內容超出了定義的寬)
   scrollWidth = 實際內容的寬度 + padding * 2;

scrollLeft和scrollTop是可讀寫的,指的是當元素內容超出其寬高的時候,元素被捲起的高度和寬度。

   #main {
      width: 400px;
      height: 200px;
      background: red;
      padding: 20px;
      margin: 10px;
      border: 20px solid #000;
      overflow-y: scroll;
   }
   var div = document.getElementById('main');
   //0
   console.log(div.scrollTop);
   //0
   console.log(div.scrollLeft);
   div.scrollTop = 20;
   console.log(div.scrollTop);

可以通過這個屬性獲取滾動條距離頂部高度進行可視區域載入,具體可以參考我另一篇部落格 lazyLoad與節流

    //可視區域
    var seeHeight = window.innerHeight || document.documentElementHeight || document.body.clientHeight;
    //滾動條距離頂部高度
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;