1. 程式人生 > 實用技巧 >PC端網頁特效

PC端網頁特效

1.元素偏移量offset系列

· 獲得元素距離帶有定位父元素的位置
· 獲得元素自身的大小(寬度高度)
· 注意:返回的數值都不帶單位

offset 系列常用屬性

<script type="text/javascript">
            var father = document.querySelector('.father');
            var son = document.querySelector('.son');
            //1.可以得到元素的偏移位置 返回的不帶單位的數值
            console.log(father.offsetTop);
            
//它以帶有定位的父級為準,如果沒有父級或者父級沒有定位 則以body為準 console.log(son.offsetLeft); //2.可以得到元素的大小 寬度和高度 是包含padding + border + width console.log(father.offsetWidth); //3.返回帶有定位的父級,否則返回的是body console.log(son.offsetParent);//返回帶有定位的父級,否則返回的是body console.log(son.parentNode);//
返回最近一級的父級 不管父級有沒有定位 </script>

1.2 offset 與style區別

拖動的模態框 案例

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            *{
                padding: 0;
                margin: 
0; } .login-header{ text-align: center; margin: 200px 0 0; } .login{display: none; width: 512px; height: 280px; position: fixed; border: 1px solid #ebebeb; left: 50%; top: 50%; background: #fff; box-shadow: 0px 0px 20px #ddd; z-index: 9999; transform: translate(-50%,-50%); cursor: move; } .login-title{ width: 100%; margin: 10px 0 0 0; text-align: center; line-height: 40px; height: 40px; } .login-input-content{ margin-top: 20px; } .login-button{width: 50%; margin: 30px auto 0; line-height: 40px; font-size: 14px; border: 1px solid #EBEBEB; text-align: center; } .login-bg{ display: none; width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0,0,0,.3); } a{ text-decoration: none; color: #000; } .login-button a{ display: block; } .login-input input.list-input{ float: left; line-height: 35px; height: 35px; width: 350px; border: 1px solid #EBEBEB; text-indent: 5px; } .login-input{ overflow: hidden; margin: 0 0 20px; } .login-input label{ float: left; width: 90px; padding-right: 10px; text-align: right; line-height: 35px; height: 35px; font-size: 14px; } .login-title span{ position: absolute; font-size: 12px; right: -20px; top: -30px; background-color: #FFFFFF; border: 1px solid #ebebeb; width: 40px; height: 40px; border-radius: 20px; } </style> </head> <body> <div class="login-header"><a id="link" href="javascript:;">點選,彈出登陸框</a></div> <div id="login" class="login"> <div id="title" class="login-title"> 登入會員<span><a href="" id="closeBtn" class="close-login">關閉</a></span> </div> <div class="login-input-content"> <div class="login-input"> <label>使用者名稱:</label> <input type="text" id="username" placeholder="請輸入使用者名稱" name='info[username]' class="list-input" /> </div> <div class="login-input"> <label>登入密碼:</label> <input type="password" placeholder="請輸入登入密碼" name="info[password]" id="password" class="list-input"/> </div> </div> <div id="loginBtn" class="login-button"><a href="javascript:void(0)" id="login-button-submit">登入會員</a></div> </div> <!--遮蓋層--> <div id="bg" class="login-bg"></div> <script type="text/javascript"> //1.獲取元素 var link = document.querySelector('#link'); var login = document.querySelector('#login'); var closeBtn = document.querySelector('#closeBtn'); var bg = document.querySelector('#bg'); var title = document.querySelector('#title'); link.addEventListener('click',function(){ login.style.display = 'block'; bg.style.display = 'block'; }) closeBtn.addEventListener('click',function(){ login.style.display = 'none'; bg.style.display = 'none'; }) // 當滑鼠頂部標題欄按下,獲得滑鼠在盒子內的座標 title.addEventListener('mousedown',function(e){ //獲取滑鼠在盒子內的座標x,y var x = e.pageX - login.offsetLeft; var y = e.pageY - login.offsetTop; //當滑鼠移動 把滑鼠在頁面中的座標 減去 滑鼠在盒子內的座標 就是模態框的座標 document.addEventListener('mousemove',move) function move(e){ // login.style.left = e.pageX - x +'px'; login.style.top = e.pageY - y +'px'; } //滑鼠彈起,就讓滑鼠移動事件移除 document.addEventListener('mouseup',function(){ document.removeEventListener('mousemove',move); }) }) </script> </body> </html>
View Code

仿京東放大鏡效果 案例

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .preview_img{
                position: relative;
                width: 300px;
                height: 300px;
            }
            .proImg{
                width: 100%;
                height: 100%;
            }
            .mask{
                display: none;
                position: absolute;
                top: 0;
                left: 0;
                width: 200px;
                height: 200px;
                background: #f5e59f;
                opacity: .5;
            }
            .big{
                display: none;
                position: absolute;
                top: 0;
                left: 310px;
                width: 500px;
                height: 500px;
                z-index: 999;
                overflow: hidden;
                border: 1px solid #eee;
            }
            .big img{
                position: absolute;
                top: 0;
                left: 0;
            }
        </style>
    </head>
    <body>
        <div class="preview_img">
            <img src="../img/proImg.jpg" class="proImg"/>
            <div class="mask"></div>
            <div class="big"><img src="../img/bigImg.jpg" alt="" class="bigImg"/></div>
        </div>
        <script type="text/javascript">
            var preview = document.querySelector('.preview_img');
            var mask = document.querySelector('.mask');
            var big = document.querySelector('.big');
            //當滑鼠經過 就顯示和隱藏 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';
            })
            //滑鼠移動的時候,讓黃色盒子跟著滑鼠走
            preview.addEventListener('mousemove',function(e){
                //先計算出滑鼠在盒子內的座標
                var x = e.pageX - preview.offsetLeft;
                var y = e.pageY - preview.offsetTop;
                //減去盒子高度的一半 就是mask最終left和top值
                var maskx = x - mask.offsetWidth / 2 ;
                var masky = y - mask.offsetHeight / 2 ;
                var maskMax = preview.offsetWidth - mask.offsetWidth;
                if(maskx <= 0){
                    maskx = 0;
                }else if(maskx >= maskMax){
                    maskx = maskMax;
                }
                if(masky <= 0){
                    masky = 0;
                }else if(masky >= preview.offsetHeight - mask.offsetHeight){
                    masky = preview.offsetHeight - mask.offsetHeight;
                }
                mask.style.left = maskx +'px';
                mask.style.top = masky +'px';
                //大圖片的移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離
                var bigImg = document.querySelector('.bigImg');
                //大圖最大移動距離
                var bigMax = bigImg.offsetWidth - big.offsetWidth;
                //大圖的移動距離x y
                var bigImgx = maskx * bigMax / maskMax;
                var bigImgy = masky * bigMax / maskMax;
                bigImg.style.left = -bigImgx + 'px';
                bigImg.style.top = -bigImgy + 'px';
            })
        </script>
    </body>
