三種方式實現輪播圖功能


手動實現輪播圖

使用純HTMLCSSJavaScript實現輪播圖功能。

position

使用position的絕對定位與相對定位實現輪播圖,首先將圖片全部拼接成為一行,使用overflow: hidden;將其他圖片隱藏,將這一行圖片加入定時任務不斷進行左移,從而只顯示中間的圖片,對於邊緣特殊處理,將第一張輪播圖追加到一行圖片之后,當切換到最后一張輪播圖時,下一張即播放第一張圖,當此圖輪播完成后,將所有圖片歸位,提供兩個DEMO,第一個是單純的輪播不存在任何控制按鈕,第二個則比較完善。

實例

<!-- 
    簡單DEMO,未實現任何控制,單純圖片輪播 
-->

<!DOCTYPE html>
<html>
<head>
    <title>輪播圖</title>
    <meta charset="utf-8">
    <meta name="referrer" content="no-referrer">
</head>
<style type="text/css">
    body{
        margin: 0;
        padding: 0px;
    }
    #carousel{
        margin: auto; /* 居中 */
        width: 600px; /* 設置寬度 */
        position: relative; /* 相對定位 */
        overflow: hidden; /* 超出隱藏 */
    }
    #carousel img{
        width: 600px; /* 設定大小 按比例縮放 */
    }
    #carousel > ul {
        display: flex; /* 圖片處理為一行 */
        position: absolute; /* 設置絕對定位,實現相對於#carousel的絕對定位 */
    }
    #carousel > ul,
    #carousel > ul > li{
        padding: 0;
        margin: 0;
        list-style:none; 
    }
</style>
<body>
    <!-- 輪播圖容器 -->
    <div id="carousel">
        <ul> <!-- 圖片容器 -->
            <li>
                <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
            </li>
        </ul>
    </div>
</body>
    <script type="text/javascript">
        var imgArr = []; // 圖片數組
        var curIndex = 0; // 當前顯示圖片
        var timer = null; // 定時器
        
        function slide(slideContainer){
            var width = imgArr[curIndex].width; // 獲取圖片寬度,也就是每次切換圖片要滑動的距離
            var distanceMoved = 0; // 已經移動的距離
            var step = 10; //切換的步長
            var curConLeft = slideContainer.offsetLeft; // 獲取ul的left
            var slideInterval = setInterval(function (){ // 此定時器是為了實現切換動畫
                if(Math.abs(width - distanceMoved) > step){ // 邊界判定,判斷已移動距離以及應移動距離的差與步長關系
                    curConLeft -= step; // 大於步長則不斷移動
                    slideContainer.style.left = `${curConLeft}px`; // 移動
                    distanceMoved += step; // 已移動距離加步長
                }else{ 
                    clearInterval(slideInterval); // 若最后移動距離不足步長,則清除動畫定時器
                    slideContainer.style.left = `${curConLeft - width + distanceMoved }px`; // 直接完成此次動畫
                    distanceMoved = 0; // 重設移動距離為0
                    if(++curIndex === imgArr.length){ // index加1,判斷是否為最后一張來作邊緣處理
                        curIndex = 0; // 最后一張則重置index
                        slideContainer.style.left = 0;  // 重置ul
                    }
                }
            }, 10);
        }

        (function start() {
            var config = {
                height: "300px", // 配置高度
                interval: 5000 // 配置輪播時間間隔
            }
            document.getElementById("carousel").style.height = config.height; // 將輪播容器高度設定
            document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // 獲取所有圖片組成數組
            var slideContainer = document.querySelector("#carousel > ul"); // 獲取ul也就是一行圖片的容器
            var li = document.createElement("li"); // 創建<li>
            var img = document.createElement("img"); // 創建新的<img>
            img.src = imgArr[0].src; // 設置圖片src
            li.appendChild(img); // 追加<img>到<li>
            slideContainer.appendChild(li); // 將第一張圖片追加到輪播圖的最后,作邊緣處理
            timer = setInterval(() => {slide(slideContainer)},config.interval); // 設置定時器定時切換
        })();
    </script>
