原生js实现轮播图,思路(伪详解)

原生js轮播图效果

  • 简单的一个原生js轮播图效果,欢迎大佬指点江山,如果有萌新不懂的地方欢迎私信;

结构部分

  • 准备好一个简单的HTML结构部分,记住图片一定要用 ulli 来包裹,因为我们所做的轮播图是用 ul 的移动来实现的轮播效果,所以也别忘记给 ul加上 定位 position,一般我们都是用 绝对定位(至少我是用的绝对定位,不知道其他大佬是怎么做的)
  • 写代码的时候可能会因为 ul 父盒子的宽度不够,不能够使 li 设置了 浮动 float 也无法在一行内显示,这时我们只要将 ul 的宽度尽量设置的大一些就好。

//focus是ul的父盒子
.focus ul {
position: absolute;
left: 0;
padding: 0;
margin: 0;
list-style: none;
width: 800%;
}
.focus ul li {
width: 590px;
float: left;
}
.focus ul li img {
width: 100%;
}

js部分

鼠标移入移出
  • 如果不想要做这部分的话可以直接跳过,对最后的图片轮播效果实现并没有太大的影响。

  • 这部分也比较简单,我们只需要添加 onmouseenteronmouseleave 事件就可以了,设置左右箭头的display 属性。

  • 鼠标移入时

focus.addEventListener('mouseenter', function () {
        arrow_l.style.display = 'block';
        arrow_r.style.display = 'block';
    });
  • 鼠标移出时
focus.addEventListener('mouseleave', function () {
        arrow_l.style.display = 'none';
        arrow_r.style.display = 'none';
    });
图片左下角小圆点
创建小圆点
  • 因为可能不知道会有多少张图片,所以我们最好的方法是通过 for 循环来动态来创建小圆点
for (var i = 0; i < ul.children.length; i++) 
var li = document.createElement('li');
  • 添加到 ol 里面

ol.appendChild(li);

  • 同时在创建 li 的同时添加一个自定义属性,点击小圆点时,获取自定义属性来移动图片

li.setAttribute(‘index’, i);

点击小圆点
  • 我们在创建小圆点的同时可以同时给 li 添加绑定事件,每次点击时我们给当前的 li 添加我们写好的类名 current 或者直接修改背景颜色,其他的 li 使用 排他思想 修改类名或者修改背景颜色。
for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            // 留下我自己  当前的小li 设置current 类名
            this.className = 'current';
图片移动
  • 我们点击 li 时同获取当前的 li 的自定义属性

var index = this.getAttribute(‘index’);

  • 然后调用之前封装好的一个动画函数 animate (动画函数请往下看)

animate(ul, -index * focusWidth); //focusWidth = focus.offsetWidth;

  • 这样坐下角的小圆点的创建和点击事件基本上就做完了
图片无缝滚动的原理
  • 图片之所以会无缝滚动,是因为我们看到的最后一张图片实际上我们克隆的第一张图片,放到最后;到我们克隆的图片,我们下一次点击时 ulleft 值将会等于0,然后在继续往后滚动,由于我们设置了溢出隐藏,所以 ulleft 值等于0时,我们的肉眼并不能发现直观的变化,所以就形成了无缝滚动。
//克隆第一张图片(li)放到ul 最后面
   var first = ul.children[0].cloneNode(true);
   ul.appendChild(first);
按钮的点击
右按钮的点击
  • 我们先准备一个全局变量 num (名字随意),之后也会用来同步左下角小圆点的状态
  • 给右按钮添加点击事件,每次点击时 num 自加;
  • 并且如果 num 的值大于 图片长度的索引号时,让 num 等于0,并且让 ulleft 值等于0;这样图片就会再次回到第一张
  • 然后我们通过动画函数移动 ul
if (num == ul.children.length - 1) {
                ul.style.left = 0;
                num = 0;
            }
            num++;
            animate(ul, -num * focusWidth)
            });
  • 然后我们又准备一个全局变量 circle 点击时,左下角的小圆点也会跟着一起移动
			circle++;
            // 如果circle =4 说明走到最后我们克隆的这张图片了 我们就复原
            if (circle == ol.children.length) {
                circle = 0;
            }
            // 先清除其余小圆圈的current类名
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        // 留下当前的小圆圈的current类名
        ol.children[circle].className = 'current';
左按钮的点击与右按钮相似
自动轮播部分
  • 自动轮播部分我们只需要设置一个循环定时器,每隔几秒钟调用我们右按钮的点击事件便可实现自动轮播

var timer = setInterval(function () {
//手动调用点击事件
arrow_r.click();
}, 2000);

  • 鼠标移入时,清除定时器;鼠标移出时,就重新启动定时器;
  • 鼠标移入
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);
 });
点击按钮与小圆点同步
  • 我们点击右按钮时虽然小圆点可以同步添加类名,但是如果点击小圆点移动图片后在次点击按钮,小圆点的激活顺序就会与我们想象的不同,这时我们只需要把 li 的自定义属性赋值给全局变量 num 和 全局变量 circle 就可以解决这个问题;

num = circle = index;

动画函数
  • 我们通过改变元素的 left 属性来移动元素
  • 使用循环定时器可以不停移动元素
  • 当条件满足时,就清除定时器;
//obj 是我们要移动的那个元素,target 移动的位置,callback 回调函数
function animate(obj, target, callback) {
	//每次调用这个函数时我们先清除定时器,防止速度过快
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
    //手动设置一个缓动效果
        var step = (target - obj.offsetLeft) / 10;
        //如果小于0就向下取整,大于0就向上取整
        step = step < 0 ? Math.floor(step) : Math.ceil(step);
        if (obj.offsetLeft == target) {
            clearInterval(obj.timer);
            timer = null;
            //逻辑与的短路运算
            callback && callback();
        }
        obj.style.left = obj.offsetLeft + step + 'px'
    }, 15)
}

代码链接

下面是我写的代码链接
代码链接

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值