JS练习

轮播图

自动切换图片轮播

<style>
    .container {
        text-align: center;
        margin: 0 auto;
    }
    .img {
        width: 500px;
        height: 300px;
    }
</style>
<div class="container">
    <img class="img">
    <div class="switch">
        <button class="click" onclick="switchImg(-1)">上一张</button>
        <button class="click" onclick="switchImg(1)">下一张</button>
        <button class="auto">自动切换</button>
    </div>
</div>
<script>
    console.log(document.querySelectorAll('.click'));
    const imgs = ['../static/img/city-1600*1600.png', '../static/img/风景-1920*1080.jpg', '../static/img/人物-1920*1080.png', '../static/img/city-400*400.png'];
    document.querySelector('.img').src = imgs[0];
    let size = imgs.length;
    let index = 0;
    function switchImg(step) {
        if (index + step < 0) {
            index = size - 1;
        } else if (index + step >= size) {
            index = 0;
        } else {
            index += step;
        }
        document.querySelector('.img').src = imgs[index];
    }
    let auto = false;
    let timer = null;
    document.querySelector('.auto').onclick = function () {
        if (auto) {
            this.innerHTML = '自动切换';
            clearInterval(timer);
        } else {
            this.innerHTML = '停止切换';
            timer = setInterval(() => {
                switchImg(1);
            }, 1000);
        }
        auto = !auto;
    }
</script>

img


轮播图片存在的问题

切换图片时重新设置图片src,导致图片重新加载网路图片,切换速度慢,因此需要先把所有图片加载到本地,再进行切换

使用定位层级原理实现轮播

<style>
    .container {
        text-align: center;
    }

    .img {
        width: 500px;
        height: 300px;
    }

    ul {
        height: 300px;
        width: 500px;
        padding-left: 0px;
        display: inline-block;
    }

    li {
        position: absolute;
        list-style: none;
        opacity: 0;

    }

    .show {
        z-index: 1;
        opacity: 1;
        transition: opacity 1s;
    }
</style>
<div class="container">
    <ul>
        <li class="show"><img class="img" src="../static/img/city-1600*1600.png" alt=""></li>
        <li><img class="img" src="../static/img/风景-1920*1080.jpg" alt=""></li>
        <li><img class="img" src="../static/img/人物-1920*1080.png" alt=""></li>
        <li><img class="img" src="../static/img/city-400*400.png" alt=""></li>
    </ul>
    <div class="switch">
        <button class="click" onclick="switchImg(-1)">上一张</button>
        <button class="click" onclick="switchImg(1)">下一张</button>
        <button class="auto">自动切换</button>
    </div>
</div>
<script>
    let lis = document.querySelectorAll('li');
    let size = lis.length;
    let index = 0;
    function switchImg(step) {
        lis[index].classList.toggle('show');
        if (index + step < 0) {
            index = size - 1;
        } else if (index + step >= size) {
            index = 0;
        } else {
            index += step;
        }
        lis[index].classList.toggle('show');
    }
    let auto = false;
    let timer = null;
    document.querySelector('.auto').onclick = function () {
        if (auto) {
            this.innerHTML = '自动切换';
            clearInterval(timer);
        } else {
            this.innerHTML = '停止切换';
            timer = setInterval(() => {
                switchImg(1);
            }, 1000);
        }
        auto = !auto;
    }
</script>

鼠标移动停止自动切换鼠标移出继续自动切换

并使用闭包封装定时器ID

