JS輪播圖中緩動函數的封裝的詳細知識介紹

ADVERTISEMENT

JS輪播圖中緩動函數的封裝的詳細知識介紹

輪播圖的根本其實就是緩動函數的封裝,如果說輪播圖是一輛跑動的汽車,那麼緩動函數就是它的發動機,今天本文章就帶大家由簡入繁,封裝屬於自己的緩動函數~~

我們從需求的角度開始,首先給出一個簡單需求:

1、我想讓頁面中的一個盒子從開始的位置勻速向右運動到200px的地方,該怎麼實現?

分析:

1)我們需要知道盒子在哪個地方,這個可以通過offsetLeft屬性去獲取;

2)要讓盒子勻速運動,對於js肯定需要setInterval了;

3)要讓盒子向右邊跑起來?那就是需要不停改變盒子與左邊起始點的距離,有margin-left,還有定位的left,這里我選擇了改變絕對定位的left;

4)跑到離開始點200px的距離我們要停下來,使用clearInterval就可以了。

接下來直接上代碼了

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<title>Document</title>

<style type="text/css">

* {

margin: 0;

padding: 0;

}

div {

position: absolute;

top: 50px;

width: 100px;

height: 100px;

background-color: red;

}

input {

width: 100px;

height: 30px;

color: #fff;

background-color: yellowgreen;

}

</style>

</head>

<body>

<div></div>

<input type="button" value="移動到200" />

<script type="text/javascript">

// 獲取到元素(這里有個小細節,如果給元素設置了id名,即便不使用獲取元素的方法,也能通過這個id名獲取到元素哦~~大家可以自己嚐試一下)

ADVERTISEMENT

var btn = document.querySelector('input'),

dv = document.querySelector('div');

// 添加點擊事件

btn.addEventListener('click',function() {

var timer = null,// 保存定時器

currentDistance = dv.offsetLeft, // 當前離父盒子的距離

step = 8,// 每次改變的距離

target = 200;// 目標距離

timer = setInterval(function() {

currentDistance += step;// 當前距離 = 上一個當前距離 + 改變的距離

if((target - currentDistance) < step) {

currentDistance = target; // 如果目標距離與當前距離的差小於了要改變的距離,這時候我們就直接讓當前距離等於目標距離,防止盒子停下來的時候有誤差

clearInterval(timer); // 清楚定時器

timer = null; // 將timer解綁,釋放內存

}

dv.style.left = currentDistance + 'px'; // 最核心的一步,改變盒子的left為當前距離

},17)

})

</script>

</body>

</html>

2、一個初步運動的效果實現了,那麼接下來我們改進了需求:

盒子運動到200px的位置後,我們要讓盒子繼續運動到400px的位置?

分析:

1)、這時候要有兩個按鈕點擊,一個運動到200px,一個運動到400px

2)、雖然有兩個運動,但是其使用的功能都是一樣,都是從一個點移動到另一個點,所以我們考慮將1中的運動封裝一個函數,以供複用。

上代碼~

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<title>Document</title>

<style type="text/css">

* {

margin: 0;

padding: 0;

}

div {

position: absolute;

ADVERTISEMENT

top: 50px;

width: 100px;

height: 100px;

background-color: red;

}

input {

width: 100px;

height: 30px;

color: #fff;

background-color: yellowgreen;

}

</style>

</head>

<body>

<div></div>

<input type="button" value="移動到200" />

<input type="button" value="移動到400" />

<script type="text/javascript">

// 封裝函數,盒子和目標距離都是不確定的,我們可以將他們作為參數傳遞。

function animation(tag,target) {

var timer = null,

currentDistance = tag.offsetLeft,

step = 5;

step = currentDistance < target? step: -step;// 判斷step的正負,200到400時是遞增,400到200時是遞減

timer = setInterval(function() {

if(Math.abs(currentDistance - target) > Math.abs(step)) { // 這里判斷條件也要略作改動,使用絕對值進行比較

currentDistance += step; /

tag.style.left = currentDistance + 'px';

}else {

tag.style.left = target + 'px' // 當當前距離與目標距離之間的差值小於step改變的距離時,我們直接讓盒子移動到目標距離。

clearInterval(timer);

timer = null;

}

},17)

}

var btns = document.querySelectorAll('input'),

dv = document.querySelector('div');

btns[0].addEventListener('click',function() )

btns[1].addEventListener('click',function() )

</script>

</body>

</html>

3、盒子來回運動的函數我們封裝好了,但是我們再想一下輪播圖的滾動效果,它並不是勻速移動,而是最開始很塊,在接近滾動完成時,速度又逐漸減低。

需求: 讓盒子緩動(也就是變速運動)

上代碼~

function animation(tag,target) {

var timer = null;

timer = setInterval(function() {

var currentDistance = tag.offsetLeft,

step = (target - currentDistance) / 5;// 通過目標距離與當前距離的差除以5便達到了我們需要的變速運動,因為step每次定製器執行都要改變,所以放入定時器內

step = step > 0 ? Math.ceil(step):Math.floor(step);// 這里如果將currentDistance定時器外面聲明可以不用寫,如果放在定時器內聲明,因為offsetLeft取整的特性,要對step進行取整

if(Math.abs(currentDistance - target) > Math.abs(step)) {

currentDistance += step;

tag.style.left = currentDistance + 'px';

}else {

tag.style.left = target + 'px'

clearInterval(timer);

timer = null;

}

},17)

好了,一個輪播圖需要的最基本的緩動函數完成了~

這里補充一個比較完整的緩動函數:它的功能更全面一點,可以同時更改多樣式。

function perfectAnimate(tag, obj, fn) {// 傳三個參數,運動的盒子,對象(可以傳多個屬性),回調函數(在執行完後可以再執行自定義的功能)

clearInterval(tag.timer);// 這里將定時器作為tag標簽的屬性保存,可以多次調用函數清除上一個定時器。

tag.timer = setInterval(function () {

var flag = true;

for (var k in obj) {

// 因為並不是所有屬性都帶px單位,所以這里進行判斷分別設置

if (k == 'opacity') {

var currentDistance = getStyle(tag, k) * 100,

target = obj[k] * 100,

step = (target - currentDistance) / 10;

step = step > 0 ? Math.ceil(step) : Math.floor(step);

currentDistance += step;

tag.style[k] = currentDistance / 100;

} else if (k == 'zIndex') {

tag.style[k] = obj[k];

else {

var currentDistance = parseInt(getStyle(tag, k)) || 0,

target = obj[k],

step = (target - currentDistance) / 10;

step = step > 0 ? Math.ceil(step) : Math.floor(step);

currentDistance += step;

tag.style[k] = currentDistance + 'px';

}

if (target != currentDistance) {

flag = false // 隻要還有屬性沒有運動完成,就不會清楚定時器

}

}

if (flag) {

clearInterval(tag.timer)

fn && fn();// 所有定時器走完,這里執行回調函數,短路操作避免不傳回調函數也不會報錯。

}

}, 17)

}

// 獲取樣式的兼容函數,上面的緩動函數的依賴

function getStyle(tag, attr) {

if (tag.currentStyle) {

return tag.currentStyle[attr];

} else {

return getComputedStyle(tag, null)[attr];

}

}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持路飯。

本文地址:

ADVERTISEMENT