前端基础学习之手写基础轮播图(pc端、移动端)

最近在看移动端开发知识点的时候,刚好看到移动端轮播图,想着不如和之前pc端的轮播图放在一起做个记录,再回顾一遍一些基础知识点。

  • 轮播图的几个基础功能点:
    • 自动无缝切换轮播图片
    • 点击按钮切换图片
    • 移动端手指滑动切换图片
    • 移动端手机滑动短距离图片吸附回去
    • 指示器随着图片滚动而改变
1.无缝轮播图(仅简单自动轮播,通过改变绝对定位left值来实现滚动的效果,无其他任何功能点)

在这里插入图片描述

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }
        img {
            vertical-align: top;
            width: 300px;
        }
        /*取消图片底部3像素距离*/
        .box {
            width: 300px;
            height: 200px;
            margin: 100px auto;
            background-color: pink;
            border: 1px solid red;
            position: relative;
            overflow: hidden;
        }

        .box ul li {
            float: left;
        }

        .box ul {
            width: 1500px;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
</head>
<body>
<div class="box" id="screen">
    <ul>
        <li><img src="imagess/01.jpg" alt=""/></li>
        <li><img src="imagess/02.jpg" alt=""/></li>
        <li><img src="imagess/03.jpg" alt=""/></li>
        <li><img src="imagess/04.jpg" alt=""/></li>
        <li><img src="imagess/01.jpg" alt=""/></li>
    </ul>
</div>

<script>
	//根据id获取元素对象
	function my$(id) {
	    return document.getElementById(id);
	}
	
    let current = 0;
    //移动函数
    function f1() {
        current -= 10;
        let ulObj = my$("screen").children[0];
        if (current < -1200) {
            ulObj.style.left = "0px";
            current = 0
        } else {
            ulObj.style.left = current + "px";
        }
    }

    //定时移动
    let timer = setInterval(f1, 50);
    my$("screen").onmouseover = function () {
        //鼠标移上图片停止滚动--即清除定时器
        clearInterval(timer);
    }
    my$("screen").onmouseout = function () {
        //鼠标移开图片开始滚动--即重新开启定时器
        timer = setInterval(f1, 50);
    }
</script>

</body>
</html>
2.焦点切换轮播图(仅简单点击按钮切换轮播的图片,封装了一个简单的动画函数,无其他任何功能点)

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        body, ul, ol, li, img {
            margin: 0;
            padding: 0;
            list-style: none;
        }

        #box {
            width: 520px;
            height: 280px;
            padding: 5px;
            position: relative;
            border: 1px solid #ccc;
            margin: 100px auto 0;
        }

        .ad {
            width: 520px;
            height: 280px;
            overflow: hidden;
            position: relative;
        }

        #box img {
            width: 520px;
        }

        .ad ol {
            position: absolute;
            right: 10px;
            bottom: 10px;
        }

        .ad ol li {
            width: 20px;
            height: 20px;
            line-height: 20px;
            border: 1px solid #ccc;
            text-align: center;
            background: #fff;
            float: left;
            margin-right: 10px;
            cursor: pointer;
            _display: inline;
        }

        .ad ol li.current {
            background: yellow;
        }

        .ad ul li {
            float: left;
        }

        .ad ul {
            position: absolute;
            top: 0;
            width: 2940px;
        }

        .ad ul li.current {
            display: block;
        }

        #focusD {
            display: none;
        }

        #focusD span {
            width: 40px;
            height: 40px;
            position: absolute;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            cursor: pointer;
            line-height: 40px;
            text-align: center;
            font-weight: bold;
            font-family: '黑体';
            font-size: 30px;
            color: #fff;
            opacity: 0.3;
            border: 1px solid #fff;
        }

        #focusD #right {
            right: 5px;
            left: auto;
        }
    </style>
</head>
<body>
<div id="box" class="all">
    <div class="ad">
        <ul id="imgs">
            <li><img src="images/01.jpg"/></li>
            <li><img src="images/02.jpg"/></li>
            <li><img src="images/03.jpg"/></li>
            <li><img src="images/04.jpg"/></li>
            <li><img src="images/05.jpg"/></li>
        </ul>
    </div><!--相框-->
    <div id="focusD"><span id="left">&lt;</span><span id="right">&gt;</span>
    </div>
</div>