</html>
View Code

2. 元素可視區client系列

client系列屬性

clientWidth與offsetWidth最大的區別就是不包含邊框

淘寶flexible.js原始碼分析

<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>

1.立即執行函式(function(){})()
立即執行函式:不需要呼叫,立馬能夠自己執行的函式。
主要作用:建立一個獨立的作用域。避免了命名衝突問題。

2.寫法:
① (function(){})()或者
② (function(){}());

<script type="text/javascript">
            //1.立即執行函式:不需要呼叫,立馬能夠自己執行的函式
            //2.寫法 也可以傳遞引數進來
            //(function(){})() 或者 (function(){}());
            (function(a,b){
                console.log(a + b);
                var num = 10;
            })(1,2);//第二個小括號可以看做是呼叫函式
            
            (function(a,b){
                console.log(a + b);
                var num = 10;//區域性變數
            }(2,3));
            //3.立即執行函式最大的作用 獨立建立了一個作用域 裡面所有變數都是區域性變數 不會有命名衝突情況
        </script>

pageshow事件(重新載入頁面觸發)

跟load事件不同的是 pageshow這個事件在頁面顯示時觸發,無論頁面是否來自快取。在重新載入頁面中,
pageshow會在load事件觸發後觸發;根據事件物件中的presisted來判斷是否是快取中的頁
面觸發的pageshow事件,注意這個事件給window新增

