前端如何利用BFC特性实现一个简易的循环轮播图效果?(CV查看效果)

100 阅读1分钟
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<style>
    body {
        margin: 0;
        padding: 0;
        outline: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100vw;
        height: 100vh;
    }

    #main {
        display: flex;
        width: 608px;
        height: 380px;
        overflow: hidden;
    }

    #main img {
        width: 608px;
        height: 380px;
    }
</style>

<body>
    <div id="main">
        <!-- 图片素材 -->
        <img id="img-1" src="轮播图/1.jpg" alt="">
        <img id="img-2" src="轮播图/2.jpg" alt="">
        <img id="img-3" src="轮播图/3.jpg" alt="">
        <img id="img-4" src="轮播图/4.jpg" alt="">
    </div>
</body>
<script>
    let main = document.getElementById('main');

    //保存图片节点以复用提高性能
    let imgs = [];

    for (let i = 0; i < 4; i++) {
        imgs.push(document.getElementById(`img-${i+1}`));
    }

    //轮播效果
    let swiper = async function (img, timeout) {
        for (let i = 4; i <= 608; i += 4) {

            //浏览器会对宏任务的dom操作一次性集中优化故需要使用promise微任务来处理时延,此处Promise搭配setimeout
            //setTimeout有效最小时延是4ms
            await new Promise(resolve => setTimeout(resolve, 4)).then(() => {
                img.style = `margin-left:${-i}px`
            })
        }

        //重置样式
        img.style = "";

        //循环轮播
        main.appendChild(main.removeChild(img));
    }

    //开启轮播效果,接受一个参数x为轮播间隔 x毫秒
    let start = async (gap = 1000) => {

        let begin = 0,
            end = 4;
        while (1) {
            await new Promise(resolve => setTimeout(resolve, gap)).then(() => {
                swiper(imgs[begin]);
                begin++;
            })
            if (begin == end) begin = 0;
        }
    }
    start(3000);
</script>

</html>