1. 程式人生 > 其它 >緩封動畫的原理和封

緩封動畫的原理和封

技術標籤:js學習jscss定位

學習目標:網頁輪播圖的實現

1.offset .client. scroll 三大家族
2.緩動動畫的原理和封
3.網頁輪播圖實現
4.節流閥 返回頂部及筋斗雲案例
5.移動端輪播圖實現
6.移動端外掛使用 及輪播圖的實現
7.html5本地儲存及記住使用者名稱案例

學習內容:

1.mouseover與mouseenter的區別

mousedown才是滑鼠按下觸發

(1)當滑鼠移動到元素上時就會觸發mouseenter事件
(2)類似mouseover ,但是二者有差別
(3) mouseover 滑鼠經過自身盒子會觸發,經過子盒子還會觸發。
mouseenter 只會經過自身盒子觸發

(4)因為mouseenter不會冒泡 。 mouseover會冒泡
(5) 跟mousrenter搭配使用的mouseleave 同樣不會冒泡

//給父親新增一個事件
father.addEventListener ( 'mouseover' , function() {
	alert(11);
}
//輸出:mouseover經過子盒子,因為會冒泡,所以會執行父盒子的函式(冒泡:son~father~body~html~document)

2.動畫原理

核心原理:通過定時器setInterval()不斷地移動盒子位置。

實現步驟:
(1)獲得盒子當前的位置。
(2)讓盒子在當前位置上加1個移動距離。

(3)利用定時器不斷重複這個操作。

   <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>


<body>
    <div></div>
    <script>
        //(1)獲得盒子當前的位置。
        // (2)讓盒子在當前位置上加1個移動距離。
        // (3)利用定時器不斷重複這個操作。
        //4.加一個結束定時器的條件
        //5.注意此元素需要新增定位,才能使用element.style.left
        var div = document.querySelector('div');
        
        var timer = window.setInterval( function() {
            if(div.offsetLeft >= 400 ) {
                //停止動畫(停止定時器)
                clearInterval(timer);
            } 
            div.style.left = div.offsetLeft + 5 +'px';
            
        },500);
    </script>
</body>

3.簡單動畫封裝

 //animate:動畫    target:目標
 function animate(obj, target) {
            var timer = window.setInterval(function () {
                if (obj.offsetLeft >= target) {
                    //停止動畫(停止定時器)
                    clearInterval(timer);
                } 
                obj.style.left = obj.offsetLeft + 5 + 'px';
                
            }, 500);
        }
        var div = document.querySelector('div');

        //呼叫函式(這裡是普通函式)

        animate(div, 400);

5.動畫函式-給不同元素記錄不同的定時器

1.給不同的元素記錄不同的定時器

首先給物件新增屬性的方法

//給物件新增屬性
         var obj = {};
         obj.name= 'a';

其次

   function animate(obj, target) {
            obj.timer = window.setInterval(function () {
                //用obj.timer 相比var timer的好處: 1.只是給obj添加了一個屬性不會開闢新的空間消耗記憶體 
                //var宣告會佔記憶體 2.每個物件都有自己獨立的定時器了
                if (obj.offsetLeft >= target) {
                    //停止動畫(停止定時器)
                    clearInterval(obj.timer);
                } 
                 obj.style.left = obj.offsetLeft + 10 + 'px';
                
            }, 30);
        }

2.會有bug 當你給動畫加了執行按鈕,重複點選按鈕時,元素的速度會越來越快
(因為開啟了太多的定時器)

<body>
    <button>執行</button>
    <div></div>
    <script>

        // //給物件新增屬性
        //  var obj = {};
        //  obj.name= 'a';
        
        function animate(obj, target) {
            //執行時先清除定時器
            clearInterval(obj.timer);
            obj.timer = window.setInterval(function () {
                //用obj.timer 相比var timer的好處: 1.只是給obj添加了一個屬性不會開闢新的空間消耗記憶體 
                //var宣告會佔記憶體 2.每個物件都有自己獨立的定時器了
                if (obj.offsetLeft >= target) {
                    //停止動畫(停止定時器)
                    clearInterval(obj.timer);
                } 
                 obj.style.left = obj.offsetLeft + 10 + 'px';
                
            }, 30);
        }
        var div = document.querySelector('div');
        var btn = document.querySelector('button');

        //呼叫函式(這裡是普通函式)

        btn.addEventListener('click',function() {
            animate(div,400);
        })


    </script>
</body>

重點

  function animate(obj, target) {
            //執行時先清除定時器
            clearInterval(obj.timer);
            obj.timer = window.setInterval(function () {

6.緩動函式原理

緩動動畫就是讓元素運動有所變化,最常見的是讓速度慢慢停下來(效果柔和)

(1)讓盒子每次移動的距離慢慢變小,速度就會慢慢落下來
(2)核心演算法:(目標值-現在的位置)/10 作為每次移動的距離步長
(3)停止的條件:讓當前的盒子位置等於目標位置就停止定時器

    <button>執行</button>
    <div></div>
    <script>
        // (1)讓盒子每次移動的距離慢慢變小,速度就會慢慢落下來
        // (2)核心演算法:(目標值-現在的位置)/10   作為每次移動的距離步長
        function animate(obj, target) {

            //執行時先清除定時器
            clearInterval(obj.timer);

            obj.timer = window.setInterval(function () {

                //步長值寫在定時器的裡面(隨著改變的)

                var step = (target - obj.offsetLeft)/10;

                if (obj.offsetLeft >= target) {
                    clearInterval(obj.timer);
                } 
                 obj.style.left = obj.offsetLeft + step + 'px';
                
            }, 50);
        }
        var div = document.querySelector('div');
        var btn = document.querySelector('button');
        //呼叫函式(這裡是普通函式)

        btn.addEventListener('click',function() {
            animate(div,400);
        })
    </script>

勻速動畫:盒子當前的位置 + 固定的值
緩動動畫: 盒子當前的位置 + 慢慢變小的值

但是有bug,即盒子在按鈕點選後並沒有在400停下,而是395.5:(有了小數就無法達到目標值)——把步長值改為整數,不要出現小數的問題。

/把步長值改為整數,不要出現小數的問題。
                //取整步長值Math.ceil  向上取整數
                var step = Math.ceil((target - obj.offsetLeft)/10);

7.緩動動畫多個目標值之間移動

使盒子在400~800間來回移動

<body>
    <button class="btn400">執行到400</button>
    <button class="btn800">執行到800</button>
    <div></div>
    <script>
        // (1)讓盒子每次移動的距離慢慢變小,速度就會慢慢落下來
        // (2)核心演算法:(目標值-現在的位置)/10   作為每次移動的距離步長
        function animate(obj, target) {

            //執行時先清除定時器
            clearInterval(obj.timer);

            obj.timer = window.setInterval(function () {

                //步長值寫在定時器的裡面(隨著改變的)
                //把步長值改為整數,不要出現小數的問題。
                //取整步長值    往上取整Math.ceil  往下取整Math.floor

                
                //前進的時候   步長取整  8.1 取 9   往大了取
                //返回的時候,步長取整是負數,-8.1  應該取-9 ,往小了取

                var step =(target - obj.offsetLeft)/10;

                //加判斷條件,step是正是負
                step = step > 0 ? Math.ceil(step) : Math.floor(step);

                if (obj.offsetLeft == target) {//這裡不能用>= 得用==  不然沒法回來
                    clearInterval(obj.timer);
                } 
                 obj.style.left = obj.offsetLeft + step + 'px';
                
            }, 50);
        }
        var div = document.querySelector('div');
        var btn400 = document.querySelector('.btn400');
        var btn800 = document.querySelector('.btn800');
        //呼叫函式(這裡是普通函式)

        btn400.addEventListener('click',function() {
            animate(div,400);
        })

        btn800.addEventListener('click',function() {
            animate(div,800);
        })
    </script>

</body>

8.給緩動動畫添加回調函式

回撥函式原理:函式可以作為一個引數,將這個函式作為引數傳遞到另一個函式裡面,當那個函式執行完之後,再執行傳進去這個函式,這個過程就叫做回撥(callback)。

回撥函式寫的位置:定時器結束


        function animate(obj, target,callback) {
            //執行時先清除定時器
            clearInterval(obj.timer);
            obj.timer = window.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';
            }, 50);
        }
btn800.addEventListener('click',function() {
            animate(div,800,function() {});
        })

重點

1. function animate(obj, target,callback) {
2.    clearInterval(obj.timer);
                    //回撥函式寫到定時器裡面  定時器結束才執行回撥函式
                    if (callback) {
                        //呼叫函式
                        callback();
                    }
3.btn800.addEventListener('click',function() {
            animate(div,800,function() {});
        })
 

9.動畫函式的使用

(1)動畫函式封裝到一個單獨的Js檔案,使用的時候可以引用這個函式

注意offsetleft返回以帶定位父元素的偏移值(父元素有定位,返回與父元素的偏移值)

<!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>
        .sliderbar {
            position: fixed;
            right: 0;
            bottom: 100px;
            width: 40px;
            height: 40px;
            text-align: center;
            line-height: 40px;
            cursor: pointer;
            color: #fff;
        }

        .con {
            /* 父親加了固定定位,以父親為準 */
            position: absolute;
            left: 0;
            top: 0;
            width: 200px;
            height: 40px;
            background-color: purple;
            z-index: -1;
        }
    </style>

    <script src="animate.js"></script>
</head>

<body>
    <div class="sliderbar">
        <span>←</span>
        <div class="con">問題反饋</div>
    </div>

    <script>
        var sliderbar = document.querySelector('.sliderbar');
        var con = document.querySelector('.con');
        sliderbar.addEventListener('mouseenter', function() {//不會冒泡
            animate(con,-160,function() {
                //當我們動畫執行完畢,就把⬅改為➡
                sliderbar.children[0].innerHTML = '➡';
            })//沒有callback就直接忽略
            
            
        })

        sliderbar.addEventListener('mouseleave', function() {//不會冒泡
            animate(con,0,function() {
                //當我們動畫執行完畢,就把⬅改為➡
                sliderbar.children[0].innerHTML = '➡';
            })//沒有callback就直接忽略
            
            
        })

    </script>

</body>

</html>

重點

 <script src="animate.js"></script>

效果
在這裡插入圖片描述