元素偏移量
元素偏移量
1. 元素偏移量offset系列
1.1 offset概述
offset 翻譯過來就是偏移量, 我們使用 offset系列相關屬性可以動態的得到該元素的位置(偏移)、大小等。
- 獲得元素距離帶有定位父元素的位置,無論子元素是通過 margin、padding 還是絕對定位設定的與父元素的距離,都可以獲取
- 獲得元素自身的大小(寬度高度),使用js動態設定的寬度,也可以獲取
- 注意:返回的數值都不帶單位
offset系列屬性 | 作用 |
---|---|
element.offsetParent | 返回作為改元素帶有定位的父級元素如果父級都沒有定位則返回body |
element.offsetTop | 返回元素相對帶有定位父元素上方的偏移 |
element.offsetLeft | 返回元素相對帶有定位父元素左邊框的偏移 |
element.offsetWidth | 返回自身包括padding、邊框、內容區的寬度,返回數值不帶單位 |
element.offsetHeight | 返回自身包括padding、邊框、內容區的高度,返回數值不帶單位 |
程式碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.parent {
position: relative;
width: 500px;
height: 300px;
margin: 100px;
background-color: #ccc;
padding-top: 50px;
}
.son {
width: 200px;
padding: 20px;
height: 100px;
background-color: orange;
margin-left: 100px;
}
.daughter{
position: absolute;
left: 50px;
top: 100px;
width: 200px;
height: 100px;
background-color: red;
}
.sonBorder{
border: 10px solid black;
}
</style>
</head>
<body>
<div class="parent">
<div class="son"></div>
<div class="daughter"></div>
</div>
<script>
/*
* offsetTop 屬效能夠獲取當前元素距離父元素(有定位)的上邊框的距離,通過如下幾種方式設定的距離都可以獲取到
1)通過子元素的 margin-top
2)通過父元素的 padding-top
3)通過絕對定位
* offsetWidth 獲取的元素寬度為 width+padding+border
*/
var son = document.querySelector('.son')
var daughter=document.querySelector('.daughter')
// 元素距離父元素(一定要有定位)左邊框的距離
console.log(son.offsetLeft);
// 元素距離父元素(一定要有定位)上邊框的距離
console.log(son.offsetTop);
console.log(daughter.offsetLeft);
// 獲取元素自身寬度
console.log(son.offsetWidth);
// 為元素動態新增寬度後,offsetWidth 還可以獲取馬
son.addEventListener('click',function(){
this.className=this.className+' sonBorder'
console.log(son.offsetWidth);
})
// 返回父級元素
console.log(son.offsetParent==daughter.offsetParent);
</script>
</body>
</html>
1.2 offset於style區別
offset
- offset 可以得到任意樣式表中的樣式值
- offset 系列獲得的數值是沒有單位的
- offsetWidth 包含padding+border+width
- offsetWidth 等屬性是隻讀屬性,只能獲取不能賦值
- 所以,我們想要獲取元素大小位置,用offset更合適
style
- style 只能得到行內樣式表中的樣式值
- style.width 獲得的是帶有單位的字串
- style.width 獲得不包含padding和border 的值
- style.width 是可讀寫屬性,可以獲取也可以賦值
- 所以,我們想要給元素更改值,則需要用style改變
1.3案例:獲取滑鼠在盒子內的座標
- 我們在盒子內點選,想要得到滑鼠距離盒子左右的距離。
- 首先得到滑鼠在頁面中的座標(e.pageX, e.pageY)
- 其次得到盒子在頁面中的距離 ( box.offsetLeft, box.offsetTop)
- 用滑鼠距離頁面的座標減去盒子在頁面中的距離,得到 滑鼠在盒子內的座標
- 如果想要移動一下滑鼠,就要獲取最新的座標,使用滑鼠移動
var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x座標是' + x + ' y座標是' + y;
})
1.4 案例:拖拽盒子
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
position: relative;
width: 300px;
height: 200px;
border: 1px solid black;
margin-left: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div class="box">
</div>
<script>
/* 思路
* 1)在盒子內部按下滑鼠左鍵,在頁面中拖動,也就是說
觸發盒子的 mousedown 事件,觸發頁面的 mouseover 事件
* 2)滑鼠在頁面中移動時,計算滑鼠移動的距離,然後設定盒子位置加上
這個距離
**/
var box = document.querySelector('.box')
box.addEventListener('mousedown', function(event) {
// 獲取滑鼠按下時的橫座標
var old_x = event.pageX
var old_y = event.pageY
// 獲取盒子的左側距離
var offsetLeft = this.offsetLeft
var offsettop = this.offsetTop
// console.log(offsettop)
document.addEventListener('mousemove', move)
function move(e) {
// 獲取滑鼠在文件中移動時的新的橫座標
var new_x = e.pageX
var new_y = e.pageY
// 計算滑鼠移動的x軸距離
var x = new_x - old_x
var y = new_y - old_y
// console.log(y)
// 設定盒子的 left 的值=原來left 的值+移動距離
box.style.left = (offsetLeft + x - 100) + 'px'
box.style.top = (offsettop + y) + 'px'
}
// 為盒子註冊 mouseup 事件
document.addEventListener('mouseup', function() {
// console.log('up');
document.removeEventListener('mousemove', move)
})
})
</script>
</body>
</html>
1.5 案例:偽京東放大鏡
案例分析:
- 黃色的遮擋層跟隨滑鼠功能。
- 把滑鼠座標給遮擋層不合適。因為遮擋層座標以父盒子為準。
- 首先是獲得滑鼠在盒子的座標。
- 之後把數值給遮擋層做為left 和top值。
- 此時用到滑鼠移動事件,但是還是在小圖片盒子內移動。
- 發現,遮擋層位置不對,需要再減去盒子自身高度和寬度的一半。
- 遮擋層不能超出小圖片盒子範圍。
- 如果小於零,就把座標設定為0
- 如果大於遮擋層最大的移動距離,就把座標設定為最大的移動距離
- 遮擋層的最大移動距離:小圖片盒子寬度 減去 遮擋層盒子寬度
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.preview {
width: 250px;
height: 250px;
border: 1px solid #ebebeb;
margin: 50px 0 0 50px;
text-align: center;
}
.preview_img {
position: relative;
width: 250px;
}
.mask {
display: none;
position: absolute;
width: 150px;
height: 150px;
background-color: rgba(245, 201, 56, 0.4);
top: 0;
left: 0;
border: 1px solid #ccc;
margin: 50px 0 0 50px;
cursor: move;
}
.big {
display: none;
position: absolute;
width: 600px;
height: 600px;
left: 450px;
top: 20px;
z-index: 999;
border: 1px solid #ccc;
overflow: hidden;
}
.big_img {
position: absolute;
/*新增了定位才可以移動*/
top: 0;
left: 0;
width: 1000px;
}
</style>
</head>
<body>
<div class="preview">
<img src="./xiao.jpg" alt="" class="preview_img">
<div class="mask"></div>
<div class="big">
<img src="./xiao.jpg" alt="" class="big_img">
</div>
</div>
<script>
// 因為是外部的js,所以要等頁面載入完畢執行
window.addEventListener('load', function() {
var preview = document.querySelector('.preview');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
//1.當我們滑鼠經過preview就顯示和隱藏mask遮擋層和big大盒子
preview.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
preview.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
//2.滑鼠移動事件
preview.addEventListener('mousemove', function(e) {
//(1)先計算出滑鼠在盒子內的座標
var x = e.pageX - preview.offsetLeft;
var y = e.pageY - preview.offsetTop;
//(2)減去盒子寬度和高度的一半(x - mask.offsetWidth / 2)
//(3)限制遮擋層移動範圍
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
//遮擋層的最大移動距離
var maskMax = preview.offsetWidth - mask.offsetWidth; //因為是正方形,width和height用一個就行
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
//3.大圖片跟隨移動功能
// 大圖片移動距離=遮擋層移動距離*大圖片最大移動距離/遮擋層最大移動距離
var bigImg = document.querySelector('.big_img');
//大圖片最大移動距離
var bigMax = big.offsetWidth - bigImg.offsetWidth;
//大圖片的移動距離
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigImg.style.left = bigX + 'px'; //這個地方視訊上說加-號,我沒有加的效果是好的,不清楚?
bigImg.style.top = bigY + 'px';
})
})
</script>
</body>
</html>
2. 元素可視區client系列
client概述
client 翻譯過來就是客戶端,我們使用 client 系列的相關屬性來獲取元素可視區的相關資訊。通過 client系列的相關屬性可以動態的得到該元素的邊框大小、元素大小等。
client系列屬性 | 作用 |
---|---|
element.clientTop | 返回元素上邊框的大小 |
element.clientLeft | 返回元素左邊框的大小 |
element.clientWidht | 返回自身包括padding、內容區的寬度,不含邊框,返回值不帶單位 |
element.clientHeight | 返回自身包括padding、內容區的高度,不含邊框,返回數值不帶單位 |
3 元素滾動scroll系列
3.1 scroll概述
scroll 翻譯過來就是滾動的,我們使用 scroll 系列的相關屬性可以動態的得到該元素的大小、滾動距離等。
scroll系列屬性 | 作用 |
---|---|
element.scrollTop | 返回被捲去的上側距離,返回數值不帶單位 |
element.scrollLeft | 返回被捲去的左側距離,返回數值不帶單位 |
element.scrollWidth | 返回自身實際的寬度,不含邊框,返回數值不帶單位 |
element.scrollHeight | 返回自身實際的高度,不含邊框,返回數值不帶單位 |
3.2 頁面被捲去的頭部相容性解決方案
需要注意的是,頁面被捲去的頭部,有相容性問題,因此被捲去的頭部通常有如下幾種寫法:
- 宣告瞭 DTD,使用 document.documentElement.scrollTop
- 未宣告 DTD,使用 document.body.scrollTop
- 新方法 window.pageYOffset和 window.pageXOffset,IE9 開始支援
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft ||document.body. scrollLeft ||0,
top: window.pageYOffset || document.documentElement.scrollTop ||document.body.scrollTop || 0
};
}
使用的時候 getScroll().left
4 三大系列總結
三大系列大小對比 | 作用 |
---|---|
element.offsetWidth | 返回自身包括padding、邊框、內容區的寬度,返回數值不帶單位 |
element.clientWidth | 返回自身包括padding、內容區的寬度,不含邊框,返回數值不帶單位 |
element.scrollWidth | 返回自身實際的寬度,不含邊框,返回數值不帶單位 |
他們主要用法:
- offset系列 經常用於獲得元素位置 offsetLeft offsetTop
- client經常用於獲取元素大小 clientWidth clientHeight
- scroll 經常用於獲取滾動距離 scrollTop scrollLeft
- 注意頁面滾動的距離通過 window.pageXOffset 獲得
5.mouseenter和mouseover的區別
- 當滑鼠移動到元素上時就會觸發mouseenter 事件
- 類似 mouseover,它們兩者之間的差別是
- mouseover 滑鼠經過自身盒子會觸發,經過子盒子還會觸發。mouseenter 只會經過自身盒子觸發
- 之所以這樣,就是因為mouseenter不會冒泡
- 跟mouseenter搭配滑鼠離開 mouseleave 同樣不會冒泡
6.動畫函式封裝
動畫函式給不同元素記錄不同定時器
如果多個元素都使用這個動畫函式,每次都要var 宣告定時器。我們可以給不同的元素使用不同的定時器(自己專門用自己的定時器)。
核心原理:利用 JS 是一門動態語言,可以很方便的給當前物件新增屬性。
function animate(obj, target) {
// 當我們不斷的點選按鈕,這個元素的速度會越來越快,因為開啟了太多的定時器
// 解決方案就是 讓我們元素只有一個定時器執行
// 先清除以前的定時器,只保留當前的一個定時器執行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止動畫 本質是停止定時器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
相關文章
- JavaScript--元素偏移量(offset)JavaScript
- 獲取元素的偏移量offset
- 獲取元素大小、偏移量及滑鼠位置
- JavaScript獲取元素相對於document的偏移量JavaScript
- kafka的偏移量Kafka
- javascript - 滑鼠偏移量JavaScript
- kafka重置偏移量Kafka
- rocketMq 訊息偏移量 OffsetMQ
- MySQL偏移量的一點分析MySql
- AIX lv 4k偏移量AI
- Spark Streaming 之 Kafka 偏移量管理SparkKafka
- 【Kafka】《Kafka權威指南》——提交和偏移量Kafka
- C語言中的指標加減偏移量C語言指標
- Kafka中手工提交偏移量的4種方法Kafka
- 6.5陣列--模擬、偏移量-螺旋矩陣陣列矩陣
- JavaScript偏移量offset,可視區client,滾動scroll系列JavaScriptclient
- 解決MySQL使用limit偏移量較大效率慢的問題MySqlMIT
- js如何元素當前元素所有的父元素JS
- HTML_行內元素、塊級元素、空元素HTML
- 大偏移量下Redis與MongoDB的分頁/排名效能比較RHRedisMongoDB
- 建立元素和刪除元素
- jQuery 元素操作——遍歷元素jQuery
- 判斷一個元素是否是另一個元素的子元素或者父元素
- 塊狀元素、內聯元素和內聯塊狀元素
- CSS子元素居中(父元素寬高已知,子元素未知)CSS
- HTML 空元素 And 可替換元素HTML
- 空元素和可替換元素
- 塊級元素和行內元素
- 行內元素與塊元素1
- 行內元素和塊級元素
- STL.vector容器刪除單個元素、部分元素、全部元素
- HTML 塊級元素和內聯元素HTML
- js小功能之-新增元素-清楚元素JS
- jQuery獲取元素前面所有兄弟元素jQuery
- 常見塊元素和內聯元素
- JavaScript在指定元素後面插入元素JavaScript
- CSS塊狀元素和內聯元素CSS
- Html 內聯元素和外聯元素HTML