(function flexible (window, document) {
    //獲取html的根元素
  var docEl = document.documentElement
  //dpr 物理畫素比
  var dpr = window.devicePixelRatio || 1

  // adjust body font size 設定body字型大小
  function setBodyFontSize () {
      //如果頁面中有body這個元素 就設定body的字型大小
    if (document.body) {
      document.body.style.fontSize = (12 * dpr) + 'px'
    }
    else {
        //如果頁面中沒有body這個元素,則等頁面主要DOM元素載入完畢後設置字型大小
      document.addEventListener('DOMContentLoaded', setBodyFontSize)
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10  設定html元素的文字大小
  function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // reset rem unit on page resize 當頁面尺寸大小發生變化的時候,要重新設定下rem的大小
  window.addEventListener('resize', setRemUnit)
  //pageshow 是重新載入頁面觸發的事件
  window.addEventListener('pageshow', function (e) {
      //e.persisted 返回的是true 如果頁面是從快取取過來的頁面 也需要重新計算一下rem大小
    if (e.persisted) {
      setRemUnit()
    }
  })

  // detect 0.5px supports 有些移動端瀏覽器不支援0.5畫素的寫法
  if (dpr >= 2) {
    var fakeBody = document.createElement('body')
    var testElement = document.createElement('div')
    testElement.style.border = '.5px solid transparent'
    fakeBody.appendChild(testElement)
    docEl.appendChild(fakeBody)
    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines')
    }
    docEl.removeChild(fakeBody)
  }
}(window, document))
flexible註釋詳解

3.元素滾動scroll系列

scroll系列屬性

頁面被捲去的頭部:可以通過window.pageYOffset 獲得 如果是被捲去的左側 window.pageXOffset
元素被捲去不透 是element.scrollTop,如果是頁面被捲去頭部 則是window.pageYOffset

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .slider-bar{
                position: absolute;
                left: 50%;
                top: 300px;
                margin-left: 600px;
                width: 45px;
                height: 130px;
                background-color: pink;
            }
            .w{
                width: 1200px;
                margin: 10px auto;
            }
            .header{
                height: 150px;
                background-color: purple;
            }
            .banner{
                height: 250px;
                background-color: skyblue;
            }
            .main{
                height:1000px;
                background-color:yellowgreen;
            }
            span{
                display: none;
                position:absolute;
                bottom:0;
            }
        </style>
    </head>
    <body>
        <div class="slider-bar"><span class="goback">返回頂部</span></div>
        <div class="header w">頭部區域</div>
        <div class="banner w">banner區域</div>
        <div class="main w">主體部分</div>
        <script type="text/javascript">
            var sliderbar = document.querySelector('.slider-bar');
            var goback = document.querySelector('.goback');
            var banner = document.querySelector('.banner');
            var main = document.querySelector('.main');
            //bannerTop 就是被捲去頭部的大小 一定要寫到滾動的外面
            var bannerTop = banner.offsetTop;
            var sliderbarTop = sliderbar.offsetTop;
            var mainTop = main.offsetTop;
            //頁面滾動事件scoll
            document.addEventListener('scroll',function(){
                //window.pageYOffset 頁面被捲去的頭部
                if(window.pageYOffset> bannerTop){
                    sliderbar.style.position = 'fixed';
                    sliderbar.style.top = sliderbarTop - bannerTop + 'px';
                }else{
                    sliderbar.style.position = 'absolute';
                    sliderbar.style.top = sliderbarTop + 'px';
                    console.log(sliderbarTop);
                }
                //當頁面滾動到main盒子 就顯示goback模組
                if(window.pageYOffset > mainTop){
                    goback.style.display = 'block';
                }else{
                    goback.style.display = 'none';
                }
            })
        </script>
    </body>
</html>
仿淘寶固定側邊欄

頁面被捲去的頭部 有相容性問題,因此被捲去的頭部通常有以下幾種寫法:

① 聲明瞭DTD,使用document.documentElement.scrollTop
② 未宣告DTD,使用document.body.scrollTop
③ 新方法window.pageYOffset 和 window.pageXOffset,IE9開始支援

三大系列對比

他們主要用法:

① offset系列經常用於獲得元素位置 offsetLeft offsetTop
② client經常用於獲取元素大小 clientWidth clientHeight
③ scroll經常用於獲取滾動距離 scrollTop scrollLeft

mouseenter 和 mouseover的區別

· 當滑鼠移動到元素上時就會觸發mouseenter事件
· mouseover 滑鼠經過自身盒子會觸發,經過子盒子還會觸發。mouseenter 只經過自身盒子觸發
· 因為mouseenter 不會冒泡

4.動畫函式封裝

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

動畫物件一定要加定位

<script type="text/javascript">
            //動畫原理
            //① 獲得盒子當前位置
            //② 讓盒子在當前位置加上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';
            },30)
        </script>

