幾種原生js輪播圖

因爲各類各樣的緣由(好比說懶),本文直接在代碼裏面用註釋+序號記錄實現的思路javascript

1.普通版

原理:一個包含多張圖片的ul,其中全部的li左浮動成一排,實際過程就是將ul往左(右)邊移動,改變left值。css

效果圖:實際應用的時候.screen的overflow:hidden。只能看到中間方框的部分
在線demo
clipboard.pngjava

HTMLcss3

<div class="all" id="box">
  <div class="screen">
    <ul>
      <li><a href="javascript:;"><img src="images/01.jpg" ></a></li>
      <li><a href="javascript:;"><img src="images/02.jpg"></a></li>
      <li><a href="javascript:;"><img src="images/03.jpg"></a></li>
      <li><a href="javascript:;"><img src="images/04.jpg"></a></li>
      <li><a href="javascript:;"><img src="images/05.jpg"></a></li>
    </ul>
    <ol>
                
    </ol>
   </div>
   <div id="arr"><span class="left">&lt;</span><span class="right">&gt;</span></div>
</div>

其中<ol></ol>用來存放動態生成的小方塊。c++

css部分代碼git

.screen li {
  width: 200px;
  height: 200px;
  overflow: hidden;
  float: left;
}
.all ol li {
  float: left;
  width: 20px;
  height: 20px;
  background: #fff;
  border: 1px solid red;
  margin-left: 10px;
  cursor: pointer;
}
.all ol li.current {
  background: yellow;
}

js(有用了本身封裝的一個動畫函數)github

//動畫函數
function animate(el, target){
    if(el.timer) {
        clearInterval(el.timer);
    }
    el.timer = setInterval(function () {
        //leader = leader + step
        var leader = el.offsetLeft;
        var step = 30;
        if(target < leader) {
            step = -step;
        }
        //若是到達終點的距離已經小於一步了,就直接跨到終點。
        if(Math.abs(target-leader) >= Math.abs(step)) {
            leader = leader + step;
            el.style.left = leader + "px";
        }else {
            clearInterval(el.timer);
            el.style.left = target + "px";
        }
    }, 15);
}
    //1. 找對象
    var box = document.querySelector(".all");
    var screen = document.querySelector(".screen");
    var ul = screen.children[0];
    var ullis = ul.children;
    var ol = screen.children[1];
    var arr = document.querySelector("#arr");
    var leftArr = arr.querySelector(".left");
    var rightArr = arr.querySelector(".right");
    var imgwidth = screen.offsetWidth;

    var pic = fk = 0;
    var timer;
    //2. 動態建立結構
    //2.1 建立小方塊,ulLis
    //根據ul中li的個數建立小方塊
    for(var i = 0; i < ullis.length; i++){
        var li = document.createElement("li");
        ol.appendChild(li);
        li.innerHTML = i + 1;
    }
    var ollis = ol.children;
    ollis[0].className = "current";

    //2.2 建立假圖片
    //2.2.1 克隆ul下的第一個li
    var cloneli = ullis[0].cloneNode(true);
    ul.appendChild(cloneli);
    //3. 簡單輪播功能
    //3.1 給小方塊註冊點擊事件
    for(var i=0;i<ollis.length;i++){
        ollis[i].index=i;//存索引
        ollis[i].addEventListener("click", function(){
            //3.2 小方塊高亮排他
            for(var i=0;i<ollis.length;i++){
                ollis[i].className="";
            }
            this.className="current";
            //3.3. 移動ul
            var target=-this.index*imgwidth;
            animate(ul,target);

            pic=fk=this.index;
        })
    }

    //4. 左右焦點功能(無縫)
    //4.1 鼠標通過盒子,顯示箭頭
    box.onmouseover = function(){
        arr.style.display = "block";
        //清除定時器
        clearInterval(timer);
    }
    //4.2 鼠標離開盒子,隱藏箭頭
    box.onmouseleave = function(){
        arr.style.display = "none";
        timer = setInterval(function(){
            rightArr.onclick();
        },1000)
    }
    //4.3 點擊右箭頭
    rightArr.onclick = function(){
        //若是已經到了最後一張假圖片,讓ul瞬移到第一張真圖片
        if(pic === ollis.length){
            ul.style.left = 0;
            pic = 0;
        }
        pic++;//記錄出去的圖片張數

        fk++;
        if(fk === ollis.length){
            fk = 0;
        }
        for(var i = 0; i < ollis.length;i++){
            ollis[i].className = "";
        }
        ollis[fk].className = "current";
        var target = -pic*imgwidth;
        animate(ul,target);
    }
    //4.4 點擊左箭頭
    leftArr.onclick = function(){
        if(pic === 0){
            ul.style.left = -(ullis.length - 1)*imgwidth + "px";
            pic = ullis.length - 1;
        }
        pic--;

        //同步小方塊
        fk--;
        if(fk === -1){
            fk = ollis.length - 1;
        }
        for(var i = 0; i < ollis.length; i++){
            ollis[i].className = "";
        }
        ollis[fk].className = "current";
        var target = -pic*imgwidth;
        animate(ul,target);
    }
    //5. 自動播放的功能
    timer = setInterval(function(){
        rightArr.onclick();
    },1000)
    //6. 同步問題
    //6.1 點擊右箭頭,同步
    //6.2 點擊左箭頭,同步
    //6.3 點擊小方塊,同步