<script>
	//根据id获取元素对象
	function my$(id) {
	    return document.getElementById(id);
	}
    //获取box
    let box = my$("box");
    //获取相框ad
    let ad = box.children[0];
    let width = ad.offsetWidth;
    let ulObj = ad.children[0];
    //获取ul对象

    //获取左右焦点的div
    let focusD = my$("focusD");

    //第一个鼠标移入box显示左右两个焦点按钮
    box.onmouseover = function () {
        focusD.style.display = "block";
    }
    box.onmouseout = function () {
        focusD.style.display = "none";
    }

    let count = 0;
    //点击左右两个焦点按钮移动相框
    my$("left").onclick = function () {
        if (count > 0) {
            count--;
            animate(ulObj, -count * width);
        }

    }

    my$("right").onclick = function () {
        //点击一次移动一次
        if (count < ulObj.children.length - 1) {
            count++;
            animate(ulObj, -count * width);
        }

    }

    //公共的任意对象移动指定位置
    function animate(element, target) {
        //清除一次
        clearInterval(element.timerId);
        //定时器开始
        element.timerId = setInterval(function () {
            //获取当前元素的left
            let current = element.offsetLeft;
            let step = 10;
            step = current < target ? step : -step;
            current += step;
            if (Math.abs(target - current) > Math.abs(step)) {
                element.style.left = current + "px";
            } else {
                clearInterval(element.timerId);
                element.style.left = target + "px";
            }
        }, 10)
    }
</script>

</body>
</html>
3.基础功能完整的轮播图(包含自动轮播,焦点切换图片,指示器切换图片,指示器随着图片变化而变化)

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
            list-style: none;
            border: 0;
        }

        .all {
            width: 500px;
            height: 200px;
            padding: 7px;
            border: 1px solid #ccc;
            margin: 100px auto;
            position: relative;
        }

        .screen {
            width: 500px;
            height: 200px;
            overflow: hidden;
            position: relative;
        }

        .screen li {
            width: 500px;
            height: 200px;
            overflow: hidden;
            float: left;
        }

        .screen ul {
            position: absolute;
            left: 0;
            top: 0px;
            width: 3000px;
        }

        .all ol {
            position: absolute;
            right: 10px;
            bottom: 10px;
            line-height: 20px;
            text-align: center;
        }

        .all ol li {
            float: left;
            width: 20px;
            height: 20px;
            background: #fff;
            border: 1px solid #ccc;
            margin-left: 10px;
            cursor: pointer;
        }

        .all ol li.current {
            background: #DB192A;
        }

        #arr {
            display: none;
        }

        #arr span {
            width: 40px;
            height: 40px;
            position: absolute;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            cursor: pointer;
            line-height: 40px;
            text-align: center;
            font-weight: bold;
            font-family: '黑体';
            font-size: 30px;
            color: #fff;
            opacity: 0.3;
            border: 1px solid #fff;
        }

        #arr #right {
            right: 5px;
            left: auto;
        }
    </style>
</head>
<body>
<div class="all" id='box'>
    <div class="screen"><!--相框-->
        <ul>
            <li><img src="images/1.jpg" width="500" height="200"/></li>
            <li><img src="images/2.jpg" width="500" height="200"/></li>
            <li><img src="images/3.jpg" width="500" height="200"/></li>
            <li><img src="images/4.jpg" width="500" height="200"/></li>
            <li><img src="images/5.jpg" width="500" height="200"/></li>
        </ul>
        <ol>
        </ol>
    </div>
    <div id="arr"><span id="left">&lt;</span><span id="right">&gt;</span></div>
</div>