4.2 動畫函式簡單封裝

注意函式需要傳遞2個引數,動畫物件和移動到的距離。

<script type="text/javascript">
            //var obg = {};
            //obg.name = 'andy';
            //簡單動畫函式封裝obj目標物件 target 目標位置
            function animate(obg,target){
                //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器
                //解決方案就是 讓元素只有一個定時器執行
                clearInterval(obj.timer);
                obj.timer = setInterval(function(){
                    if(obg.offsetLeft >= target){
                        clearInterval(timer);
                    }
                    obg.style.left = obg.offsetLeft + 1 + 'px';
                },30)
            }
            var btn = document.querySelector('button');
            btn.addEventListener('click',function(){
                animate(span,400);
            })
            animate(div,300);
        </script>

4.4緩動效果原理

緩動動畫公式:(目標值 - 現在的位置) / 10 作為每次移動的距離步長

勻速動畫 就是 盒子當前的位置 + 固定的值 10
緩動動畫 就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置)/10

<button class="btn800">點選夏雨湖到800</button>
        <button class="btn300">點選夏雨湖到300</button>
        <div></div>
        <span></span>
        <script type="text/javascript">
            //var obg = {};
            //obg.name = 'andy';
            var span = document.querySelector('span');
            var div = document.querySelector('div');
            //簡單動畫函式封裝obj目標物件 target 目標位置
            function animate(obj,target){
                //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器
                //解決方案就是 讓元素只有一個定時器執行
                clearInterval(obj.timer);
                obj.timer = setInterval(function(){
                    //緩動動畫公式:(目標值 - 現在的位置) / 10   作為每次移動的距離步長
                    //把步長值改為整數 不要出現小數問題
                    var step = (target - obj.offsetLeft) / 10;
                    step = step > 0 ? Math.ceil(step) : Math.floor(step);
                    if(obj.offsetLeft == target){
                        clearInterval(obj.timer);
                    }
                    //把每次加1 這個步長值改為一個慢慢變小的值 
                    obj.style.left = obj.offsetLeft + step + 'px';
                },40)
            }
            var btn800 = document.querySelector('.btn800');
            var btn300 = document.querySelector('.btn300');
            
            btn800.addEventListener('click',function(){
                animate(span,800);
            });
            btn300.addEventListener('click',function(){
                animate(span,300);
            })
            //勻速動畫 就是 盒子當前的位置 + 固定的值 10
            //緩動動畫 就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置)/10
        </script>

4.6 動畫函式添加回調函式
回撥函式原理:函式可以作為一個引數。將這個函式作為引數傳到另一個函式裡面,當那個函式執行完之後,再執行穿進去的這個函式,這個過程叫回撥