</html>
<!-- 
    加入控制按鈕,上一張與下一張,直接切換按鈕
    將第一張圖片的邊緣化進行處理
    對瀏覽器頁面顯隱與鼠標移入移出事件的支持
-->

<!DOCTYPE html>
<html>
<head>
    <title>輪播圖</title>
    <meta charset="utf-8">
    <meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">
    body{
        margin: 0;
        padding: 0px;
    }
    #carousel{
        margin: auto; /* 居中 */
        width: 600px; /* 設置寬度 */
        position: relative; /* 相對定位 */
        overflow: hidden; /* 超出隱藏 */
    }
    #carousel img{
        width: 600px; /* 設定大小 按比例縮放 */
    }
    #carousel > ul {
        display: flex; /* 圖片處理為一行 */
        position: absolute; /* 設置絕對定位,實現相對於#carousel的絕對定位 */
    }
    #carousel > ul,
    #carousel > ul > li{
        padding: 0;
        margin: 0;
        list-style:none; 
    }

    /* 控制按鈕的樣式 */
    #leftArrow,
    #rightArrow{
        position: absolute;
        left: 5px;
        top: 43%;
        width: 25px;
        height: 30px;
        background-color: #eee;
        display: flex;
        justify-content: center;
        align-items: center;
        opacity: 0.7;
        font-size: 20px;
        cursor: pointer;
    }
    #rightArrow{
        left: auto;
        right: 5px;
    }
    #sliderBtn{
        position: absolute;
        width: 100%;
        bottom: 0;
        display: flex;
        justify-content: flex-end;
    }
    .unitBtn{
        width: 10px;
        height: 10px;
        background-color: #eee;
        border-radius: 10px;
        margin: 10px;
        cursor: pointer;
    }
    .active{
        background-color: #4C98F7;
    }
</style>
<body>
    <!-- 輪播圖容器 -->
    <div id="carousel">
        <ul> <!-- 圖片容器 -->
            <li>
                <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
            </li>
        </ul>
        <!-- 按鈕組 -->
        <div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- 左箭頭切換按鈕 -->        
        <div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- 右箭頭切換按鈕 --> 
        <div id="sliderBtn"></div> <!-- 切換按鈕組 -->
    </div>