<style>
    body {
        margin: 0;
    }

    .container {
        margin-top: 60px;
        text-align: center;
    }

    .banner {
        position: relative;
        width: 500px;
        height: 300px;
        margin: 0 auto;
    }

    .img {
        width: 500px;
        height: 300px;
    }

    ul {
        height: 300px;
        width: 500px;
        margin: 0;
        padding-left: 0px;
        position: absolute;
    }

    li {
        position: absolute;
        list-style: none;
        opacity: 0;
    }

    .show {
        z-index: 1;
        opacity: 1;
        transition: opacity 1s;
    }

    .pre {
        width: 30px;
        height: 300px;
        position: absolute;
        top: 0;
        left: 0;
        line-height: 300px;
        color: white;
        font-size: 40px;
        z-index: 2;
        opacity: .5;
        cursor: pointer;
        transition: opacity .3s;
    }

    .pre:hover {
        opacity: 1;
    }

    .next {
        width: 30px;
        height: 300px;
        position: absolute;
        top: 0;
        right: 0;
        line-height: 300px;
        color: white;
        font-size: 40px;
        z-index: 2;
        opacity: .5;
        cursor: pointer;
        transition: opacity .3s;
    }

    .next:hover {
        opacity: 1;
    }
</style>
<div class="container">
    <div class="banner">
        <div class="pre" onclick="switchImg(-1)">&lt;</div>
        <div class="next" onclick="switchImg(1)">&gt;</div>
        <ul>
            <li class="show"><img class="img" src="../static/img/city-1600*1600.png" alt=""></li>
            <li><img class="img" src="../static/img/风景-1920*1080.jpg" alt=""></li>
            <li><img class="img" src="../static/img/人物-1920*1080.png" alt=""></li>
            <li><img class="img" src="../static/img/city-400*400.png" alt=""></li>
        </ul>
    </div>
</div>
<script>
    let lis = document.querySelectorAll('li');
    let size = lis.length;
    let index = 0;
    function switchImg(step) {
        lis[index].classList.toggle('show');
        if (index + step < 0) {
            index = size - 1;
        } else if (index + step >= size) {
            index = 0;
        } else {
            index += step;
        }
        lis[index].classList.toggle('show');
    }
    let toggleAuto = (
        function () {
            let timer = null;
            return () => {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                } else {
                    timer = setTimeout(function autoSwitch() {
                        switchImg(1);
                        timer = setTimeout(autoSwitch, 1000);
                    }, 1000);
                }
            }
        }
    )();
    toggleAuto();
    document.querySelector('.banner').addEventListener('mouseenter', function () {
        toggleAuto();
    });
    document.querySelector('.banner').addEventListener('mouseleave', function () {
        toggleAuto();
    });
</script>

img


轮播图添加当前轮播图索引

<style>
    body {
        margin: 0;
    }

    .container {
        margin-top: 60px;
        text-align: center;
    }

    .banner {
        position: relative;
        width: 500px;
        height: 300px;
        margin: 0 auto;
    }

    .img {
        width: 500px;
        height: 300px;
    }

    ul {
        height: 300px;
        width: 500px;
        margin: 0;
        padding-left: 0px;
        position: absolute;
    }

    li {
        position: absolute;
        list-style: none;
        opacity: 0;
    }

    .show {
        z-index: 1;
        opacity: 1;
        transition: opacity 1s;
    }

    .pre {
        width: 30px;
        height: 300px;
        position: absolute;
        top: 0;
        left: 0;
        line-height: 300px;
        color: white;
        font-size: 40px;
        z-index: 2;
        opacity: .5;
        cursor: pointer;
        transition: opacity .3s;
    }

    .pre:hover {
        opacity: 1;
    }

    .next {
        width: 30px;
        height: 300px;
        position: absolute;
        top: 0;
        right: 0;
        line-height: 300px;
        color: white;
        font-size: 40px;
        z-index: 2;
        opacity: .5;
        cursor: pointer;
        transition: opacity .3s;
    }

    .next:hover {
        opacity: 1;
    }

    .dot {
        width: 500px;
        height: 20px;
        position: absolute;
        z-index: 3;
        bottom: 10px;
        text-align: center;
    }

    .dot-item {
        width: 20px;
        height: 20px;
        background-color: grey;
        border-radius: 50%;
        display: inline-block;
        font-size: 12px;
        line-height: 20px;
        opacity: 0.4;
        cursor: pointer;
    }

    .dot-item:hover {
        opacity: 1;
    }

    .dot-item-active {
        opacity: 1;
    }
