假設有一個網頁岩四,有一個寬度為10%的sidebar,我們不斷的拉伸瀏覽器哥攘,sidebar的寬度也在不斷的增加剖煌,反之減少。在手機上看網頁的時候逝淹,我們不斷的滾動網頁或者拉伸網頁來改變內容呈現末捣。這些機制是怎樣實現的呢?是否是瀏覽器在不斷的重繪節(jié)點(reflow, repaint)來做不同的展示呢创橄?
當然不是箩做!瀏覽器實現這一套機制的原理是viewport(視口)。我們在你不知道的CSS——BFC(塊級格式化上下文)中介紹了BFC妥畏,而html節(jié)點則是最頂級的BFC邦邦,viewport則是用來約束html顯示的區(qū)域。事實上醉蚁,viewport又可分為visual viewport和layout viewport燃辖。為了了解這兩個viewport的區(qū)別,我們不妨看看stackoverflow上的解釋
The visual viewport is the part of the page that’s currently shown on-screen.
The layout viewport can be considerably wider than the visual viewport, and contains elements that appear and do not appear on the screen.
Imagine the layout viewport as being a large image which does not change size or shape. Now imagine you have a smaller frame through which you look at the large image. The small frame is surrounded by opaque material which obscures your view of all but a portion of the large image. The portion of the large image that you can see through the frame is the visual viewport. You can back away from the large image while holding your frame (zoom out) to see the entire image at once, or you can move closer (zoom in) to see only a portion. You can also change the orientation of the frame, but the size and shape of the large image (layout viewport) never changes.
也就是說网棍,visual viewport是頁面顯示到屏幕上的可見區(qū)域黔龟,而layout viewport則是一個比較比visual viewport大的區(qū)域。我們可以假定是通過一個相框在看一個無限大的區(qū)域滥玷,只有其中的一部分能看到氏身,其他部分被相框周邊遮擋了。我們通過移動相框位置或者離這個區(qū)域的距離惑畴,能看到不同的內容或者放縮內容的大小蛋欣,而在整個過程中,該區(qū)域的內容并未發(fā)生任何變化如贷。這個比喻形象的模擬和解釋了我們拖動滾動條以及對頁面放縮的過程陷虎,整個過程中并未觸發(fā)頁面的layout,只是可視區(qū)域發(fā)生變化而已杠袱!
事實上尚猿,設備對自身的layout viewport也有其默認設定:
由此,我們不難理解楣富,在移動端開發(fā)時凿掂,我們需要在網頁中加入viewport設置:
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
這里將layout viewport的寬度設置成設備像素寬度,事實上這里只設置initial-scale=1也相當于將layout viewport設置和visual viewport大小相同菩彬。
另外缠劝,值得注意的一點是潮梯,window.innerWidth/Height獲取的是layout viewport的寬度骗灶,而document.documentElement.clientWidth/Height獲取到的是visual viewport的寬度惨恭,相差的是滾動條的寬度。未設置viewport耙旦,這二者將返回默認layout viewport寬度脱羡。
此外,關于事件綁定中的幾個位置免都,clientX/Y相對于visual viewport, pageX/Y相對于頁面锉罐,screenX/Y相對于屏幕,在有滾動條的情況下绕娘,我們最常用的應該是pageX/Y了脓规。
參考文章
stackflow-viewport
兩個viewport的故事(第一部分)
兩個viewport的故(第二部分)
深入了解viewport和px
移動前端開發(fā)之viewport的深入理解