</body>
    <script type="text/javascript">
        var imgArr = []; // 圖片數組
        var curIndex = 0; // 當前顯示圖片
        var timer = null; // 定時器
        var clickAllow = true; // 鎖,是否允許用戶點擊
        var btnList = []; // 右下角切換按鈕組
        
        function slide(slideContainer , targetIndex = curIndex + 1){
            var width = 0; // 計算切換圖片要滑動的距離
            if(targetIndex > curIndex){
                for(let i=curIndex;i<targetIndex;++i) width+=imgArr[i].width; // 正向切換則計算本圖片到后續圖片寬度
            }else{
                if(targetIndex === -1) width = imgArr[imgArr.length-1].width; // 特殊處理第一張圖片
                else for(let i=targetIndex;i<curIndex;++i) width+=imgArr[i].width; // 逆向切換處理寬度
            }
            clickAllow = false; // 不允許用戶點擊
            var step = width/60; // 動態設置步長
            step = targetIndex > curIndex ? step : -step; // 正向逆向切換 
            var curConLeft = slideContainer.offsetLeft; // 獲取ul的left
            var distanceMoved = 0; // 已經移動的距離
            var slideInterval = setInterval(function (){ // 此定時器是為了實現切換動畫
                if(Math.abs(width - distanceMoved) > Math.abs(step)){ // 邊界判定,判斷已移動距離以及應移動距離的差與步長關系
                     curConLeft -= step; // 大於步長則不斷移動
                    slideContainer.style.left = `${curConLeft - step}px`; // 移動
                    distanceMoved += Math.abs(step); // 已移動距離加步長
                }else{ 
                    clearInterval(slideInterval); // 若最后移動距離不足步長,則清除動畫定時器
                    var directMove = step > 0 ? (curConLeft - width + distanceMoved) : (curConLeft + width - distanceMoved); // 正向移動與逆向移動的計算方式不同
                    slideContainer.style.left = `${directMove}px`; // 直接完成此次動畫
                    distanceMoved = 0; // 重設移動距離為0
                    curIndex = targetIndex; // 設置當前index
                    if(curIndex === imgArr.length){ // index加1,判斷是否為最后一張來作邊緣處理
                        curIndex = 0; // 最后一張則重置index
                        slideContainer.style.left = `-${imgArr[0].width}px`;  // 重置ul
                    }else if (curIndex === -1) {
                        curIndex = imgArr.length-1; // 第一張重置index
                        slideContainer.style.left = `-${slideContainer.offsetWidth - imgArr[imgArr.length-1].width - imgArr[0].width}px`;  // 重置ul
                    }
                    switchBtnActive(); // 右下角按鈕的切換
                    clickAllow = true; // 允許點擊
                }
            }, 10);
        }

        function switchBtnActive(){ 
            btnList.forEach((v) => {
                v.className = "unitBtn"; // 設置其他按鈕為灰色
            })
            btnList[curIndex] .className = "unitBtn active"; // 設置當前按鈕為藍色
        }

        function createBtnGroup(carousel,slideContainer,config){
            document.getElementById("leftArrow").addEventListener('click',(e) => { 
                clearInterval(timer); // 清除定時器,避免手動切換時干擾
                if(clickAllow) slide(slideContainer,curIndex-1); // 允許點擊則切換上一張
                timer = setInterval(() => {slide(slideContainer)},config.interval); // 重設定時器
            }) 
            document.getElementById("rightArrow").addEventListener('click',(e) => {
                clearInterval(timer); // 清除定時器,避免手動切換時干擾
                if(clickAllow) slide(slideContainer,curIndex+1); // 允許點擊則切換下一張
                timer = setInterval(() => {slide(slideContainer)},config.interval); // 重設定時器
            }) 
            var sliderBtn = document.getElementById("sliderBtn"); // 獲取按鈕容器的引用
            imgArr.forEach((v,i) => {
                let btn = document.createElement("div"); // 制作按鈕
                btn.className = i === 0 ?  "unitBtn active" : "unitBtn"; // 初設藍色與灰色按鈕樣式
                btn.addEventListener('click',(e) => {
                    clearInterval(timer); // 清除定時器,避免手動切換時干擾
                    if(clickAllow) slide(slideContainer,i); // // 允許點擊則切換
                    timer = setInterval(() => {slide(slideContainer)},config.interval); // 重設定時器
                }) 
                btnList.push(btn); // 添加按鈕到按鈕組
                sliderBtn.appendChild(btn); // 追加按鈕到按鈕容器
            })
        }


        function edgeDispose(slideContainer){
            var li = document.createElement("li"); // 創建<li>
            var img = document.createElement("img"); // 創建新的<img>
            img.src = imgArr[0].src; // 設置圖片src
            li.appendChild(img); // 追加<img>到<li>
            slideContainer.appendChild(li); // 將第一張圖片追加到輪播圖的最后,作邊緣處理
            var li2 = document.createElement("li"); // 創建<li>
            var img2 = document.createElement("img"); // 創建新的<img>
            img2.src = imgArr[imgArr.length-1].src; // 設置圖片src
            li2.appendChild(img2); // 追加<img>到<li>
            slideContainer.insertBefore(li2,slideContainer.firstChild); // 將最后一張圖片追加到輪播圖的最前,作邊緣處理
            slideContainer.style.left = `-${imgArr[0].width}px`; // 重設ul位置
        }

        function eventDispose(carousel,slideContainer,config){
            document.addEventListener('visibilitychange',function(){ // 瀏覽器切換頁面會導致動畫出現問題,監聽頁面切換
                if(document.visibilityState=='hidden') clearInterval(timer); // 頁面隱藏清除定時器
                else timer = setInterval(() => {slide(slideContainer)},config.interval); // 重設定時器
            });
            carousel.addEventListener('mouseover',function(){ // 鼠標移動到容器則不切換動畫,停止計時器
                clearInterval(timer); // 頁面隱藏清除定時器
            });
            carousel.addEventListener('mouseleave',function(){ // 鼠標移出容器則開始動畫
                timer = setInterval(() => {slide(slideContainer)},config.interval); // 重設定時器
            });
        }


        (function start() {
            var config = {
                height: "300px", // 配置高度
                interval: 5000 // 配置輪播時間間隔
            }
            var carousel = document.getElementById("carousel"); //獲取容器對象的引用
            carousel.style.height = config.height; // 將輪播容器高度設定
            document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // 獲取所有圖片組成數組
            var slideContainer = document.querySelector("#carousel > ul"); // 獲取ul也就是一行圖片的容器
            edgeDispose(slideContainer); // 對邊緣處理
            eventDispose(carousel,slideContainer,config); // 對一些瀏覽器事件處理
            createBtnGroup(carousel,slideContainer,config); // 按鈕組的處理
            timer = setInterval(() => {slide(slideContainer)},config.interval); // 設置定時器定時切換
        })();
    </script>