</style>
<div class="container">
    <div class="banner">
        <div class="pre" onclick="switchImg(-1)">&lt;</div>
        <div class="next" onclick="switchImg(1)">&gt;</div>
        <ul>
            <li class="show"><img class="img" src="../static/img/1.jpg" alt=""></li>
            <li><img class="img" src="../static/img/2.jpeg" alt=""></li>
            <li><img class="img" src="../static/img/3.jpeg" alt=""></li>
            <li><img class="img" src="../static/img/4.jpg" alt=""></li>
        </ul>
        <div class="dot">
            <span class="dot-item" onclick="switchImg(0,0)">1</span>
            <span class="dot-item" onclick="switchImg(0,1)">2</span>
            <span class="dot-item" onclick="switchImg(0,2)">3</span>
            <span class="dot-item" onclick="switchImg(0,3)">4</span>
        </div>
    </div>
</div>
<script>
    let lis = document.querySelectorAll('li');
    let size = lis.length;
    let index = 0;
    function switchImg(step, showIndex) {
        lis[index].classList.remove('show');
        document.querySelectorAll('.dot-item')[index].classList.remove('dot-item-active');
        if (showIndex !== undefined) {
            index = showIndex;
        } else {
            if (index + step < 0) {
                index = size - 1;
            } else if (index + step >= size) {
                index = 0;
            } else {
                index += step;
            }
        }
        lis[index].classList.add('show');
        document.querySelectorAll('.dot-item')[index].classList.add('dot-item-active');
    }
    let toggleAuto = (
        function () {
            let timer = null;
            return () => {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                } else {
                    timer = setTimeout(function autoSwitch() {
                        switchImg(1);
                        timer = setTimeout(autoSwitch, 1000);
                    }, 1000);
                }
            }
        }
    )();
    toggleAuto();
    document.querySelector('.banner').addEventListener('mouseenter', function () {
        toggleAuto();
    });
    document.querySelector('.banner').addEventListener('mouseleave', function () {
        toggleAuto();
    });
</script>

img


贪吃蛇

1.每个蛇节点使用定位布局
2.蛇的移动方式: 把蛇尾节点位置移动到蛇头节点前面的位置,并把蛇尾节点放到蛇头节点位置
3.撞墙和撞自己:
(1)蛇头下一个位置是否超过了边界
(2)蛇头下一个位置是否和其他蛇节点有重合,除了蛇尾节点(因为蛇头下一步可能会移动到蛇尾节点位置)
4.在没有完成移动前,方向按键不可用

<style>
    body {
        margin: 0;
    }

    .container {
        margin: 0 auto;
        width: 340px;
        height: 400px;
        border: 10px solid black;
        border-radius: 5%;
        background-color: #b7d4a8;
    }

    .border {
        width: 300px;
        height: 300px;
        margin: 0 auto;
        margin-top: 15px;
        border: 2px solid black;
        position: relative;
    }

    .info {
        margin: 0 auto;
        margin-top: 30px;
        width: 300px;
        height: 50px;
        text-align: center;
        display: flex;
        justify-content: space-between;
        font-weight: bold;
    }

    .snake {
        position: absolute;
        left: 0;
        bottom: 0;
    }

    .food {
        width: 10px;
        height: 10px;
        background-color: red;
        position: absolute;
        margin: 1px;
    }

    .snake-node {
        position: absolute;
        width: 10px;
        height: 10px;
        margin: 1px;
        background-color: black;
        left: 0;
        bottom: 0;
    }
</style>
<div class="container">
    <div class="border">
        <div class="snake">
        </div>
        <div class="food"></div>
    </div>
    <div class="info">
        <div class="scoreInfo">
            SCORE:
            <span class="score">0</span>
        </div>
        <div class="levelInfo">
            LEVEL:
            <span class="score">1</span>
        </div>
    </div>
