1. 元素偏移量 offset系列
offset翻譯過來就是偏移量,我們可以使用offset系列相關的屬性可以動态的得到該元素的位置(偏移)、大小等。
1.1 offset系列常用屬性
傳回的數值都不帶機關
屬性 | 描述 |
---|---|
element.offsetParent | 傳回帶有定位的父親,否則傳回的是body |
element.offsetTop | 傳回元素相對帶有定位父元素上方的偏移,若沒有父親或父親不帶機關,則以body為準 |
element.offsetLeft | 傳回元素相對帶有定位父元素左邊框的偏移,若沒有父親或父親不帶機關,則以body為準 |
element.offsetWidth | 傳回自身包括padding、邊框、内容區的寬度 |
element.offsetHeight | 傳回自身包括padding、邊框、内容區的高度度 |
注意:element.parentNode傳回的是最近一級的父元素,不管該父元素有無定位。
1.2 offset系列和style的差別
offset | style |
---|---|
offset可以得到任意樣式表中的樣式值 | style隻能得到行内樣式表中的樣式值 |
offset系列獲得的數值是沒有機關的 | style.width獲得的是帶有機關的字元串 |
offsetWidth包含padding+ border+width | style.width獲得不包含padding和border的值 |
offsetWidth 等屬性是隻讀屬性,隻能擷取不能指派 | style.width是可讀寫屬性,可以擷取也可以指派 |
是以,我們想要擷取元素大小位置,用offset更合适 | 是以,我們想要給元素更改值,則需要用style改變 |
2. 元素可視區client系列
client翻譯過來就是用戶端,我們使用client系列的相關屬性來擷取元素可視區的相關資訊。通過client相關屬性可以動态的得到該元素的邊框大小、元素大小等。
2.1 client系列常用屬性
client相關屬性 | 描述 |
---|---|
element.clientTop | 傳回元素上邊框的大小 |
element.clientLeft | 傳回元素左邊框的大小 |
element.clientWidth | 傳回自身包括padding、内容區的寬度,不含邊框,傳回值不帶機關 |
element.clientHeight | 傳回自身包括padding、内容區的高度,不含邊框,傳回值不帶機關 |
client和offset最大的差別是傳回寬度和高度時,offset包括邊框,client不包括邊框。
2.2 flexible分析案例
1. 立即執行函數
立即執行函數:不需要調用,立馬能夠自己執行的函數。
(function () {
console.log('riki');
})();
// or
(function sum(a, b) {
console.log(a + b);
}(2, 3));
注意:
- 第二個小括号可以看作是調用函數,也可以在裡面傳參。
- 立即執行函數最大的作用就是獨立建立了一個作用域,裡面所有的變量全部是局部變量,不會出現命名沖突。
- 也可以給函數起名字
2. pageshow事件
有三種情況會重新整理頁面而觸發load事件:
- a标簽的超連結。
- F5或者重新整理按鈕。
- 前進後退按鈕。
但是火狐中,有個特點,有個“往返緩存”,這個緩存中不僅儲存着頁面資料,還儲存了DOM和JavaScript的狀态;實際上是将整個頁面都儲存在了記憶體裡。是以此時後退按鈕不能重新整理頁面。
此時可以使用pageshow事件來觸發。這個事件在頁面顯示時觸發,無論頁面是否來自緩存。在重新加載頁面中,pageshow會在load事件觸發後觸發,根據事件對象中的persisted來判斷是否是緩存中的頁面觸發的pageshow事件,注意這個事件給window添加。
3. 元素滾動scroll系列
scroll翻譯過來就是滾動的,我們使用scroll系列的相關屬性可以動态的得到該元素的大小、滾動距離等。
3.1 scroll系列常用屬性
傳回值都不帶機關。
屬性 | 描述 |
---|---|
element.scrollTop | 傳回被卷去的上側距離 |
element.scrollLeft | 傳回被卷去的左側距離 |
element.scrollWidth | 傳回自身實際内容的寬度,不含邊框 |
element.scrollHeight | 傳回自身實際内容的寬度,不含邊框 |
3.2 頁面被卷去的頭部
如果浏覽器的高(或寬)度不足以顯示整個頁面時,會自動出現滾動條。當滾動條向下滾動時,頁面上面被隐藏掉的高度,我們就稱為頁面被卷去的頭部。滾動條在滾動時會觸發onscroll事件。
3.3 仿淘寶側邊欄案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.w {
width: 1200px;
margin: 10px auto;
}
.slider-bar {
position: absolute;
left: 50%;
top: 300px;
margin-left: 600px;
width: 45px;
height: 130px;
background-color: orchid;
}
.header {
height: 150px;
background-color: hotpink;
margin-bottom: 20px;
}
.banner {
height: 300px;
background-color: aqua;
margin-bottom: 20px;
}
.main {
height: 1000px;
background-color: lawngreen;
}
span {
display: none;
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div class="slider-bar">
<span class="goBack"> <a href="#header">傳回頂部</a> </span>
</div>
<div id="header" class="header w">頭部區域</div>
<div class="banner w">banner區域</div>
<div class="main w">主體區域</div>
<script>
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
// bannerTop就是被卷去的部分高度
var bannerTop = banner.offsetTop;
// sliderTop是側邊欄離頂部的高度
var sliderTop = sliderbar.offsetTop - bannerTop;
var main = document.querySelector('.main');
var goBack = document.querySelector('.goBack');
var mainTop = main.offsetTop;
document.addEventListener('scroll', function () {
// window.pageYOffset頁面被卷去的頭部
console.log(window.pageYOffset);
// 當頁面被卷去的頭部大于等于banner的offsetTop時(到達banner區域),側邊欄改為固定定位
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed';
sliderbar.style.top = sliderTop + 'px';
} else {
sliderbar.style.position = 'absolute';
sliderbar.style.top = 300 + 'px';
}
// 當頁面被卷曲的頭部大于等于主體部分的offsetTop時,側邊欄出現"傳回頂部"的子產品
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
</script>
</body>
</html>
4. 三大系列總結
- offset系列經常用于獲得元素位置offsetLeft、offsetTop。
- client經常用于擷取元素大小clientWidth、clientHeight。
- scroll經常用于擷取滾動距離 scrollTop 、scrollLeft。
- 注意頁面滾動的距離通過window.pageXoffset獲得。
5. mouseover和mouseenter的差別
二者都是滑鼠經過事件。
- 但是,mouseover滑鼠經過自身盒子會觸發,經過子盒子還會觸發。
- mouseenter隻會經過自身盒子觸發,之是以這樣,就是因為mouseenter不會冒泡。
- mouseenter搭配mouseleave使用,同樣不會冒泡。
6. 動畫函數封裝
6.1 動畫原理
核心原理:通過定時器setInterval()不斷移動盒子位置。
實作步驟:
- 獲得盒子目前位置
- 讓盒子在目前位置加上1個移動距離
- 利用定時器不斷重複這個操作
- 加一個結束定時器的條件
- 注意此元素需要添加定位,才能使用element.style.left
var div = document.querySelector('div');
var timer = setInterval(function () {
if (div.offsetLeft >= 400) {
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 10)
6.2 簡單動畫函數封裝
第一個參數是對象,第二個參數是目标位置。
function animate(obj, target) {
var timer = setInterval(function () {
if (obj.offsetLeft >= target) {
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30)
}
改良版:提高了效率,給不同對象添加不同的定時器。
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)
}
6.3 緩動效果原理
緩動動畫就是讓元素運動速度有所變化,最常見的是讓速度慢慢停下來。
思路:
- 讓盒子每次移動的距離慢慢變小,速度就會慢慢落下來。
- 核心算法:(目标值-現在的位置)/ 10做為每次移動的距離步長。
- 停止條件:目前位置等于目标位置就停止定時器。
function animate(obj, target) {
// 目的是讓元素隻能有一個定時器,防止定時器效果累加
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 步長值寫在定時器裡面
// 把步長值改為整數,盡量避免小數的出現
// 前進:向上取整
// 後退:向下取整
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 30)
}
6.4 回調函數
等動畫執行完畢後,再執行另一個函數的動作。
function animate(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
// 回調函數寫在定時器結束裡
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
// 如果有回調函數傳進來
if (callback) {
// 調用函數
callback();
}
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 30)
}