2. 3D版

原理:切割的思路實際上是讓四個圖片拼成一個圖片 ,而且讓每一張圖片都往左走必定的距離結合了css3動畫web

效果圖:在線democss3動畫

clipboard.png

HTMLapp

<div class="box">
  <ul>
    <li><img src="imgs/1.jpg"></li>
    <li><img src="imgs/2.jpg"></li>
    <li><img src="imgs/3.jpg"></li>
    <li><img src="imgs/4.jpg"></li>
  </ul>
  <ul>
    <li><img src="imgs/1.jpg"></li>
    <li><img src="imgs/2.jpg"></li>
    <li><img src="imgs/3.jpg"></li>
    <li><img src="imgs/4.jpg"></li>
  </ul>
  <ul>
    <li><img src="imgs/1.jpg"></li>
    <li><img src="imgs/2.jpg"></li>
    <li><img src="imgs/3.jpg"></li>
    <li><img src="imgs/4.jpg"></li>
  </ul>
  <ul>
    <li><img src="imgs/1.jpg"></li>
    <li><img src="imgs/2.jpg"></li>
    <li><img src="imgs/3.jpg"></li>
    <li><img src="imgs/4.jpg"></li>
  </ul>    
</div>
<div class="btn_wrap">
  <button>向上翻轉按鈕</button>
  <button>向下翻轉按鈕</button>
</div>

不要把按鈕放到box裏面,一旦放到這裏面,它默認就會成爲一個項目,從而影響整個的ul。

css部分代碼

*{
        padding:0;
        margin:0;
        list-style-type: none;
    }
    .box{
        width:533px;
        height:300px;
        margin:100px auto 0;
        border: 1px solid #000;
        /* 讓盒子變成一個伸縮容器 */
        display:flex;
    }
    /* 第一步  須要製做出一個長方體 */
    .box ul{
        width:533px;
        height:300px;
        position:relative;
        transform-style: preserve-3d;
        transition: transform 1s;
    }
    .box ul:nth-child(1){
        transition-delay: 0s;
    }
    .box ul:nth-child(2){
        transition-delay: 0.2s;
    }
    .box ul:nth-child(3){
        transition-delay: 0.4s;
    }
    .box ul:nth-child(4){
        transition-delay: 0.6s;
    }
    .box > ul > li{
        /* 這裏最好是設置成width:100%  讓它繼承收縮後的UL的寬度*/
        width:100%;
        height:100%;
        position:absolute;
        left:0;
        top:0;
        /* 這個切割必定是加給li的 ul加的話會把3D空間給幹掉*/
        overflow:hidden;
    }
    .box > ul > li:nth-child(1){
        transform:rotateX(90deg) translateZ(150px);/* 上面 */
    }
    .box > ul > li:nth-child(2){
        transform:rotateX(-90deg) translateZ(150px);/* 下面 */
    }
    .box > ul > li:nth-child(3){
        transform:translateZ(150px);/* 正面 */
    }
    .box > ul > li:nth-child(4){
        transform:rotateX(180deg) translateZ(150px);/* 背面 */
    }
    .box > ul:nth-child(2) img{
        margin-left: -134px;
    }
    .box > ul:nth-child(3) img{
        margin-left: -268px;
    }
    .box > ul:nth-child(4) img{
        margin-left: -402px;
    }
    .btn_wrap{
        width:760px;
        height:0px;
        margin:0 auto;
        position:relative;
        top:-250px;
    }
    .btn_wrap button{
        width:100px;
        height:100px;
    }
    .btn_wrap button:nth-child(1){
        float: left;
    }
    .btn_wrap button:nth-child(2){
        float: right;
    }

js部分