<script>
	//根据id获取元素对象
	function my$(id) {
	    return document.getElementById(id);
	}
    //首先获取所有需要的元素
    //最外层的box对象
    let box = my$("box");
    //相册screen对象
    let screen = box.children[0];
    //相册宽度
    let imgWidth = screen.offsetWidth;
    //ul对象--移动的对象
    let ulObj = screen.children[0];
    //ul下面的li
    let list = ulObj.children;
    //ol对象
    let olObj = screen.children[1];
    //arr对象 控制鼠标移上显示鼠标移出隐藏
    let arrObj = my$("arr");

    //首先遍历大的图片li生成ol里面的按钮li ---先写最容易控制的右下角按钮点击显示对应图片
    for (let i = 0; i < list.length; i++) {
        //创建ol中的li元素并添加内容
        let liObj = document.createElement("li");
        liObj.innerHTML = (i + 1);
        olObj.appendChild(liObj);

        //为移动ul做准备,需要给每个li一个索引值
        liObj.setAttribute("index", i);
        //鼠标移上事件
        liObj.onmouseover = mouseoverHandle;

    }

    let imgIndex = 0;

    //鼠标移上右下角按钮的事件处理函数
    function mouseoverHandle() {
        //第一 鼠标移上显示红色背景
        //排它-取消所有ol下li的class
        for (let j = 0; j < olObj.children.length; j++) {
            olObj.children[j].removeAttribute("class");
        }
        //给当前元素设置背景class
        this.setAttribute("class", "current");

        //第二 鼠标移上移动显示到对应索引的图片
        imgIndex = this.getAttribute("index");
        animate(ulObj, -imgIndex * imgWidth);

    }

    //默认给第一个点击按钮设置背景色
    olObj.children[0].setAttribute("class", "current")
    //深拷贝第一张图片放在ul中的最后,变成原来的length+1 以备自动播放时无缝衔接
    ulObj.appendChild(list[0].cloneNode(true));
    //此时比原先的图片要多一张


    //自动播放效果在做完点击右侧按钮的事件之后再来写,
    //本质其实就是调用点击右侧的事件函数,定时跑这个函数
    let autoId = setInterval(clickRight, 1500);

    //鼠标移上box显示左右两个焦点按钮
    box.onmouseover = function () {
        //鼠标移上显示
        arrObj.style.display = "block";
        //清除定时器自动播放
        clearInterval(autoId);
    }

    box.onmouseout = function () {
        // 鼠标移开取消显示
        arrObj.style.display = "none";
        //开启自动播放定时器
        autoId = setInterval(clickRight, 2000);
    }

    //点击左按钮的事件
    my$("left").onclick = function () {
        // 写完右侧的再来写左侧
        if (imgIndex == 0) {
            ulObj.style.left = -(ulObj.children.length - 1) * imgWidth;
            imgIndex = ulObj.children.length - 1;
        }
        // 首先是切换图片 --需要和上面的鼠标移上右下侧按钮显示的一致,一次上面的index值需要公用
        //点击时索引+1
        imgIndex--;
        animate(ulObj, -imgIndex * imgWidth);

        //这个时候测试会发现在使用右击按钮滚动图片时,右下角的按钮背景没有随之改变,因此这里也需要做处理
        //直接做排它
        for (let j = 0; j < olObj.children.length; j++) {
            olObj.children[j].removeAttribute("class");
        }
        //设置当前索引的颜色
        olObj.children[imgIndex].setAttribute("class", "current");
    }
    //点击右按钮的事件
    my$("right").onclick = clickRight;

    function clickRight() {
        //因为此时的最后一张图片 和第一张是同一张,需要做处理,在索引值到最后一个时,立马设置为第一张的索引,并跳回第一张
        if (imgIndex == ulObj.children.length - 1) {
            ulObj.style.left = 0;
            imgIndex = 0;
        }
        // 首先是切换图片 --需要和上面的鼠标移上右下侧按钮显示的一致,一次上面的index值需要公用
        //点击时索引+1
        imgIndex++;
        animate(ulObj, -imgIndex * imgWidth);

        //这个时候测试会发现在使用右击按钮滚动图片时,右下角的按钮背景没有随之改变,因此这里也需要做处理
        if (imgIndex == ulObj.children.length - 1) {
            //最后一张的特殊性做判断
            //即在显示最后一张图片时,右下角的标识应该显示第一个背景颜色
            olObj.children[0].setAttribute("class", "current");
            //同时取消最后的颜色
            olObj.children[olObj.children.length - 1].removeAttribute("class");
        } else {
            //设置当前索引的颜色
            olObj.children[imgIndex].setAttribute("class", "current");
            //取消上一个的颜色
            olObj.children[imgIndex].previousElementSibling.removeAttribute("class");
        }

    }

    //复习公共方法--给任意元素移动到指定目标位置
    function animate(element, target) {
        clearInterval(element.timerId);
        element.timerId = setInterval(function () {
            //首先获取当前元素的left值
            let current = element.offsetLeft;
            //设置步数,判断当前值和目标值的大小,区分正负,即从左向右走,还是从右向左走
            let step = 20;
            step = current < target ? step : -step;
            current += step;
            if (Math.abs(target - current) > Math.abs(step)) {
                element.style.left = current + "px";
            } else {
                clearInterval(element.timerId);
                element.style.left = target + "px";
            }
        }, 10)

    }
</script>
</body>
</html>

