這一節將解釋說明viewport和各類重要元素的寬度是如何工做的,例如元素<html>,以及窗口和屏幕。css
這個頁面是關於桌面瀏覽器的,它的惟一目的是爲移動瀏覽器的相似討論奠基基礎。大多數web開發人員已經直觀地理解了大多數桌面概念。在移動設備上,咱們會發現一樣的概念,可是更加複雜,而且對每一個人都已經知道的術語進行預先討論將極大地幫助您理解移動瀏覽器。html
第一個須要理解的概念是css像素,以及它與設備像素的差別。web
設備像素被直觀的認爲是「正確」的像素。它給出了咱們正在使用的各類設備的分辨率,能夠經過讀取screen.width/height獲取具體的數值。數據庫
若是給一個元素設置寬度width:128px,你的顯示器是1024px,最大化你的瀏覽器,8個給定寬度的元素恰好填滿你的顯示屏(固然這並不是絕對精確,先忽略那些細節)。瀏覽器
若是用戶使用放大或者縮小功能,填充的數量將會發生變化。若是放大瀏覽器到200%,那麼填充1024寬度的顯示器將只須要四個width:128px的元素。ide
在現代瀏覽器中,縮放只不過是「拉伸」像素。元素的寬度並無從128px變化爲256px,可是實際像素翻倍了。形式上,該元素依然具備128個css像素的寬度,可是卻佔據了256個設備像素。佈局
換句話說,縮放到200%,使得CSS像素擴大爲設備像素的四倍(寬度兩倍,高度兩倍,總爲四倍)。測試
用幾張圖來講明這個概念。這裏是一個縮放100%的四個像素。CSS像素與設備像素徹底重疊。網站
如今來縮小,CSS像素就會縮小,也就是一個設備像素與多個CSS像素重疊。ui
再來放大,就會發生相反的狀況。CSS像素開始變大,結果一個css像素能夠多個設備像素重疊。
這裏的重點是,你只須要關注CSS像素,由於它直接影響你如何呈現元素樣式。
設備像素對您幾乎毫無用處。不是對用戶;用戶會將頁面放大或縮小,直到他可以舒服地閱讀爲止。然而,縮放級別對您來講並不重要。瀏覽器會自動確保你的CSS佈局被拉伸或壓縮。
最開始假設縮放100%,是時候給出一個確切的定義:
縮放級別100%,一個CSS像素正好等於一個設備像素。
100%縮放的概念對於理解接下來的內容頗有用,但平常工做中,並不須要過多擔憂。在桌面,一般都是在100%縮放級別下測試你的網站,即便用戶選擇放大或者縮小操做,CSS像素的魔法會確保你的網站保持原有的佈局。
看一看實際的測量。首先,screen.width和screen.height,它們分別表示用戶屏幕的寬度和高度。這個數值大小的單位是設備像素,由於它們不會發生改變:它們是顯示器的特徵,並不是瀏覽器的。
PS:IE7和IE8模式下,測量使用的是CSS像素。
Fun!可是咱們用這個信息來作什麼呢?
基本上,什麼都不作。用戶顯示器的大小對咱們來講並不重要——除非你須要將這些數據記錄在web統計數據庫中。
相反,你須要知道瀏覽器窗口的內部尺寸。這個大小就是你能夠用來進行CSS佈局的空間大小。能夠經過window.innerWIdth和window.innerHeight得出這個數值。
PS:這個尺寸包含滾動條的寬度,單位是CSS像素。IE瀏覽器不支持。Opera得出的結果是設備像素單位。
顯然,這個窗口的內部尺寸測量使用的是CSS像素。你須要知道你的佈局有多少能夠擠進瀏覽器窗口,當用戶放大時,能夠擠進去的內容就會減小。用戶放大時,你可利用的窗口空間就會變小。window.innerWidth/Height數值就會反映出來。
Opera瀏覽器是一個例外。用戶進行放大操做時,window.innerWidth/Height數值並不會發生變化。該數值的單位是設備像素。在桌面很煩人,在移動設備上確實很是致命的,下面再議。
記住,這個數值包含滾動條。滾動條也是包含在窗口的尺寸中(因爲歷史緣由)。
window.pageXOffset和window.pageYOffset表示文檔水平和垂直滾動的偏移量。經過這個數值,能夠知道用戶滾動了多少
這些測量數值是CSS像素單位的。不管縮放程度如何,你均可以知道文檔被滾動了多少。
理論上,若是用戶滾動了頁面,而後再放大。window.pageX/YOffset會發生變化。事實上,瀏覽器試圖經過在用戶縮放時保持可見頁面頂部的相同元素來保持web頁面的一致性。雖然實際效果並不完美,可是重要的是window.pageX/YOffset並不會發生改變——滾動超出窗口的部分的CSS像素數值並不會發生改變。(通過測量,實際數值會發生很是微小的差距)
在繼續介紹更多JavaScript屬性以前,咱們必須引入另外一個概念:viewport。
viewport是用來約束<html>元素,該元素是網站頁面最外層的包含塊。
這樣說可能仍是以爲不太好理解吧。來舉一個例子。假設你有一個流佈局頁面,頁面中有一個寬度width:10%的側邊欄。當你調整瀏覽器窗口大小時,側邊欄會整潔的放大或者縮小。這是怎麼回事呢?
從技術上來講,側邊欄寬度就是其父元素寬度的10%。假設其父元素是<body>(你並無給body一個固定的寬度),那麼問題就變成了<body>元素的寬度從何而來?
一般,全部塊級元素會填充其父元素,也即寬度爲父元素的寬度(固然也有例外,先忽略)。因此<body>和它的父元素寬度同樣,也就是<html>元素。
那麼,<html>的寬度呢?它和瀏覽器窗口同樣寬,這就是爲何側邊欄老是會佔據瀏覽器窗口的10%。全部web開發人員都知道並在使用這個事實。
可是你可能想要知道這其中的原理。理論上,元素<html>的寬度是由viewport的寬度約束的。<html>獲取viewport寬度的100%。
反過來,viewport與瀏覽器窗口徹底同樣,由於它是被這樣定義的。viewport並非HTML結構,不能夠經過CSS影響它。在桌面系統,viewport的寬高就是瀏覽器窗口的寬高。可是在移動設備上略微複雜一點。
這種狀況產生了一些奇怪的後果。你能夠在這個網站上看到其中一個。滾動到頂部,並放大頁面,以便該站點的內容溢出瀏覽器窗口。
如今向右滾動,您將看到站點頂部的藍色欄再也不正常對齊。
這就是viewport定義帶來的意外。我給頂部的藍色條設置width:100%,可是100%是相對於誰呢?是<html>元素,它和viewport具備同樣的寬度,和瀏覽器窗口寬度同樣。
重點是,頁面內容在100%縮放時徹底可以正常顯示。當進行放大操做時,viewport變得比網站寬度要小了。對於它自己,這並無什麼影響,內容從<html>中溢出了,可是因爲設置了overflow:visible,溢出的內容都會顯示出來。
頂部的藍色條並無溢出。我設置了width:100%,因而瀏覽器給了它跟viewport同樣的寬度。他們並不關心寬度是否是過小。
(這個圖應該是帶有水平滾動條的,可是圖片看不出來)
我真正須要知道的是頁面的總內容有多寬,包括「突出」的部分。就我所知,要找到這個值是不可能的(嗯,除非您計算頁面上全部元素的單獨寬度和頁邊距,但這很容易出錯)。
我開始相信,咱們須要一個JavaScript屬性對來提供我稱之爲「文檔寬度(document width)」(顯然是CSS像素)。
若是咱們真的感受很時髦,那爲什麼不把這個值暴露給CSS呢?我很願意將個人藍色條寬度設置爲100%的document width,而不是<html>的寬度。(實現起來大概很棘手吧,即便沒法實現,我也不會意外)
瀏覽器供應商們,大家怎麼想呢?
你也許想要知道如何測量viewport。document.documentElement.clientWidth/Height提供了這樣的功能。
若是你瞭解DOM,你就會知道document.documentElement其實就是<html>元素:HTML文檔的根元素。然而,能夠說,viewport更高一層。它是包含元素<html>的元素。這會影響到也許你會給<html>一個寬度(雖然我不推薦,可是這是可能並容許的)
在下面這種狀況下,document.docuemntElement.clientWidth/Height依然會給出了viewport的數值,而非<html>元素。(這是一個特殊的規則,只適用於這個元素,只適用於這個屬性對。在全部其餘狀況下,都使用元素的實際寬度)
document.documentElement.clientWidth/Height老是給出viewport的大小,不管<html>的多大多小
可是viewport寬度的大小不是也由window.innerWidth/Height給出的嗎?是也不是。
有一個形式上的差異,那就是window.innerWidth/Height包含了滾動條,可是document.documentElement.clientWidth/Height沒有包含。這有點吹毛求疵。
事實上,這兩對屬性是瀏覽器戰爭的遺留問題。當時Netscape只支持window.innerWidth/Heigh,IE只支持document.documentElement.clientWidth/Height。從那時起,全部其餘瀏覽器都開始支持clientWidth/Height,但IE沒有選擇window.innerWidth/Height。
在桌面上有兩個可用的屬性對是一個小麻煩,但咱們將會看到,在移動端倒是一個福音。
clientWidth/Height不管在設麼狀況下均可以給出viewport的大小。但,咱們從哪裏能夠知道<html>元素的大小呢 。該數值存儲在document.documenElement.offsetWidth/Height。
這些屬性使您可以以塊級元素的形式訪問<html>元素;若是設置寬度,offsetWidth將會反映出這個數值。
接下來講說事件座標。當一個鼠標事件觸發時,公開的屬性對很多於5對,以提供有關事件確切位置的信息。在咱們的討論中,其中三個問題很重要:
90%你都會使用pageX/Y,大多狀況下,你須要知道事件相對於文檔的座標。剩下的10%,你會須要clientX/Y。而相對於屏幕的座標幾乎歷來不用。
最後是一些關於媒體查詢的單詞。這個想法很是簡單:能夠定義特殊的CSS規則,只有當頁面的寬度大於、等於或小於必定的值時才執行這些規則。例如:
div.sidebar { width: 300px; } @media all and (max-width: 400px) { // styles assigned when width is smaller than 400px; div.sidebar { width: 100px; } }
側邊欄的寬度是300px,除非寬度小於400px時,側邊欄將會變成100px.
有一個問題:這裏的寬度是什麼寬度呢?
這裏有兩個媒體查詢:width、height 和device-width/device-height
咱們應該使用哪一個呢?顯而易見,固然是:width。web開發者們對設備寬度(device width)不感興趣,重要的是瀏覽器窗口的寬度。
因此使用width,忘記device-width吧——在桌面系統中。就如咱們所知,在移動設備中會複雜的多。
設備像素與CSS像素是不一樣的,web開發者基本上只須要關注CSS像素便可,css設置的值直接影響頁面元素的CSS像素大小。
window.pageX/YOffset表示頁面滾動偏移量。(滾動隱藏起來的部分CSS像素)
window.pageX/YOffset與document.docuemtnElement.scrollTop/Left獲得的都是滾動偏移量。前者只讀,後者能夠讀寫。前者主要應用在現代瀏覽器中(IE8及其如下不兼容),後者幾乎兼容全部瀏覽器(混雜模式的IE瀏覽器下,使用document.body代替document.docuemntElement)
document,docuemntElement,clientWidth/Height——viewport的大小
window.innerWIdth/Height表示瀏覽器窗口(標籤頁)的大小,包含滾動條。(CSS像素)
innerWidth/Height 和clientWidth/Height差別在包不包含滾動條(瀏覽器戰爭的遺留問題,IE不支持innerWidth)。
document.docuemntElement.offsetWidth/Height表示<html>大小,也就是頁面的總大小。IE瀏覽器中獲得的是viewport的大小,而非<html>的大小。
document.documentElement.clientX/Y——鼠標相對於視口(viewport)的位置。(10%)
document.documentElement.pageX/Y——鼠標相對於頁面(page)的位置。(90%)
document.documentElement.screenX/Y——鼠標相對於屏幕的位置。(幾乎不用)
媒體查詢中用來的width/height是viewport的大小,也就是document.docuemntElement.clientWidth.Height.
有關移動瀏覽器的請看下一篇翻譯