// 需求 點擊按鈕一次,就讓長方體沿着X軸旋轉90度(是基於上一次的角度累加或者累減)
    var box = document.querySelector('.box');
    var _ul = box.querySelectorAll('ul');
    var _li = box.querySelectorAll('li');
    var btns = document.querySelectorAll('button');
    // 聲明一個信號量,以便計算須要旋轉的度數
    var num = 0;
    // 當用戶暴力點擊的時候會出現過分執行不過來的BUG狀況,須要函數節流。聲明一個開關變量
    var flag = true;
    
    _ul[_ul.length -1].addEventListener('transitionend',function(){
        console.log(1);
        // 在過渡執行完畢以後從新打開開關
        flag = true;
    })

    for(var i = 0; i < btns.length; i++){
        btns[i].setAttribute('data-index', i);
        btns[i].addEventListener('click',function(){
            if(flag){
                flag = false;
                // 每次點擊進行一次判斷後在累加或者累減
                // 經過this去找到當前對象的自定義下標
                var index = this.dataset['index'];
                if(index == 1){
                    num++;
                }else if(index == 0){
                    num--;
                }
                // 給全部的UL添加翻轉效果
                for(var i = 0; i < _ul.length; i++){
                    _ul[i].style.transform = 'rotateX('+num*90+'deg)';
                }
            }
        })
    }

3. 移動端

原理:利用定位,分爲左中右

效果圖:在線demo

clipboard.png

HTML

同普通版

css部分代碼

.carouse-wrap {
    position: relative;
    min-height: 143px;
}

.carouse-wrap li {
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    transform : translateX(100%);
}

js部分(代碼較長,只放了重點部分,完整代碼見文末)

// 將最初始的位置賦值
left = carouseWrapLi.length - 1;
center = 0;
right = 1;
// 將最開始的三張先就位
carouseWrapLi[left].style.transform = 'translateX('+ -windowWidth +'px)';
carouseWrapLi[center].style.transform = 'translateX(0px)';
carouseWrapLi[right].style.transform = 'translateX('+ windowWidth +'px)';
// 看到下一張的邏輯
function showNext(){
    // 輪轉下標
    left = center;
    center = right;
    right++;

    // 極值判斷
    if(right > carouseWrapLi.length - 1){
        right = 0;
    }

....

// 手指touch的時候去切換圖片
jdCarouse.addEventListener('touchstart',touchstartHandler);
jdCarouse.addEventListener('touchmove',touchmoveHandler);
jdCarouse.addEventListener('touchend',touchendHandler);

var startX = 0;  // 記錄開始的時候的手指落點
var moveX = 0;    // 記錄移動最終的手指落點
var starTime = null;

function touchstartHandler(event){
    // 記錄滑動開始的時間
    starTime = new Date();
    // 在最開始的時候清除定時器
    clearInterval(carouseTimer);
    // 獲取手指的落點
    startX = event.touches[0].pageX;

4. 純css3無縫滾動版

原理:結合CSS3的@keyframes

效果圖:在線demo

clipboard.png

HTML

<div class="box">
    <ul>
        <li><a href="#"><img src="imgs/1.jpg" alt=""></a></li>
        <li><a href="#"><img src="imgs/2.jpg" alt=""></a></li>
        <li><a href="#"><img src="imgs/3.jpg" alt=""></a></li>
        <li><a href="#"><img src="imgs/4.jpg" alt=""></a></li>
        <!-- 複製兩個臨時工 -->
        <li><a href="#"><img src="imgs/1.jpg" ></a></li>
        <li><a href="#"><img src="imgs/2.jpg" alt=""></a></li>
    </ul>
</div>

css

* {
    padding: 0;
    margin: 0;
    list-style-type: none;
}
.box {
    width: 533px;
    height: 200px;
    border: 1px solid #000;
    margin: 100px auto;
    position: relative;
    overflow: hidden;
}
.box:hover ul{
    /* 在hover的時候讓動畫暫停 */
    animation-play-state:paused;
}
img{
    display: block;
}
ul {
    width: 3198px;
    height: 200px;
    position: absolute;
    left: 0;
    top: 0;
    animation: wufeng 10s linear infinite;
}
@keyframes wufeng{
    0%{
        left: 0;
    }
    100%{
        left: -2132px;
    }
}
ul li{
    float: left;
}

完整代碼能夠去:
https://github.com/aloe2014/s...
https://github.com/aloe2014/s... (移動版)

(此文獻與對原生js動畫保有熱愛的咱們......)

相關文章
相關標籤/搜索