主頁 > 前端設計 > Javascript高級知識之PC端

Javascript高級知識之PC端

2021-11-03 08:31:14 前端設計

offset

offset 翻譯過來就是偏移量,我們使用offset 系列相關屬性可以動態的得到該元素的位置(偏移)、大小等,
獲得元素距離帶有定位父元素的位置
獲得元素自身的大小(寬度高度)
注意:回傳的數值都不帶單位

在這里插入圖片描述
offset和style的區別

offset 可以得到任意樣式表中的樣式值
offset 系列獲得的數值是沒有單位的
offsetWidth 包含padding+border+width
offsetWidth 等屬性是只讀屬性,只能獲取不能賦值
所以,我們想要獲取元素大小位置,用offset更合適

style 只能得到行內樣式表中的樣式值
style.width 獲得的是帶有單位的字串
style.width 獲得不包含padding和border 的值
style.width 是可讀寫屬性,可以獲取也可以賦值
所以,我們想要給元素更改值,則需要用style改變

我們使用offest可以動態的得到該元素的位置和大小,
在這里插入圖片描述

    <div class="box" style="width: 200px;height: 200px;background: red;"></div>
    <script>
        // offset與style的區別
        var box = document.querySelector('.box');
        console.log(box.offsetWidth);
        console.log(box.style.width);
        // box.offsetWidth = '300px';
        box.style.width = '300px';
    </script>

經典案例1 獲取滑鼠在盒子內的坐標,掌味訓鼠在頁面中的坐標如何計算

    <div class="box"></div>
    <script>
        // 我們在盒子內點擊, 想要得到滑鼠距離盒子左右的距離,
        // 首先得到滑鼠在頁面中的坐標( e.pageX, e.pageY)
        // 其次得到盒子在頁面中的距離(box.offsetLeft, box.offsetTop)
        // 用滑鼠距離頁面的坐標減去盒子在頁面中的距離, 得到 滑鼠在盒子內的坐標
        var box = document.querySelector('.box');
        box.addEventListener('mousemove', function(e) {
            // console.log(e.pageX);
            // console.log(e.pageY);
            // console.log(box.offsetLeft);
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            this.innerHTML = 'x坐標是' + x + ' y坐標是' + y;
        })
    </script>

client

client翻譯過來就是客戶端,我們使用client 系列的相關屬性來獲取元素可視區的相關資訊,通過client 系列的相關屬性可以動態的得到該元素的邊框大小、元素大小等,
和我們offsetWidth 最大的區別就是 不包含邊框

在這里插入圖片描述
在這里插入圖片描述

scroll

scroll翻譯過來就是滾動的,我們使用scroll 系列的相關屬性可以動態的得到該元素的大小、滾動距離等,

在這里插入圖片描述
在這里插入圖片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
            overflow: auto;
        }
    </style>
</head>

<body>
    <div>
        我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容 我是內容
    </div>
    <script>
        // scroll 系列
        var div = document.querySelector('div');
        console.log(div.scrollHeight);
        console.log(div.clientHeight);
        // scroll滾動事件當我們滾動條發生變化會觸發的事件
        div.addEventListener('scroll', function() {
            console.log(div.scrollTop);

        })
    </script>
</body>

</html>

可根據代碼自行理解感受,
經典案例2 仿淘寶固定右側側邊欄

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .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>
        //1. 獲取元素
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        // banner.offestTop 就是被卷去頭部的大小 一定要寫到滾動的外面
        var bannerTop = banner.offsetTop
            // 當我們側邊欄固定定位之后應該變化的數值
        var sliderbarTop = sliderbar.offsetTop - bannerTop;
        // 獲取main 主體元素
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');
        var mainTop = main.offsetTop;
        // 2. 頁面滾動事件 scroll
        document.addEventListener('scroll', function() {
            // console.log(11);
            // window.pageYOffset 頁面被卷去的頭部
            // console.log(window.pageYOffset);
            // 3 .當我們頁面被卷去的頭部大于等于了 172 此時 側邊欄就要改為固定定位
            if (window.pageYOffset >= bannerTop) {
                sliderbar.style.position = 'fixed';
                sliderbar.style.top = sliderbarTop + 'px';
            } else {
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px';
            }
            // 4. 當我們頁面滾動到main盒子,就顯示 goback模塊
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block';
            } else {
                goBack.style.display = 'none';
            }

        })
    </script>
</body>

</html>

三大系列總結在這里插入圖片描述

.offset系列經常用于獲得元素位置offsetLeft offsetTop
.client 經常用于獲取元素大小clientWidth clientHeight
scroll 經常用于獲取滾動距離scrollTop scrollLeft
注意頁面滾動的距離通過window.pageXOffset 獲得