</html>

opacity

首先通過對圖片絕對定位來使圖片堆疊,通過使用opacity來控制圖片的顯示與隱藏,即不使用Js控制輪播圖的切換動畫,而使用CSS動畫來完成,由於是堆疊完成的,使用z-index也是可行的方案。

實例

<!DOCTYPE html>
<html>
<head>
    <title>輪播圖</title>
    <meta charset="utf-8">
    <meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">
    body{
        margin: 0;
        padding: 0px;
    }
    #carousel{
        margin: auto; /* 居中 */
        width: 600px; /* 設置寬度 */
        position: relative; /* 相對定位 */
        overflow: hidden; /* 超出隱藏 */
    }
    #carousel img{
        position: absolute; /* 絕對定位 使圖片堆疊 */
        width: 600px; /* 設定大小 按比例縮放 */
        transition: all .6s; /* 動畫 */
        opacity: 0; /* 隱藏 */
    }
    .imgActive{
        opacity: 1 !important; /* 顯示圖片 最高優先級 */
    }

    /* 控制按鈕的樣式 */
    #leftArrow,
    #rightArrow{
        position: absolute;
        left: 5px;
        top: 43%;
        width: 25px;
        height: 30px;
        background-color: #eee;
        display: flex;
        justify-content: center;
        align-items: center;
        opacity: 0.7;
        font-size: 20px;
        cursor: pointer;
        z-index: 1000;
    }
    #rightArrow{
        left: auto;
        right: 5px;
    }
    #sliderBtn{
        position: absolute;
        width: 100%;
        bottom: 0;
        display: flex;
        justify-content: flex-end;
        z-index: 1000;
    }
    .unitBtn{
        width: 10px;
        height: 10px;
        background-color: #eee;
        border-radius: 10px;
        margin: 10px;
        cursor: pointer;
    }
    .btnActive{
        background-color: #4C98F7;
    }
</style>
<body>
    <!-- 輪播圖容器 -->
    <div id="carousel">
        <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
        <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
        <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
        <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
        <!-- 按鈕組 -->
        <div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- 左箭頭切換按鈕 -->        
        <div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- 右箭頭切換按鈕 --> 
        <div id="sliderBtn"></div> <!-- 切換按鈕組 -->
    </div>