回撥函式 寫到定時器結束裡面

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            div{
                width: 200px;
                height: 200px;
                background-color: pink;
                position: absolute;
            }
            span{width: 300px;
                height: 300px;
                background-color: purple;
                position: absolute;
            }
        </style>
    </head>
    <body>
        <button class="btn800">點選夏雨湖到800</button>
        <button class="btn300">點選夏雨湖到300</button>
        <div></div>
        <span></span>
        <script type="text/javascript">
            //var obg = {};
            //obg.name = 'andy';
            var span = document.querySelector('span');
            var div = document.querySelector('div');
            //簡單動畫函式封裝obj目標物件 target 目標位置
            function animate(obj,target,callback){
                //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器
                //解決方案就是 讓元素只有一個定時器執行
                clearInterval(obj.timer);
                obj.timer = setInterval(function(){
                    //緩動動畫公式:(目標值 - 現在的位置) / 10   作為每次移動的距離步長
                    //把步長值改為整數 不要出現小數問題
                    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();
                        }
                    }
                    //把每次加1 這個步長值改為一個慢慢變小的值 
                    obj.style.left = obj.offsetLeft + step + 'px';
                },40)
            }
            var btn800 = document.querySelector('.btn800');
            var btn300 = document.querySelector('.btn300');
            
            btn800.addEventListener('click',function(){
                animate(span,800,function(){
                    span.style.backgroundColor = 'yellow';
                });
            });
            btn300.addEventListener('click',function(){
                animate(span,300,function(){
                    span.style.backgroundColor = 'yellow';
                })
            })
            //勻速動畫 就是 盒子當前的位置 + 固定的值 10
            //緩動動畫 就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置)/10
        </script>
    </body>
</html>
回撥函式

輪播圖案例

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="../js/animate.js" type="text/javascript"></script>
        <script src="../js/rotation.js" type="text/javascript" charset="utf-8"></script>
        <style type="text/css">
            *{
                padding: 0;
                margin: 0;
            }
            ul,ol{
                list-style: none;
            }
            .focus{
                position: relative;
                width: 720px;
                height: 455px;
                background-color: purple;
                overflow: hidden;
            }
            .focus li img{
                width: 720px;
                height: 455px;
            }
            .focus ul{
                position: absolute;
                top: 0;
                left: 0;
                width: 600%;
            }
            .focus ul li{
                float: left;
            }
            .arrow-l,.arrow-r{
                position: absolute;
                display: none;
                top: 50%;
                margin-top: -20px;
                width: 24px;
                height: 40px;
                background:rgba(0,0,0,.3);
                text-align: center;
                line-height: 40px;
                z-index: 999;
            }
            .arrow-r{
                right: 0;
            }
            .circle{
                position: absolute;
                bottom: 10px;
                left: 50px;
            }
            .circle li{float: left;
                width: 8px;
                height: 8px;
                border: 2px solid rgba(255,255,255,.5);
                margin: 0 3px;
                border-radius: 50%;
                cursor: pointer;
            }
            .current{
                background-color: #fff;
            }
            
        </style>
    </head>
    <body>
        <div class ="focus">
            <!--左側按鈕-->
            <a href="javascript:;" class="arrow-l">&lt;</a>
            <!--右側按鈕-->
            <a href="javascript:;" class="arrow-r">></a>
            <!--核心滾動區域-->
            <ul>
                <li><a href="#"><img src="../upload/focus1.jpg" alt="" /></a></li>
                <li><a href="#"><img src="../upload/focus2.jpg" alt="" /></a></li>
                <li><a href="#"><img src="../upload/focus3.jpg" alt="" /></a></li>
                <li><a href="#"><img src="../upload/focus4.jpg" alt="" /></a></li>
            </ul>
            <!--小圓圈-->
            <ol class="circle">
            </ol>
        </div>
    </body>