擴展:mouseover和mouseenter的區別

當滑鼠移動到元素上時就會觸發mouseenter 事件
類似mouseover,它們兩者之間的差別是
mouseover 滑鼠經過自身盒子會觸發,經過子盒子還會觸發,
mouseenter 只會經過自身盒子觸發
之所以這樣,就是因為mouseenter不會冒泡
跟mouseenter搭配滑鼠離開mouseleave 同樣不會冒泡

    <div class="father">
        <div class="son"></div>
    </div>
    <script>
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        son.addEventListener('mouseleave', function() {
            console.log(11);

        })
    </script>

感興趣可以自行驗證,比如把mouseleave分別換成mouseenter和mouseover 或者把son換成father 測驗最終的效果

立即執行函式

    <script>
        // 1.立即執行函式: 不需要呼叫,立馬能夠自己執行的函式
        function fn() {
            console.log(1);

        }
        fn();
        // 2. 寫法 也可以傳遞引數進來
        // 1.(function() {})()    或者  2. (function(){}());
        (function(a, b) {
            console.log(a + b);
            var num = 10;
        })(1, 2); // 第二個小括號可以看做是呼叫函式
        (function sum(a, b) {
            console.log(a + b);
            var num = 10; // 區域變數
        }(2, 3));
        // 3. 立即執行函式最大的作用就是 獨立創建了一個作用域, 里面所有的變數都是區域變數 不會有命名沖突的情況
    </script>

影片函式

核心原理:通過定時器setInterval() 不斷移動盒子位置,
實作步驟:1. 獲得盒子當前位置
2. 讓盒子在當前位置加上1個移動距離
3. 利用定時器不斷重復這個操作
4. 加一個結束定時器的條件
5. 注意此元素需要添加定位,才能使用element.style.left

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        
        span {
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: purple;
        }
    </style>
</head>

<body>
    <button>點擊夏雨荷才走</button>
    <div></div>
    <span>夏雨荷</span>
    <script>
        // var obj = {};
        // obj.name = 'andy';
        // 簡單影片函式封裝obj目標物件 target 目標位置
        // 給不同的元素指定了不同的定時器
        function animate(obj, target) {
            // 當我們不斷的點擊按鈕,這個元素的速度會越來越快,因為開啟了太多的定時器
            // 解決方案就是 讓我們元素只有一個定時器執行
            // 先清除以前的定時器,只保留當前的一個定時器執行
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                if (obj.offsetLeft >= target) {
                    // 停止影片 本質是停止定時器
                    clearInterval(obj.timer);
                }
                obj.style.left = obj.offsetLeft + 1 + 'px';

            }, 30);
        }

        var div = document.querySelector('div');
        var span = document.querySelector('span');
        var btn = document.querySelector('button');
        // 呼叫函式
        animate(div, 300);
        btn.addEventListener('click', function() {
            animate(span, 200);
        })
    </script>
</body>

</html>

緩動影片

我們根據上一個案例進行封裝和調整,核心目標就是設定步長

    <script>
        // 緩動影片函式封裝obj目標物件 target 目標位置
        // 思路:
        // 1. 讓盒子每次移動的距離慢慢變小, 速度就會慢慢落下來,
        // 2. 核心演算法:(目標值 - 現在的位置) / 10 做為每次移動的距離 步長
        // 3. 停止的條件是: 讓當前盒子位置等于目標位置就停止定時器
        function animate(obj, target, callback) {
            // console.log(callback);  callback = function() {}  呼叫的時候 callback()

            // 先清除以前的定時器,只保留當前的一個定時器執行
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                // 步長值寫到定時器的里面
                // 把我們步長值改為整數 不要出現小數的問題
                // var step = Math.ceil((target - obj.offsetLeft) / 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 這個步長值改為一個慢慢變小的值  步長公式:(目標值 - 現在的位置) / 10
                obj.style.left = obj.offsetLeft + step + 'px';

            }, 15);
        }
        var span = document.querySelector('span');
        var btn500 = document.querySelector('.btn500');
        var btn800 = document.querySelector('.btn800');

        btn500.addEventListener('click', function() {
            // 呼叫函式
            animate(span, 500);
        })
        btn800.addEventListener('click', function() {
                // 呼叫函式
                animate(span, 800, function() {
                    // alert('你好嗎');
                    span.style.backgroundColor = 'red';
                });
            })
            // 勻速影片 就是 盒子是當前的位置 +  固定的值 10 
            // 緩動影片就是  盒子當前的位置 + 變化的值(目標值 - 現在的位置) / 10)
    </script>

