JavaScript 中那些關於座標和距離的屬性與方法

一 前言

在前端開發中總會遇到各類各樣須要使用或計算座標和距離的狀況,可是這些屬性和方法衆多,所有熟練地記下來並不是是一件易事,大多隻能現查,耗費很多時間精力,因而便有了整理記錄的想法,即加深了印象,又方便隨時查閱。javascript

二 window 對象

瀏覽器裏面,window 對象(注意,w爲小寫)指當前的瀏覽器窗口。css

它也是當前頁面的頂層對象,即最高一層的對象,全部其餘對象都是它的下屬。一個變量若是未聲明,那麼默認就是頂層對象的屬性。html

摘自《阮一峯 JavaScript 教程》前端

位置大小屬性

window.screenX , window.screenY

只讀屬性java

返回瀏覽器窗口左上角相對於當前屏幕左上角的水平距離和垂直距離(單位像素)。web

window.innerHeight , window.innerWidth

只讀屬性瀏覽器

返回網頁在當前窗口中可見區域的高度和寬度,即「視口」(viewport)的大小(單位像素)。dom

注意,這兩個屬性包括滾動條的高度和寬度。函數

window.outerHeight , window.outerWidth

只讀屬性性能

返回瀏覽器窗口的高度和寬度,包括瀏覽器菜單和邊框(單位像素)。

window.scrollX , window.scrollY

只讀屬性

別名: window.pageXOffset , window.pageYOffset

分別返回頁面的水平滾動距離和垂直滾動距離,單位都是像素。

注意,這兩個屬性的返回值不是整數,而是雙精度浮點數。若是頁面沒有滾動,它們的值就是0。

摘自《阮一峯 JavaScript 教程》

爲了跨瀏覽器兼容性,請使用 window.pageXOffset 代替 window.scrollX。另外,舊版本的 IE(<9)兩個屬性都不支持,必須經過其餘的非標準屬性來解決此問題。

摘自 MDN :developer.mozilla.org/zh-CN/docs/…

window 對象的方法

window.scrollTo() , window.scroll() , window.scrollBy()

window.scrollTo 方法 ---> 別名: window.scroll 方法

用於將文檔滾動到指定位置。

它接受兩個參數,表示滾動後位於窗口左上角的頁面座標。

也能夠接受一個配置對象做爲參數。

window.scrollTo(options)
複製代碼

配置對象 options 有三個屬性。

  • top:滾動後頁面左上角的垂直座標,即 y 座標。
  • left:滾動後頁面左上角的水平座標,即 x 座標。
  • behavior:字符串,表示滾動的方式,有三個可能值(smooth、instant、auto),默認值爲 auto。

window.scrollBy 方法用於將網頁滾動指定距離(單位像素)。

它接受兩個參數:水平向右滾動的像素,垂直向下滾動的像素。

注意:仔細體會這二者的差異。

三 Element 節點

Element節點對象對應網頁的 HTML 元素。每個 HTML 元素,在 DOM 樹上都會轉化成一個Element節點對象(簡稱元素節點)。

相關屬性

Element.clientHeight,Element.clientWidth

分別返回元素的高度和寬度,始終是整數值。

若是該元素是內聯元素(display: inline;),則返回值爲 0。

從盒模型的概念上來說,返回的數值計算包括元素的 content 和 padding ,不包括 border 和 margin 。

若是有滾動條,返回的數值會減去滾動條佔據的寬度或高度。(即不包含滾動條在內)

// 瀏覽器視口高度
document.documentElement.clientHeight

// 網頁總高度
document.body.clientHeight
複製代碼

Element.clientLeft,Element.clientTop

分別返回元素的左邊框寬度和上邊框寬度,沒有邊框則返回 0。

一樣不支持內聯元素。

(我沒太明白這兩個屬性有啥做用……)

Element.scrollHeight,Element.scrollWidth

返回當前元素的總高度和總寬度,包括溢出容器、當前並不可見的部分。

包括 padding 區域。

包括僞元素的寬度和高度。

不包含滾動條的寬度和高度。

來個小 demo 輔助下理解:

<div class="box"> 666 </div>
複製代碼
.box {
  width: 200px; height: 200px; overflow: hidden;
  border: 1px solid red; padding: 10px; position: relative;
}
.box::after {
  position: absolute; content: '';
  width: 100px; height: 100px; left: 100%;
}
複製代碼
let box = document.querySelector('.box')
console.log(box.scrollWidth) // 320
console.log(box.scrollHeight) // 220
複製代碼

能夠看到 box 元素的 scrollHeight 是 220,這個和咱們提到的「包括 padding 區域」相符合。

那 box 元素的 scrollWidth 爲啥是 320 ? 是由於僞元素的位置和寬度,雖然僞元素溢出被隱藏了,可是這個屬性返回的數值依然包括它。

固然不只僅包括它的寬度和高度,它所處的位置也會計算在內。

好比把僞元素的 css 改一下:

.box::after {
  position: absolute; content: '';
  width: 100px; height: 100px;
  left: 120%; top: 120%;
}
複製代碼

如今你要不要猜一下 box 的 scrollWidthscrollHeight 分別是多少?

Element.scrollLeft,Element.scrollTop

可讀寫,設置該屬性的值,會致使瀏覽器將當前元素自動滾動到相應的位置。

分別返回當前元素的水平滾動距離和垂直滾動距離。

對於那些沒有滾動條的網頁元素,這兩個屬性老是等於 0。

若是要查看整張網頁的水平的和垂直的滾動距離,要從 document.documentElement 元素上讀取。