</html>
HTML部分
            //var obg = {};
            //obg.name = 'andy';
            //簡單動畫函式封裝obj目標物件 target 目標位置
            function animate(obj,target,callback){
                //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器
                //解決方案就是 讓元素只有一個定時器執行
                clearInterval(obj.timer);
                obj.timer = setInterval(function(){
                    //緩動動畫公式:(目標值 - 現在的位置) / 10   作為每次移動的距離步長
                    //把步長值改為整數 不要出現小數問題
                    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();
                        }
                    }
                    //把每次加1 這個步長值改為一個慢慢變小的值 
                    obj.style.left = obj.offsetLeft + step + 'px';
                },40)
            }
animateJS
window.addEventListener('load',function(){
    //1.獲取元素
    var arrow_l = document.querySelector('.arrow-l');
    var arrow_r = document.querySelector('.arrow-r');
    var focus = document.querySelector('.focus');
    var focusWidth = focus.offsetWidth;
    
    //2、滑鼠經過focus 就顯示隱藏左右按鈕
    focus.addEventListener('mouseenter',function(){
        arrow_l.style.display = 'block';
        arrow_r.style.display = 'block';
        clearInterval(timer);
        timer = null;
    })
    focus.addEventListener('mouseleave',function(){
        arrow_l.style.display = 'none';
        arrow_r.style.display = 'none';
        timer = setInterval(function(){
        //手動呼叫點選事件
        arrow_r.click();
        },2000)
    })
    //3.動態生成小圓圈 有幾張圖 就生成幾個小圓圈
    var ul = focus.querySelector('ul');
    var ol = focus.querySelector('.circle');
    
    for(var i = 0; i< ul.children.length; i++){
        //建立一個li
        var li = document.createElement('li');
        
        //記錄當前小圓圈的索引號 通過自定義屬性來做
        li.setAttribute('index',i);
        //把li插入到ol裡面
        ol.appendChild(li);
        //4.小圓圈排他思想 直接生成小圓圈的同時 直接幫定點選事件
        li.addEventListener('click',function(){
            //把所有li清除current 類名
            for(var i = 0;i < ol.children.length; i++){
                ol.children[i].className = '';
            }
            //當前的li 設定current類名
            this.className = 'current';
            //5.點選小圓圈,移動圖片 移動的是ul
            //ul 的移動距離 = 小圓圈的索引號 * 圖片的寬度  注意 是負值
            //當點選了某個li 就拿到當前li的索引號
            var index = this.getAttribute('index');
            //當點選li 就把當前的索引號 給num
            num = index;
            animate(ul,-index*focusWidth);
            //當點選li 就把當前的索引號 給circle
            circle = index;
        })
    }
    ol.children[0].className = 'current';
    //6.克隆第一張圖片(li)放到ul最後面
    var first = ul.children[0].cloneNode(true);
    ul.appendChild(first);
    //7.點選右側按鈕,圖片滾動一張
    var num = 0;
    //circle 控制小圓圈的播放
    var circle = 0;
    //flag 節流閥
    var flag = true;
    //右側按鈕做法
    arrow_r.addEventListener('click',function(){
        if(flag){
            flag = false; //關閉節流閥
            //如果走到最後 複製的一張圖片,此時 ul要快速復原 left 改為0
            if(num == ul.children.length - 1){
                ul.style.left = 0;
                num = 0;
            }
            num++;
            animate(ul, -num * focusWidth,function(){
                flag = true; //開啟節流閥
            });
            //8.點選右側按鈕,小圓圈跟隨一起變化 可以再宣告一個變數控制小圓圈的播放
            circle++;
            //如果circle == 4 說明走到最後克隆的這張圖片了 就復原
            if(circle == ol.children.length){
                circle = 0;
            }
            circleChange();
        }
    });
    //左側按鈕做法
    arrow_l.addEventListener('click',function(){
        if(flag){
            flag = false; //關閉節流閥
            //如果走到最後 複製的一張圖片,此時 ul要快速復原 left 改為0
            if(num == 0){
                ul.style.left = -num * focusWidth + 'px';
                num = ul.children.length - 1;
            }
            num--;
            animate(ul, -num * focusWidth,function(){
                flag = true; //開啟節流閥
            });
            //8.點選右側按鈕,小圓圈跟隨一起變化 可以再宣告一個變數控制小圓圈的播放
            circle--;
            //如果circle <0 說明 第一張圖片,則小圓圈要改為第4個小圓圈
    //        if(circle < 0){
    //            circle = ol.children.length - 1;
    //        }
            circle = circle < 0 ? ol.children.length - 1 : circle;
            circleChange();
        }
    });
    function circleChange(){
        //先清除其餘小圓圈的current類名
        for(var i = 0; i< ol.children.length;i++){
            ol.children[i].className = '';
        }
        ol.children[circle].className ='current';
    }
    //10.自動播放圖片
    var timer = setInterval(function(){
        //手動呼叫點選事件
        arrow_r.click();
    },2000)

})
ratationJS