影片函式是一個非常重要的知識點,在不使用框架的情況下,影片函式能解決頁面中大部分的動態效果圖案,
經典案例三 利用animate影片函式(效果自行嘗試)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .sliderbar {
            position: fixed;
            right: 0;
            bottom: 100px;
            width: 40px;
            height: 40px;
            text-align: center;
            line-height: 40px;
            cursor: pointer;
            color: #fff;
        }
        
        .con {
            position: absolute;
            left: 0;
            top: 0;
            width: 200px;
            height: 40px;
            background-color: purple;
            z-index: -1;
        }
    </style>
    <script src="animate.js"></script>
</head>

<body>
    <div class="sliderbar">
        <span></span>
        <div class="con">問題反饋</div>
    </div>

    <script>
        // 1. 獲取元素
        var sliderbar = document.querySelector('.sliderbar');
        var con = document.querySelector('.con');
        // 當我們滑鼠經過 sliderbar 就會讓 con這個盒子滑動到左側
        // 當我們滑鼠離開 sliderbar 就會讓 con這個盒子滑動到右側
        sliderbar.addEventListener('mouseenter', function() {
            // animate(obj, target, callback);
            animate(con, -160, function() {
                // 當我們影片執行完畢,就把 ← 改為 →
                sliderbar.children[0].innerHTML = '→';
            });

        })
        sliderbar.addEventListener('mouseleave', function() {
            // animate(obj, target, callback);
            animate(con, 0, function() {
                sliderbar.children[0].innerHTML = '←';
            });

        })
    </script>
</body>

</html>

輪播圖

輪播圖也稱為焦點圖,是網頁中比較常見的網頁特效,
功能需求:
1.滑鼠經過輪播圖模塊,左右按鈕顯示,離開隱藏左右按鈕,
2.點擊右側按鈕一次,圖片往左播放一張,以此類推,左側按鈕同理,
3.圖片播放的同時,下面小圓圈模塊跟隨一起變化,
4.點擊小圓圈,可以播放相應圖片,
5.滑鼠不經過輪播圖,輪播圖也會自動播放圖片,
6.滑鼠經過,輪播圖模塊,自動播放停止,

    // 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);
    });

①動態生成小圓圈
②核心思路:小圓圈的個數要跟圖片張數一致
③所以首先先得到ul里面圖片的張數(圖片放入li里面,所以就是li的個數)
④利用回圈動態生成小圓圈(這個小圓圈要放入ol里面)
⑤創建節點createElement(‘li’)
⑥插入節點ol.appendChild(li)
⑦第一個小圓圈需要添加current 類
①小圓圈的排他思想
②點擊當前小圓圈,就添加current類
③其余的小圓圈就移除這個current類

  // 3. 動態生成小圓圈  有幾張圖片,我就生成幾個小圓圈
    var ul = focus.querySelector('ul');
    var ol = focus.querySelector('.circle');
    // console.log(ul.children.length);
    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 就要把這個li 的索引號給 num  
            num = index;
            // 當我們點擊了某個小li 就要把這個li 的索引號給 circle  
            circle = index;
            // num = circle = index;
            console.log(focusWidth);
            console.log(index);

            animate(ul, -index * focusWidth);
        })
    }

①點擊小圓圈滾動圖片
②此時用到animate影片函式,將js檔案引入(注意,因為index.js 依賴animate.js 所以,animate.js 要寫到index.js 上面)
③使用影片函式的前提,該元素必須有定位
④注意是ul 移動而不是小li
⑤滾動圖片的核心演算法:點擊某個小圓圈,就讓圖片滾動小圓圈的索引號乘以圖片的寬度做為ul移動距離
⑥此時需要知道小圓圈的索引號,我們可以在生成小圓圈的時候,給它設定一個自定義屬性,點擊的時候獲取這個自定義屬性即可,
①點擊右側按鈕一次,就讓圖片滾動一張,
②宣告一個變數num,點擊一次,自增1,讓這個變數乘以圖片寬度,就是ul 的滾動距離,
③圖片無縫滾動原理
④把ul 第一個li 復制一份,放到ul 的最后面
⑤當圖片滾動到克隆的最后一張圖片時,讓ul 快速的、不做影片的跳到最左側:left 為0
⑥同時num 賦值為0,可以從新開始滾動圖片了

    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();
        }
    });

    // 9. 左側按鈕做法
    arrow_l.addEventListener('click', function() {
        if (flag) {
            flag = false;
            if (num == 0) {
                num = ul.children.length - 1;
                ul.style.left = -num * focusWidth + 'px';

            }
            num--;
            animate(ul, -num * focusWidth, function() {
                flag = true;
            });
            // 點擊左側按鈕,小圓圈跟隨一起變化 可以再宣告一個變數控制小圓圈的播放
            circle--;
            // 如果circle < 0  說明第一張圖片,則小圓圈要改為第4個小圓圈(3)
            // if (circle < 0) {
            //     circle = ol.children.length - 1;
            // }
            circle = circle < 0 ? ol.children.length - 1 : circle;
            // 呼叫函式
            circleChange();
        }
    });

