平時在寫js的時候,偶爾會須要用js來獲取當前div到 body 左側、頂部的距離。網上查一查,有不少都是經過offsetTop、offsetLeft來計算出來的。我按照網上的查到的資料用了一次,算出來了一堆錯誤答案。html
下面我要分享的這個方法,兼容性很好(ie4都ok),並且很方便,不會算錯。git
這個方法就是 getBoundingClientRect。github
getBoundingClientRect 返回的是一個 DOMRect 對象,是一組矩形集合,咱們此次所使用的返回值主要是left、top、bottom和right。其他的返回值width、height、x、y此次用不到,就再也不討論。 使用方法以下:chrome
let domToTop = dom.getBoundingClientRect().top // dom 的頂邊到視口頂部的距離
let domToLeft = dom.getBoundingClientRect().left // dom 的左邊到視口左邊的距離
let domToBottom = dom.getBoundingClientRect().bottom // dom 的底邊到視口頂部的距離
let domToRight = dom.getBoundingClientRect().right // dom 的右邊到視口左邊的距離
複製代碼
屬性 | chrome | Edge | Firefox | IE | Opera | Safari |
---|---|---|---|---|---|---|
基礎屬性:left、top、right、bottom | Yes | 12 | 3 | 4 | Yes | 6 |
height、width | Yes | Yes | 3.5 | 9 | Yes | Yes |
x、y | Yes | No | Yes | No | Yes | No |
由於 getBoundingClientRect 能夠獲取到視口邊界的距離,因此獲得的值加上滾動條的長度,就能夠獲得距離body邊界的距離。bash
demo預覽連接,方便你們查驗效果 預覽連接dom
github地址ui
實際使用時,直接使用 getScrollPosition 和 getDomToViewPosition這兩個方法就好,其他的方法只是爲了更好地展示。幫到你的話,點個讚唄~this
下面是完整代碼:spa
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
width: 110%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid red;
}
.content {
width: 20%;
height: 30%;
position: absolute;
top: 30%;
left: 30%;
border: 1px solid blue;
}
.board {
position: absolute;
border: black 1px solid;
transform: translate(200px, 200px);
}
</style>
</head>
<body>
<div class="box">
<div class="content" id="content"></div>
</div>
<div class="board" id="board">
<div>展現板:距離body的邊框距離 = 視口距離 + 滾動條長度</div>
<div>
<span>距離視口左側距離:</span><span id="toViewLeft"></span>
</div>
<div>
<span>距離視口頂部距離:</span><span id="toViewTop"></span>
</div>
<div>
<span>滾動條水平方向的長度:</span><span id="scrollX"></span>
</div>
<div>
<span>滾動條垂直方向的長度:</span><span id="scrollY"></span>
</div>
<div>
<span>距離body左側距離:</span><span id="toBodyLeft"></span>
</div>
<div>
<span>距離body頂部距離:</span><span id="toBodyTop"></span>
</div>
</div>
<script>
// 此方法是爲元素添加事件,並作兼容處理
function addHandler (element, type, handler) {
if (element.addEventListener) { // DOM2級 事件處理程序,this 指向元素自己。按照添加的順序正向執行
element.addEventListener(type, handler, false)
} else if (element.attachEvent) { // IE 事件處理程序,this 指向 window。按照添加的順序反向執行
element.attachEvent('on' + type, handler)
} else { // DOM0級 事件處理程序。只能綁定一個事件處理程序
element['on' + type] = handler
}
}
// 獲取 當前 滾動條的長度, 水平 && 垂直方向
function getScrollPosition () {
let x, y
if (!!window.pageXOffset) {
x = window.pageXOffset
y = window.pageYOffset
} else {
x = (document.documentElement || document.body.parentNode || document.body).scrollLeft
y = (document.documentElement || document.body.parentNode || document.body).scrollTop
}
return {x, y}
}
// 獲取 dom 到視口左側和頂部的相對位置
function getDomToViewPosition (id) {
var dom = document.getElementById(id)
let rectObject = dom.getBoundingClientRect()
return {
domToViewLeft: rectObject.left,
domToViewTop: rectObject.top
}
}
// 設置展現板的展現位置,隨着滾動條的滾動自適應,始終相對於視口左側和頂部距離 200px
function setDisplayBoardPosition () {
let {x, y} = getScrollPosition()
var board = document.getElementById('board')
let transform = 'translate(' + (200 + x) + 'px,' + (200 + y) + 'px)'
board.style.transform = transform
}
// 設置展現板的展現信息
function setDisplayBoardDetail () {
let {x, y} = getScrollPosition() // 獲取滾動條長度
let {domToViewLeft, domToViewTop} = getDomToViewPosition('content') // 獲取到視口的距離
// 在展現板中顯示到視口的距離
document.getElementById('toViewLeft').innerText = domToViewLeft + 'px'
document.getElementById('toViewTop').innerText = domToViewTop + 'px'
// 在展現板中顯示滾動條的長度
document.getElementById('scrollX').innerText = x + 'px'
document.getElementById('scrollY').innerText = y + 'px'
// 在展現板中顯示距離body左側、頂部的距離
document.getElementById('toBodyLeft').innerText = domToViewLeft + x + 'px'
document.getElementById('toBodyTop').innerText = domToViewTop + y + 'px'
}
// 設置展現板的相關信息
function setDisplayBoard () {
setDisplayBoardPosition() // 設置展現板的展現位置
setDisplayBoardDetail() // 設置展現板的詳細信息
}
// 監聽 window 的滾動事件,計算到視口和body左側和頂部的距離,而且在展現板中展現
addHandler(window, 'scroll', setDisplayBoard)
</script>
</body>
</html>
複製代碼