5.常見網頁特效案例

5.1 節流閥

防止輪播圖按鈕連續點選造成播放過快。

節流閥目的:當上一個函式動畫內容執行完畢,再去執行下一個函式動畫,讓世界無法連續觸發。

核心實現思路:利用回撥函式,新增一個變數來控制,鎖住函式和解鎖函式。

開始設定一個變數var flag = true;
if(flag){flag = flase; do something}關閉水龍頭 程式碼在ratationJS

返回頂部案例

//3.當我們點選了返回頂部模組 就讓視窗滾動到頁面最上方
            goback.addEventListener('click',function(){
                //裡面的x和y 不跟單位 直接寫數字
                //.scroll(0,0);
                //因為是視窗 所以物件是window
                animate(window,0);
            });
                        
            //簡單動畫函式封裝obj目標物件 target 目標位置
            function animate(obj,target,callback){
                //當我們不斷的點選按鈕,這個元素的速度會越來越快 因為開啟了太多的定時器
                //解決方案就是 讓元素只有一個定時器執行
                clearInterval(obj.timer);
                obj.timer = setInterval(function(){
                    //緩動動畫公式:(目標值 - 現在的位置) / 10   作為每次移動的距離步長
                    //把步長值改為整數 不要出現小數問題
                    var step = (target - window.pageYOffset) / 10;
                    step = step > 0 ? Math.ceil(step) : Math.floor(step);
                    if(window.pageYOffset == target){
                        clearInterval(obj.timer);
                        //回撥函式寫到結束定時器裡面
//                        if(callback){
//                            callback();
//                        }
                        callback && callback();
                    }
                    //把每次加1 這個步長值改為一個慢慢變小的值 
                    window.scroll(0,window.pageYOffset + step);
                },15)
            }
返回頂部程式碼

導航筋斗雲效果 案例(呼叫的animate函式在上面的animateJS)

<div id="c_nav" class="c-nav">
            <!--筋斗雲圖片-->
            <span class="cloud"></span>
            <ul>
                <li class='current'><a href="#">首頁新聞</a></li>
                <li><a href="#">師資力量</a></li>
                <li><a href="#">活動策劃</a></li>
                <li><a href="#">企業文化</a></li>
                <li><a href="#">公司簡介</a></li>
                <li><a href="#">連續我們</a></li>
            </ul>
        </div>
        <script src="../js/animate.js" type="text/javascript" charset="utf-8"></script>
        <script>
            var cloud = document.querySelector('.cloud');
            var c_nav = document.querySelector('.c-nav');
            var lis = c_nav.querySelector('li');
            //給所有li繫結事件
            //這個current作為筋斗雲的起始位置
            var current = 0;
            for(var i = 0; i< lis.length;i++){
                //滑鼠經過把當前li的位置作為目標值
                lis[i].addEventListener('mouseenter',function(){
                    animate(cloud,this.offsetLeft);
                })
                //滑鼠離開就復原為0回到起始位置
                lis[i].addEventListener('mouseleave',function(){
                    animate(cloud,current);
                })
                //當滑鼠點選,就把當前位置作為目標值
                lis[i].addEventListener('click',function(){
                    current = this.offsetLeft;
                })
            }
        </script>