①克隆第一張圖片
②克隆ul 第一個li cloneNode() 加true 深克隆復制里面的子節點false 淺克隆
③添加到ul 最后面appendChild
①點擊右側按鈕,小圓圈跟隨變化
②最簡單的做法是再宣告一個變數circle,每次點擊自增1,注意,左側按鈕也需要這個變數,因此要宣告全域變數,
③但是圖片有5張,我們小圓圈只有4個少一個,必須加一個判斷條件
④如果circle == 4 就從新復原為0

    // 把ol里面的第一個小li設定類名為 current
    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.click()
⑤滑鼠經過focus 就停止定時器
⑥滑鼠離開focus 就開啟定時器

    function circleChange() {
        // 先清除其余小圓圈的current類名
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        // 留下當前的小圓圈的current類名
        ol.children[circle].className = 'current';
    }
    // 10. 自動播放輪播圖
    var timer = setInterval(function() {
        //手動呼叫點擊事件
        arrow_r.click();
    }, 2000);

防止輪播圖按鈕連續點擊造成播放過快,
節流閥目的:當上一個函式影片內容執行完畢,再去執行下一個函式影片,讓事件無法連續觸發,
核心實作思路:利用回呼函式,添加一個變數來控制,鎖住函式和解鎖函式,開始設定一個變數var flag = true;If(flag) {flag = false; do something}
關閉水龍頭利用回呼函式影片執行完畢,flag = true 打開水龍頭

主要HTML代碼如下

            <div class="focus fl">
                <!-- 左側按鈕 -->
                <a href="javascript:;" class="arrow-l">
                    &lt;
                 </a>
                <!-- 右側按鈕 -->
                <a href="javascript:;" class="arrow-r"> ? </a>
                <!-- 核心的滾動區域 -->
                <ul>
                    <li>
                        <a href="#"><img src="upload/focus.jpg" alt=""></a>
                    </li>
                    <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>
                </ul>
                <!-- 小圓圈 -->
                <ol class="circle">

                </ol>
            </div>

animate影片函式JS如下

function animate(obj, target, callback) {
    // console.log(callback);  callback = function() {}  呼叫的時候 callback()

    // 先清除以前的定時器,只保留當前的一個定時器執行
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        // 步長值寫到定時器的里面
        // 把我們步長值改為整數 不要出現小數的問題
        // var step = Math.ceil((target - obj.offsetLeft) / 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();
            // }
            callback && callback();
        }
        // 把每次加1 這個步長值改為一個慢慢變小的值  步長公式:(目標值 - 現在的位置) / 10
        obj.style.left = obj.offsetLeft + step + 'px';

    }, 15);
}

完整代碼如下,親測可用,需要自己調整一些引數和類名

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');
    // console.log(ul.children.length);
    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 就要把這個li 的索引號給 num  
            num = index;
            // 當我們點擊了某個小li 就要把這個li 的索引號給 circle  
            circle = index;
            // num = circle = index;
            console.log(focusWidth);
            console.log(index);

            animate(ul, -index * focusWidth);
        })
    }
    // 把ol里面的第一個小li設定類名為 current
    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();
        }
    });

    // 9. 左側按鈕做法
    arrow_l.addEventListener('click', function() {
        if (flag) {
            flag = false;
            if (num == 0) {
                num = ul.children.length - 1;
                ul.style.left = -num * focusWidth + 'px';

            }
            num--;
            animate(ul, -num * focusWidth, function() {
                flag = true;
            });
            // 點擊左側按鈕,小圓圈跟隨一起變化 可以再宣告一個變數控制小圓圈的播放
            circle--;
            // 如果circle < 0  說明第一張圖片,則小圓圈要改為第4個小圓圈(3)
            // 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 = '';
        }
        // 留下當前的小圓圈的current類名
        ol.children[circle].className = 'current';
    }
    // 10. 自動播放輪播圖
    var timer = setInterval(function() {
        //手動呼叫點擊事件
        arrow_r.click();
    }, 2000);

})

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/345779.html

標籤:其他

上一篇:JavaScript的運算子

下一篇:《微信小程式》音樂播放器專案

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more