4.移动端轮播图(仿的老jd页面,包含自动轮播,手指滑动切换图片,指示器随着图片变化而变化,用过渡动画,不用自己手写动画)
  • 轮播图的实现:
    • 1.自动轮播 需要定时器+过渡效果
    • 2.底部圆点随着图片轮播时发生改变 需要根据索引做切换
    • 3.滑动效果 需要触摸事件
    • 4.滑动结束时 如果滑动的距离小于屏幕的1/2 吸附回去 过渡
    • 5.滑动结束时 如果滑动的距离大于屏幕的1/2 切换图片(上一张/下一张) 根据滑动的方向决定 过渡效果

在这里插入图片描述

    <div class="jd_banner">
        <ul>
            <!--无缝衔接-->
            <li><a href="#"><img src="images/l8.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l1.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l2.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l3.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l4.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l5.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l6.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l7.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l8.jpg" alt=""></a></li>
            <li><a href="#"><img src="images/l1.jpg" alt=""></a></li>
        </ul>
        <ul>
            <li class="now"><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
            <li><a href=""></a></li>
        </ul>
    </div>
//面向对象 构造函数的方式
let bannerScroll = function () {
    let Banner = function (bannerObj) {
        this.bannerBox = bannerObj || document.querySelector(".jd_banner");
        this.bannerWidth = this.bannerBox.offsetWidth;
        this.imageBox = this.bannerBox.querySelector("ul:first-child");
        this.pointBox = this.bannerBox.querySelector("ul:last-child");
        this.points = this.pointBox.querySelectorAll("li");
        this.index = 1;
    }
    Banner.prototype.init = function () {
        this.autoScroll();
        this.touchScroll();
    };
    //1.自动滚动
    Banner.prototype.autoScroll = function () {
        let _this = this;
        //定时器
        this.timer = setInterval(function () {
            _this.index++;
            _this.addTransition();
            _this.setTranslateX((-_this.index) * _this.bannerWidth);
        }, 2000);
        _this.imageBox.addEventListener("transitionend", function () {
            if (_this.index >= 9) {
                _this.index = 1;
                _this.removeTransition();
                _this.setTranslateX((-_this.index) * _this.bannerWidth);
            } else if (_this.index <= 0) {
                _this.index = 8;
                _this.removeTransition();
                _this.setTranslateX((-_this.index) * _this.bannerWidth);
            }
            //小圆点同步
            _this.syncPoints();
        });


    };
    //2.小圆点同步
    Banner.prototype.syncPoints = function () {
        for (let i = 0; i < this.points.length; i++) {
            this.points[i].classList.remove("now");
        }
        this.points[this.index - 1].classList.add("now");
    };
    //3.手指滑动事件
    Banner.prototype.touchScroll = function () {
        this.bannerBox.addEventListener("touchstart", evt => {
            console.log("start");
            clearInterval(this.timer);
            this.moveX0 = evt.targetTouches[0].clientX;
        });
        this.bannerBox.addEventListener("touchmove", evt => {
            console.log("move");
            this.moveFlag = true;
            let moveX1 = evt.targetTouches[0].clientX;
            this.moveWidth = moveX1 - this.moveX0;
            this.removeTransition();
            this.setTranslateX((-this.index) * this.bannerWidth + this.moveWidth);
        });
        this.bannerBox.addEventListener("touchend", evt => {
            console.log("end");
            if (this.moveFlag) {
                if (Math.abs(this.moveWidth) <= this.bannerWidth / 2) {
                    this.addTransition();
                    this.setTranslateX((-this.index) * this.bannerWidth);
                } else {
                    this.moveWidth > 0 ? this.index-- : this.index++;
                    this.addTransition();
                    this.setTranslateX((-this.index) * this.bannerWidth);
                }
            }
            this.moveX0 = 0;
            this.moveWidth = 0;
            let _this = this;
            this.timer = setInterval(function () {
                _this.index++;
                _this.addTransition();
                _this.setTranslateX((-_this.index) * _this.bannerWidth);
            }, 2000)
        });
    };
    //添加过渡
    Banner.prototype.addTransition = function () {
        this.imageBox.style.transition = "all 0.3s";
        this.imageBox.style.webkitTransition = "all 0.3s";
    };
    //取消过渡
    Banner.prototype.removeTransition = function () {
        this.imageBox.style.transition = "none";
        this.imageBox.style.webkitTransition = "none";
    };
    //位移
    Banner.prototype.setTranslateX = function (width) {
        this.imageBox.style.transform = "translateX(" + width + "px)";
        this.imageBox.style.webkitTransform = "translateX(" + width + "px)";
    };

    let banner = new Banner();
    banner.init();
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值