document.documentElement.scrollLeft
document.documentElement.scrollTop
複製代碼

Element.offsetHeight,Element.offsetWidth

分別返回元素的高度和寬度,包括元素自己的高和寬、padding 和 border ,以及滾動條的高和寬。

若是元素的 display 爲 none,則返回 0。

與 clientHeight 和 clientWidth 相比,我想這對屬性用的更多一點,由於更多的時候咱們須要獲取的是元素的完整寬高。

Element.offsetLeft,Element.offsetTop

返回當前元素左上角相對於 Element.offsetParent 節點的水平和垂直位移。

說到這個咱們來了解下 Element.offsetParent:

Element.offsetParent 屬性返回最靠近當前元素的、而且 CSS 的 position 屬性不等於 static 的上層元素。

若是該元素是不可見的(display屬性爲none),或者位置是固定的(position屬性爲fixed),則offsetParent屬性返回null。

若是某個元素的全部上層節點的position屬性都是static,則Element.offsetParent屬性指向元素。

摘自《阮一峯 JavaScript 教程》

相關方法

Element.getBoundingClientRect()

返回一個對象,提供當前元素的大小、位置等信息。

我經常使用來它獲取元素的寬高和座標。

該對象有以下屬性:

  • width
  • height
  • x 元素左上角相對於 視口 的橫座標
  • y
  • left
  • right
  • top
  • bottom

因爲元素相對於視口(viewport)的位置,會隨着頁面滾動變化,所以表示位置的四個屬性值,都不是固定不變的。若是想獲得絕對位置,能夠將 left 屬性加上 window.scrollX , top 屬性加上 window.scrollY。

摘自《阮一峯 JavaScript 教程》

四 鼠標事件

MouseEvent 接口

let event = new MouseEvent('click', {
    // ...
})
複製代碼

經過 addEventListener 添加的 click 事件所產生的事件對象也是 MouseEvent 實例。

let box = document.querySelector('.box')

box.addEventListener('click', (e) => {
  console.log(e) // 事件對象
})
複製代碼

這個事件對象,也就是 MouseEvent 實例,有不少屬性,這裏來簡單分析一下。

MouseEvent.clientX 和 MouseEvent.clientY

只讀屬性

分別返回鼠標位置相對於 瀏覽器窗口 左上角的水平座標和垂直座標。(不受滾動距離的影響)

能夠這樣理解:

client 原本就是客戶端的意思,web 中的客戶端就是瀏覽器,那 clientX 和 clientY 天然就是相對於瀏覽器的位置了。

這兩個屬性還分別有一個別名 MouseEvent.x 和 MouseEvent.y 。

MouseEvent.screenX,MouseEvent.screenY

只讀屬性

分別返回鼠標位置相對於 屏幕(顯示器屏幕區域) 左上角的水平座標和垂直座標。

screen 是屏幕的意思,因此,你懂的。

MouseEvent.offsetX,MouseEvent.offsetY

只讀屬性

分別返回鼠標位置相對於 目標節點(即當前元素) 左上角 padding 邊緣 的 水平距離和垂直距離。

offset 有偏移的意思,因此這裏也能夠理解爲鼠標位置相對於目標元素內部左上角的偏移值,和目標元素自己以及外部的元素都無關。

那 「padding 邊緣」是什麼意思呢?

咱們拿圖說話:

offsetX 和 offsetY

上圖中三個元素分別有紅藍綠三種邊框來區分,紅藍邊框寬度爲 1px , 綠邊框爲 30px 。每一個元素都有 padding 值。具體代碼以下:

<!-- HTML -->
<body>
  <div class="parent">
    <div class="hello">Hello</div>
  </div>
</body>
複製代碼
/* css */
body {
  border: 1px solid red; margin: 0; padding: 20px;
}
.parent {
  border: 1px solid blue; padding-top: 50px;
}
.hello {
  width: 100px; height: 100px; padding: 100px; border: 30px solid green;
}
複製代碼

咱們給 hello 元素添加一個 click 時間監聽函數:

// js
let hello = document.querySelector('.hello')

hello.addEventListener('click', (e) => {
  console.log(e)
  console.log(e.offsetX)
  console.log(e.offsetY)
})

複製代碼

分別點擊 hello 元素的綠色邊框和空白區域,會發現前者的值爲負數,後者的值爲整數,且都是相對空白區域的左上角開始計算的。

這就是咱們一開始提到的 「鼠標位置相對於 目標節點(即當前元素) 左上角 padding 邊緣 的 水平距離和垂直距離」 這句話的意思。

MouseEvent.pageX,MouseEvent.pageY

只讀屬性

分別返回鼠標位置相對於文檔左上角的距離。(包括滾動距離)

MouseEvent.movementX,MouseEvent.movementY

只讀屬性

返回當前位置與上一個 mousemove 事件之間的水平距離和垂直距離。

很明顯這兩個屬性和 mousemove 事件確定有着密切的關係,因此咱們再瞭解一下 mousemove 事件:

當鼠標在一個節點內部移動時觸發。當鼠標持續移動時,該事件會連續觸發。爲了不性能問題,建議對該事件的監聽函數作一些限定,好比限定一段時間內只能運行一次。

說到這個應該會牽扯到「節流」,暫不深刻了。

這兩個屬性仍是頗有用的,我雖然沒咋用過,不過目前想來能夠用來判斷鼠標的移動方向等。

參考連接:

window 對象 - WangDoc.com

Element 節點 - WangDoc.com

鼠標事件 - WangDoc.com

(完)

相關文章
相關標籤/搜索