</div>
<script>
    let step = 12;
    let defaultLength = 7;
    let score = defaultLength;
    let moveDirection = 'right';
    let speed = 200;
    let gameOver = false;
    // true时可以控制方向,false时说明正在移动,不能重复设置方向
    let setDirection = true;
    let snakeNode = document.createElement('div');
    snakeNode.classList.add('snake-node');
    let snake = document.querySelector('.snake');
    let food = document.querySelector('.food');
    let scoreNode = document.querySelector('.score');
    scoreNode.innerHTML = score;
    food.style.left = Math.floor(Math.random() * 25) * step + 'px';
    food.style.bottom = Math.floor(Math.random() * 25) * step + 'px';
    for (let i = 0; i < defaultLength; i++) {
        let node = snakeNode.cloneNode();
        left = (defaultLength - 1 - i) * step;
        node.style.bottom = 0 + 'px';
        node.style.left = 0 + 'px';
        snake.appendChild(node);
    }
    function move() {
        if (hit()) {
            gameOver = true;
            alert('game over');
            return;
        }
        nodeMove();
        setDirection = true;
    }
    let toggleMove = (function () {
        let timer = null;
        return () => {
            if (timer === null) {
                timer = setTimeout(function autoMove() {
                    if (gameOver) {
                        clearTimeout(timer);
                        timer = null;
                        return;
                    }
                    move();
                    timer = setTimeout(autoMove, speed);
                }, speed)
            } else {
                clearTimeout(timer);
                timer = null;
            }
        }
    })();
    toggleMove();
    function nodeMove() {
        let { x, y } = headLeftAndBottom();
        if (parseInt(food.style.left) === x && parseInt(food.style.bottom) === y) {
            let last = snake.lastElementChild;
            snake.appendChild(last.cloneNode());
            food.style.left = Math.floor(Math.random() * 25) * step + 'px';
            food.style.bottom = Math.floor(Math.random() * 25) * step + 'px';
            score += 1;
            scoreNode.innerHTML = score;
        }
        // 把蛇尾移动到蛇头前面
        snake.lastElementChild.style.left = x + 'px';
        snake.lastElementChild.style.bottom = y + 'px';
        // 交换结构位置,始终让蛇头节点在元素的第一个位置
        snake.insertBefore(snake.lastElementChild, snake.firstElementChild);
    }
    function hit() {
        // 如果蛇头下个位置和每个节点进行位置比较,除了蛇尾节点,如果有重合说明会撞到自己
        let { x, y } = headLeftAndBottom();
        let nodes = [...snake.children];
        for (let index = 1; index < nodes.length - 1; index++) {
            let node = nodes[index];
            if (parseInt(node.style.left) === x && parseInt(node.style.bottom) === y) {
                return true;
            }
        }
        // 不能越过边界
        if (x < 0 || x >= 300 || y < 0 || y >= 300) {
            return true;
        }
    }
    document.onkeydown = function (e) {
        if (e.keyCode === 38 && moveDirection !== 'bottom' && setDirection) {
            moveDirection = 'top';
            setDirection = false;
        } if (e.keyCode === 40 && moveDirection !== 'top' && setDirection) {
            moveDirection = 'bottom';
            setDirection = false;
        }
        if (e.keyCode === 37 && moveDirection !== 'right' && setDirection) {
            moveDirection = 'left';
            setDirection = false;
        }
        if (e.keyCode === 39 && moveDirection !== 'left' && setDirection) {
            moveDirection = 'right';
            setDirection = false;
        }
    }
    function headLeftAndBottom() {
        let x = parseInt(snake.firstElementChild.style.left);
        let y = parseInt(snake.firstElementChild.style.bottom);
        if (moveDirection === 'right') {
            x += step;
        }
        if (moveDirection === 'bottom') {
            y -= step;
        }
        if (moveDirection === 'top') {
            y += step;
        }
        if (moveDirection === 'left') {
            x -= step;
        }
        return { x, y };
    }
</script>

img

posted @ 2025-05-20 17:33  ethanx3  阅读(13)  评论(0)    收藏  举报