1. 程式人生 > >用原生JS實現旋轉輪播圖

用原生JS實現旋轉輪播圖

html程式碼

<div class="wrap" id="wrap">
    <div class="slide" id="slide">
        <ul>
            <li><a href="#"><img src="images/slidepic1.jpg" alt=""/></a></li>
            <li><a href="#"><img src="images/slidepic2.jpg" alt=""/></a></li>
            <li><a href="#"><img src="images/slidepic3.jpg" alt=""/></a></li>
            <li><a href="#"><img src="images/slidepic4.jpg" alt=""/></a></li>
            <li><a href="#"><img src="images/slidepic5.jpg" alt=""/></a></li>
        </ul>
        <div class="arrow" id="arrow">
            <a href="javascript:;" class="prev"></a>
            <a href="javascript:;" class="next"></a>
        </div>
    </div>
</div>

css程式碼

ol, ul {
    list-style: none
}

.wrap {
    width: 1200px;
    margin: 100px auto;
}

.slide {
    height: 500px;
    position: relative;
}

.slide li {
    position: absolute;
    left: 200px;
    top: 0;
}

.slide li img {
    width: 100%;
}

.arrow {
    opacity: 0;
}

.prev, .next {
    width: 76px;
    height: 112px;
    position: absolute;
    top: 50%;
    margin-top: -56px;
    background: url(../images/prev.png) no-repeat;
    z-index: 99;
}

.next {
    right: 0;
    background-image: url(../images/next.png);
}

JS程式碼

動畫封裝

function animate(obj, json, fn) {
    // 第一引數 動的物件   2  attr  動的那個屬性   3   屬性值少多少
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        var flag = true;  //  用來判斷是否停止定時器   定時器的裡面
        //  每隔 30 毫秒就要執行一次
        for (var k in json) {  // k 屬性     json[k] 是屬性值
            // 第一 k 是 width
            // 第二 k     height
            //  leader  =  600 -  100
            // leader = leader + (target - leader )  /10 ;
            //  計算步長
            // target 目標位置    leader 不清楚,我們不知道使用者改那個屬性
            // 檢測使用者給我們了什麼屬性,  我們就用這個屬性的值 來計算
            // 我們怎麼知道使用者給我們屬性,我們怎麼又能得到屬性的值呢?
            //  var leader = obj.style[attr];  他只能得到行內式
            var leader = 0;
            // 因為透明度是 小數   取值 0~1 之間    第二個  它沒有單位
            if (k == "opacity") {
                // 先解決小數的問題
                leader = Math.round(getStyle(obj, k) * 100) || 100;
                // 如果沒有opacity  預設當 1 看    1* 100  = 100
                // 我們去過來的是  0.3  但是小數不好計算 我們乘以100   30  好計算
            }
            else {
                leader = parseInt(getStyle(obj, k)) || 0;
                // 他本身有單位 所以要去掉    預設的預設是 0
            }
            //去掉px 的方法   parseInt(25px)   25
            /* alert(leader);*/
            var step = (json[k] - leader) / 10;
            step = step > 0 ? Math.ceil(step) : Math.floor(step);
            leader = leader + step;
            if (k == "opacity") {   // 記住我們的透明是不加單位的  不要加px
                obj.style.opacity = leader / 100;
//                    opacity: 0.4;
//                    filter: alpha(opacity = 40);     /*不能改只能是 40  不能是 0.4*/
                obj.style.filter = "alpha(opacity = " + leader + ")";
            }
            // 設定層級
            else if (k == "zIndex") {
                obj.style.zIndex = json[k];    //  直接給值
            }
            else {
                obj.style[k] = leader + "px";   // 其他的要單位
            }
            if (leader != json[k]) {  //  只要三個屬性有一個沒有到達,我就取反
                // 這句話要寫到 for in 裡面   因為有三個屬性,所以用 for in 才能遍歷
                // 三個都到了 都不執行這句話了
                flag = false;
            }
        }
        // console.log(flag);
        if (flag) {
            clearInterval(obj.timer);
            if (fn) {   // 如果有函式傳遞過來  , 定時器結束了,說明動畫結束  可以執行 回撥函式
                fn();   // 執行函式  fn + ();
            }
        }
    }, 30)
}

function getStyle(obj, attr) {
    if (obj.currentStyle) {
        // 如果支援,返回改屬性值
        //  return  obj.style.left    只能得到行內式的
        // return  obj.currentStyle["left"];   // 正確的寫法,但是left 是傳進來的
        return obj.currentStyle[attr];
    }
    else {
        return window.getComputedStyle(obj, null)[attr];
    }
}
window.onload = function () {
    var arrow = document.getElementById("arrow");  // 三角
    var wrap = document.getElementById("wrap");   // 大盒子
    var slide = document.getElementById("slide");
    var lis = slide.children[0].children;   // 獲得所有的li
    var timer = null;
    var json = [  //  包含了5張圖片裡面所有的樣式
        {   //  1
            width: 400,
            top: 20,
            left: 50,
            opacity: 20,
            z: 2
        },
        {  // 2
            width: 600,
            top: 70,
            left: 0,
            opacity: 80,
            z: 3
        },
        {   // 3
            width: 800,
            top: 100,
            left: 200,
            opacity: 100,
            z: 4
        },
        {  // 4
            width: 600,
            top: 70,
            left: 600,
            opacity: 80,
            z: 3
        },
        {   //5
            width: 400,
            top: 20,
            left: 750,
            opacity: 20,
            z: 2
        }
    ];
    wrap.onmouseover = function () {   // 滑鼠經過顯示 三角
        animate(arrow, {opacity: 100});
    }
    wrap.onmouseout = function () {  // 滑鼠離開 隱藏三角
        animate(arrow, {opacity: 0});
    }
    move(); // 頁面執行也呼叫一次
    // 兩個按鈕
    var flag = true;   // 用於函式節流
    var as = arrow.children;   // 2 個 a
    for (var k in as) {
        as[k].onclick = function () {
            // 當俺們點選的時候, 只做一件事情  ---- 交換json
            if (this.className == "prev") {  // 左側按鈕
                //  alert(11);
                if (flag == true) {   // 實現按鈕只能點選一次
                    move(true);
                    flag = false;
                }
            }
            else {
                /*  當我們點選了 右側按鈕  :
      把 數組裡面的第一個值刪掉 ,然後把這個值追加到 陣列的最後面。
       json.push(json.shift());*/
                // alert(22);   // 右側按鈕
                if (flag == true) {   // 實現按鈕只能點選一次
                    move(false);
                    flag = false;
                }
            }
        }
    }

    //移入的時候輪播停止
    slide.onmouseover = function () {
        clearInterval(timer);
        // direction.style.display = "block";
    };
    //移出的時候輪播繼續
    slide.onmouseout = function () {
        autoPlay();
        // direction.style.display = "none";
    };

    autoPlay();

    //自動輪播
    function autoPlay() {
        timer = setInterval(function () {
            move(1)
        }, 2000)
    }

    function move(x) {
        if (x != undefined) {   // 如果沒有值傳遞過來,就應該  不執行 裡面的語句直接遍歷json
            if (x) {
                // 交換 反向json   左側
                json.unshift(json.pop())
            } else {
                // 正向 json
                json.push(json.shift());
            }
        }
        // 交換完畢 json 之後,就要 迴圈執行一次
        for (var i = 0; i < json.length; i++) {
            animate(lis[i], {
                width: json[i].width,
                top: json[i].top,
                left: json[i].left,
                opacity: json[i].opacity,
                zIndex: json[i].z
            }, function () {
                flag = true;
            })
        }
    }
}