</body>
    <script type="text/javascript">
        var imgArr = []; // 圖片數組
        var curIndex = 0; // 當前顯示圖片
        var timer = null; // 定時器
        var btnList = []; // 右下角切換按鈕組
        
        function slide(targetIndex = curIndex + 1){
            curIndex = targetIndex % imgArr.length; // 獲取當前index
            imgArr.forEach((v) => v.className = "" ); // 設置其他圖片隱藏
            imgArr[curIndex] .className = "imgActive"; // 設置當前index圖片顯示
            btnList.forEach(v => v.className = "unitBtn") // 設置其他按鈕為灰色
            btnList[curIndex] .className = "unitBtn btnActive"; // 設置當前按鈕為藍色
        }

        function createBtnGroup(carousel,config){
            document.getElementById("leftArrow").addEventListener('click',(e) => { 
                clearInterval(timer); // 清除定時器,避免手動切換時干擾
                slide(curIndex-1); // 允許點擊則切換上一張
                timer = setInterval(() => {slide()},config.interval); // 重設定時器
            }) 
            document.getElementById("rightArrow").addEventListener('click',(e) => {
                clearInterval(timer); // 清除定時器,避免手動切換時干擾
                slide(curIndex+1); // 允許點擊則切換下一張
                timer = setInterval(() => {slide()},config.interval); // 重設定時器
            }) 
            var sliderBtn = document.getElementById("sliderBtn"); // 獲取按鈕容器的引用
            imgArr.forEach((v,i) => {
                let btn = document.createElement("div"); // 制作按鈕
                btn.className = i === 0 ?  "unitBtn btnActive" : "unitBtn"; // 初設藍色與灰色按鈕樣式
                btn.addEventListener('click',(e) => {
                    clearInterval(timer); // 清除定時器,避免手動切換時干擾
                    slide(i); // // 允許點擊則切換
                    timer = setInterval(() => {slide()},config.interval); // 重設定時器
                }) 
                btnList.push(btn); // 添加按鈕到按鈕組
                sliderBtn.appendChild(btn); // 追加按鈕到按鈕容器
            })
        }

        function eventDispose(carousel,config){
            document.addEventListener('visibilitychange',function(){ // 瀏覽器切換頁面會導致動畫出現問題,監聽頁面切換
                if(document.visibilityState=='hidden') clearInterval(timer); // 頁面隱藏清除定時器
                else timer = setInterval(() => {slide()},config.interval); // 重設定時器
            });
            carousel.addEventListener('mouseover',function(){ // 鼠標移動到容器則不切換動畫,停止計時器
                clearInterval(timer); // 頁面隱藏清除定時器
            });
            carousel.addEventListener('mouseleave',function(){ // 鼠標移出容器則開始動畫
                timer = setInterval(() => {slide()},config.interval); // 重設定時器
            });
        }


        (function start() {
            var config = {
                height: "300px", // 配置高度
                interval: 5000 // 配置輪播時間間隔
            }
            var carousel = document.getElementById("carousel"); //獲取容器對象的引用
            carousel.style.height = config.height; // 將輪播容器高度設定
            document.querySelectorAll("#carousel img").forEach((v,i) => {
                imgArr.push(v); // 獲取所有圖片組成數組
                v.className = i === 0 ?  "imgActive" : "";
            }); 
            eventDispose(carousel,config); // 對一些瀏覽器事件處理
            createBtnGroup(carousel,config); // 按鈕組的處理
            timer = setInterval(() => {slide()},config.interval); // 設置定時器定時切換
        })();
    </script>
</html>

CSS

CSS實現輪播圖,完全使用CSS3動畫完成輪播,主要使用animation屬性與@keyframes規則,使用left控制距離,也可以使用opacity,為每個圖片設置動畫屬性即可。

實例

<!DOCTYPE html>
<html>
<head>
    <title>輪播圖</title>
    <meta charset="utf-8">
    <meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">
    body{
        margin: 0;
        padding: 0px;
    }
    #carousel{
        margin: auto; /* 居中 */
        width: 600px; /* 設置寬度 */
        position: relative; /* 相對定位 */
        overflow: hidden; /* 超出隱藏 */
        height: 300px;
    }
    #carousel img{
        width: 600px; /* 設定大小 按比例縮放 */
    }
    #carousel > ul {
        display: flex; /* 圖片處理為一行 */
        position: absolute; /* 設置絕對定位,實現相對於#carousel的絕對定位 */
    }
    #carousel > ul,
    #carousel > ul > li{
        padding: 0;
        margin: 0;
        list-style:none; 
    }

    #carousel > ul{
         animation: switch 10s ease 1s infinite alternate; /* 設定動畫播放 */
    }

    #carousel > ul:hover{
         animation-play-state: paused; /* 暫停動畫 */
    }

    @keyframes switch{ /* 制定動畫規則 */
        0%,13%{
            left: 0;
        }
        27%,41%{
            left: -600px;
        }
        55%,69%{
            left: -1200px;
        }
        83%,100% {
            left: -1800px;
        }
    }
</style>
<body>
    <!-- 輪播圖容器 -->
    <div id="carousel">
        <ul> <!-- 圖片容器 -->
            <li>
                <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
            </li>
            <li>
                <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
            </li>
        </ul>
    </div>
</body>
</html>

每日一題

https://github.com/WindrunnerMax/EveryDay


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM