21.JavaScript實現無縫輪播圖

来源:https://www.cnblogs.com/lanshanxiao/archive/2020/05/01/12813391.html
-Advertisement-
Play Games

JavaScript實現無縫輪播圖: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0 ...


JavaScript實現無縫輪播圖:

<!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>
        .container {
            position: relative;
            width: 500px;
            height: 400px;
            border: 1px solid #fff;
            margin: 20px auto;
            overflow: hidden;
            cursor: pointer;
        }

        .container .images img {
            display: block;
            float: left;
        }

        .container .dots {
            position: absolute;
            margin: 0 auto;
            left: 0;
            right: 0;
            bottom: 10px;
            background: rgba(255, 255, 255, .3);
            padding: 5px;
            border-radius: 20px;
        }

        .container .dots span {
            margin: 2px;
            width: 8px;
            height: 8px;
            display: block;
            border-radius: 50%;
            background: rgba(255, 255, 255, .5);
            float: left;
        }

        .container .dots span.active {
            background: #f40;
        }

        .container .arrow {
            display: none;
        }

        .container:hover .arrow {
            display: block;
        }

        .container .arrow .item {
            width: 40px;
            height: 40px;
            background: rgba(255, 255, 255, .5);
            color: #fff;
            position: absolute;
            top: 0;
            bottom: 0;
            margin: auto 0;
            text-align: center;
            line-height: 40px;
            font-size: 20px;
        }

        .container .arrow .leftArrow {
            left: 0;
            border-radius: 0 20px 20px 0;
        }

        .container .arrow .rightArrow {
            right: 0;
            border-radius: 20px 0 0 20px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="images">
        </div>
        <div class="dots">
        </div>
        <div class="arrow">
            <div class="item leftArrow">&lt;</div>
            <div class="item rightArrow">&gt;</div>
        </div>
    </div>
    <script>
        var config = {
            imgWidth: 500, //圖片寬度
            dotWidth: 12, //小圓點寬度
            imageArray: ["./image/5.jpg", "./image/1.jpg", "./image/2.jpg", "./image/3.jpg", "./image/4.jpg",
                "./image/5.jpg", "./image/1.jpg"
            ], //存儲圖片路徑的數組
            doms: {
                images: document.querySelector(".images"), //存放圖片的dom
                dots: document.querySelector(".dots"), //圓點的dom
                leftArrow: document.querySelector(".item.leftArrow"), //左一張的dom
                rightArrow: document.querySelector(".item.rightArrow") //右一張的dom
            },
            currentIndex: 2, //當前展示的圖片下標
            timer: { //計時器配置
                id: null, //計時器id
                duration: 16, //每次切換圖片,運動的間隔時間
                totalTime: 1000 //每次切換圖片,運動的時間總長
            }
        };
        initImages();
        initDots();

        //初始化圖片元素
        function initImages() {
            //創建圖片元素
            config.doms.images.style.width = config.imageArray.length * config.imgWidth + "px";
            for (var i = 0; i < config.imageArray.length; i++) {
                var img = document.createElement("img");
                img.src = config.imageArray[i];
                config.doms.images.appendChild(img);
            }

            //展示第一張圖片1.jpg
            config.doms.images.style.marginLeft = -config.imgWidth * config.currentIndex + "px";
        }

        //創建圓點元素
        function initDots() {
            config.doms.dots.style.width = (config.imageArray.length - 2) * config.dotWidth + "px";
            for (var i = 0; i < config.imageArray.length - 2; i++) {
                var dot = document.createElement("span");
                config.doms.dots.appendChild(dot);
            }

            config.doms.dots.children[config.currentIndex - 1].className = "active";
        }

        //點擊左箭頭、右箭頭、和圓點
        config.doms.leftArrow.onclick = config.doms.rightArrow.onclick = config.doms.dots.onclick = function (e) {
            if (e.target.tagName === "DIV" && e.target.classList.contains("leftArrow")) { //點擊左箭頭
                var index = config.currentIndex - 1;//向左跳轉圖片的下標
                if(index === 0){//
                    index = 5;
                }
                jumpToImage(index, "left");
            } else if (e.target.tagName === "DIV" && e.target.classList.contains("rightArrow")) { //點擊右箭頭
                var index = config.currentIndex + 1;//向右跳轉圖片的下標
                if(index === 6){//
                    index = 1;
                }
                jumpToImage(index, "right");
            } else if (e.target.tagName === "SPAN" && e.target.parentElement && e.target.parentElement.classList
                .contains("dots")) { //點擊小圓點
                var index = Array.from(config.doms.dots.children).indexOf(e.target) + 1;
                jumpToImage(index, (index > config.currentIndex) ? "right" : "left");
            }
        }

        //跳轉到哪張圖片
        function jumpToImage(index, direction) { //index:下一張圖片的下標(1,25);direction方向(1.left:左;2.right:右);
            if (index === config.currentIndex) { //若要跳轉的圖片下標和當前下標一樣,不執行
                return;
            }
            if (!direction) { //方向預設:為右
                direction = "right";
            }

            //要運動到的目標marginLeft
            var newMarginLeft = -index * config.imgWidth;
            //圖片切換
            //config.doms.images.style.marginLeft = newMarginLeft + "px";
            autoPlay();
            //圓點也自動切換
            for (var i = 0; i < config.doms.dots.children.length; i++) {
                config.doms.dots.children[i].classList.remove("active");
            }
            config.doms.dots.children[index - 1].className = "active";
            //切換完成後,改變當前圖片下標
            config.currentIndex = index;

            //圖片漸變動畫,一點一點的改變marginLeft
            function autoPlay() {
                stopPlay(); //在播放輪播圖之前,把上次的動畫先停掉

                //當前的marginLeft
                var currentMarginLeft = parseFloat(window.getComputedStyle(config.doms.images).marginLeft);
                //圖片總長度,不能算第一張和最後一張,這兩張是額外增加重覆的兩張
                var allImagesLength = (config.imageArray.length - 2) * config.imgWidth;
                //1.計算運動總次數
                var frequency = Math.ceil(config.timer.totalTime / config.timer.duration);
                var currentNum = 0; //當前運動的次數
                //2.計算運動的總距離
                var allDistance = 0;
                if (direction == "left") { //向左運動
                    if (newMarginLeft > currentMarginLeft) { //目標marginLeft > 當前marginLeft
                        //總距離 = 目標marginLeft - 當前marginLeft
                        allDistance = newMarginLeft - currentMarginLeft;
                    } else {
                        //總距離 = 圖片總長度 - |目標marginLeft - 當前marginLeft|
                        allDistance = allImagesLength - Math.abs(newMarginLeft - currentMarginLeft);
                    }
                } else { //向右運動
                    if (newMarginLeft < currentMarginLeft) { //目標marginLeft < 當前marginLeft
                        //總距離 = 目標marginLeft - 當前marginLeft
                        allDistance = newMarginLeft - currentMarginLeft;
                    } else { //目標marginLeft > 當前marginLeft
                        //總距離 = -(圖片總長度 - |目標marginLeft - 當前marginLeft|)
                        allDistance = -(allImagesLength - Math.abs(newMarginLeft - currentMarginLeft));
                    }
                }
                //3.計算每次運動改變的距離
                var everyDistance = allDistance / frequency; //每次運動距離 = 運動總距離 / 運動總次數
                config.timer.id = setInterval(function () {

                    //改變圖片的marginLeft
                    currentMarginLeft += everyDistance;
                    //若圖片向右移動到額外的第一張(即數組中最後一張圖片)
                    if (direction === "right" && Math.floor(Math.abs(currentMarginLeft)) > allImagesLength) {
                        
                        currentMarginLeft += allImagesLength; //圖片瞬間挪回第一張圖片對應的位置
                    } else if (direction === "left" && Math.ceil(Math.abs(currentMarginLeft)) < config
                        .imgWidth) { //若圖片向左移動到額外的最後一張(即數組中第一張圖片)
                        currentMarginLeft -= allImagesLength; //圖片瞬間挪回最後一張圖片對應的位置
                    }
                    config.doms.images.style.marginLeft = currentMarginLeft + "px";
                    currentNum++; //每執行一次,當前運動次數++
                    if (currentNum === frequency) { //達到運動總次數,停止運動
                        stopPlay();
                    }
                }, config.timer.duration);
            }
            //停止播放
            function stopPlay() {
                clearInterval(config.timer.id);
                config.timer.id = null;
            }
        }
    </script>
</body>

</html>
index.html

效果展示:

最後一張圖片切換第一張圖片的效果

 

圖片數組存儲一共七張圖片,但是1.jpg 和 5.jpg存放了兩次,用來銜接。這樣從5.jpg切換到1.jpg的時候不會出現斷檔,五張圖片的寬高是500 X 200

 

 

 

 製作無縫輪播圖的難點:

計算運動的總距離

向左運動,目標margin-left 和 當前的margin-left

目標marginLeft > 當前marginLeft  //總距離 = 目標marginLeft - 當前marginLeft

目標marginLeft < 當前marginLeft  //總距離 = 圖片總長度 - |目標marginLeft - 當前marginLeft|

向右運動,目標margin-left 和 當前的margin-left

目標marginLeft < 當前marginLeft  //總距離 = 目標marginLeft - 當前marginLeft

目標marginLeft > 當前marginLeft  //總距離 = -(圖片總長度 - |目標marginLeft - 當前marginLeft|)

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ansbile安裝: # ansible在CentOS7中需要安裝epel倉庫 yum install -y epel-release yum install -y ansible 安裝有好幾種方法,yum安裝是最簡單的,安裝ansible不是重點。 我的版本如下: [root@szwpldb108 ...
  • 表結構 student(StuId,StuName,StuAge,StuSex) 學生表 teacher(TId,Tname) 教師表 course(CId,Cname,C_TId) 課程表 sc(SId,S_CId,Score) 成績表 問題一:查詢“001”課程比“002”課程成績高的所有學生的 ...
  • 本學期正在學習資料庫,前段時間老師讓我們做一下50個經典SQL語句,當時做的比較快,有一些也是百度的,自我感覺理解的不是很透徹。 所以從本篇隨筆開始,我將進行50個經典SQL語句的復盤,加深理解。 答案僅供參考,不一定完全正確,若發現錯誤或有更好的,歡迎評論,互相交流,一起成長!!! 表結構 stu ...
  • 一、資料庫基本概念 數據、資料庫、資料庫管理系統和資料庫系統是資料庫中最常用的四個基本概念: 資料庫:長期存儲在電腦中有組織的、可共用的數據集合; → 資料庫的特點:1、具有較小的冗餘度;2、較高的數據獨立性;3、系統易於擴展(擴展性強);4、共用程度高; 資料庫管理系統(DBMS):專門用於建立 ...
  • 我們通常下載文件的方式無非後端給一個生成文件鏈接, 前端通過a標簽或者iframe的方式去下載,這種方式的弊端是無法監測到文件是否下載完成,無法給用戶友好的提示,以避免用戶短時間內重覆點擊下載. 如果我們能用Ajax從後端拿到PDF的相關數據,再在前端下載成PDF就可以解決這個問題,那麼新的問題是: ...
  • 項目背景:在自己的主頁中添加一個百度搜索框,在裡面輸入要搜索的內容後可以直接跳轉到相關內容搜索結果的界面。搜索框是用form表單實現的,action中為百度的url,將輸入的內容拼接到url中,以實現直接跳轉到搜索結果界面。 1.觀察在百度中搜索內容時的url,打開百度一下,輸入搜索內容,如123 ...
  • 背景 在做Electron Windows 桌面應用時候,做滑鼠懸浮到托盤圖標上時顯示一個懸浮框(例如做消息提醒),但因為Windows沒有提供托盤mouse-enter/mouse-leave事件,無法直接做這個功能,考慮到還有mouse-move事件,弄個間接的方式實現。 實現步驟 1、監聽mo ...
  • 今天看著視頻學習的時候遇到了,覺得以後會遇到,就記錄下來了 需求:點擊圖片,顯示遮擋層,同時下滑顯示視頻。點擊"X",遮擋層消失,同時視頻上滑隱藏。 具體代碼: 通過v-show控制整個video-box盒子的顯示與隱藏,可以提升性能。 <div class="item-video"> <h2> 6 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...