原生写一个渐隐渐显版的轮播图

轮播图是项目中非常常见的一个效果,平时我们可能都会用别人写好的插件,但是必要的时候也需要自己手写,尤其是需要掌握下其中的实现原理。 一、需求 1.实现渐隐渐显自动轮播效果 2.鼠标移入:显示左右切换箭头,停止自动轮播 3.鼠标离开:隐藏左右切换箭头,继续自动轮播 4.点击左右箭头实现上下切换图片 5.点击分页器跳转相应图片 二、代码实现 HTML 结构中我们需要: 轮播图容器container 图片容器wrapper 分页器容器pagination 左右按钮容器 CSS 接下来调整样式 .container { position: relative; margin: 50px auto; width: 800px; height: 400px; overflow: hidden; } .container .wrapper { position: relative; width: 100%; height: 100%; } .container .wrapper .slider { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 0; opacity: 0; transition: all .3s; } /* 默认显示第一张图片 */ .container .wrapper .slider:nth-child(1) { opacity: 1; z-index: 1; } .container .wrapper .slider img { width: 100%; height: 100%; } /* 分页器 */ .pagination { position: absolute; z-index: 999; bottom: 10px; left: 50%; transform: translateX(-50%); padding: 5px 10px; font-size: 0; border-radius: 26px; } .pagination li { display: inline-block; margin: 0 5px; width: 10px; height: 10px; border-radius: 50%; background: #fff; cursor: pointer; } .pagination li.active { background: red; } /* 左右按钮 */ .arrow { display: none; position: absolute; z-index: 999; top: 50%; margin-top: -22.5px; width: 30px; height: 45px; background: url(../images/pre.png) no-repeat 0 0; } .arrow.changeLeft { left: 0; } .arrow.changeRight { right: 0; background-position: -50px 0; } .container:hover .arrow { display: block; } 需要强调的一点:这里左右切换按钮是以背景图片的方式插入的 JS交互 在做需求之前,我们需要先把即将要操作的元素都获取到; // 获取需要操作的元素 //最外层轮播图容器 let container = document.querySelector('.container'), //包裹所有图片的容器 wrapper = container.querySelector('.wrapper'), // 所有图片的集合 sliderList = wrapper.querySelectorAll('.slider'), // 分页器容器 pagination = container.querySelector('.pagination'), // 每一个分页器的li标签集合 paginationList = pagination.querySelectorAll('li'), // 左侧按钮 changeLeft = container.querySelector('.changeLeft'), // 右侧按钮 changeRight = container.querySelector('.changeRight'); 元素都获取完了我们就来按照需求一步一步的进行; 需求一:实现渐隐渐显自动轮播效果 思路分析 渐隐渐显效果:改变相应图片的z-index和opacity两个属性即可 想让哪张图片显示,就让哪张图片的z-index和opacity为1; 同时让其他图片的z-index和opacity为0即可; 自动轮播效果:利用定时器 代码实现 // 需要用到定时器,设置定时器和切换时间初始值 let autoTimer = null, interval = 3000, prev = 0, step = 0; // 因为在后面还会用到,所以这里对切换的效果做了一个函数封装 //切换函数封装 let change = function change() { // 让上一张不显示 sliderList[prev].style.zIndex = '0'; sliderList[prev].style.opacity = '0'; // 让当前张过渡显示 sliderList[step].style.zIndex = '1'; sliderList[step].style.opacity = '1'; sliderList[step].style.transition = 'opacity .5s'; //这里是在分页器函数写完加的,小伙伴们要注意一下; // 自动切换的同时让焦点自动对齐 focus(); } // 实现自动切换 let autoMove = function autoMove() { // prev保存上一张的索引 prev = step; // step代表即将显示的这一张 step++; // 如果step大于图片时,让step重新为0 step >= sliderList.length ? step = 0 : null; // 执行切换 change(); }; //利用定时器完成自动切换 autoTimer = setInterval(autoMove, interval); 此时我们打开浏览器可以看到,已经能够实现渐隐渐显的效果了 这时候会发现一个明显的问题: 分页器不会跟着图片动态变化 接下来实现分页器和图片对应 // 分页器自动对焦 let focus = function focus() { [].forEach.call(paginationList, (item, index) => { step === index ? item.className = 'active' : item.className = ''; }) }; 函数写出来了,那在哪里执行呢? 我们要让图片切换的时候,分页器跟随图片一起运动,所以图片切换在哪,分页器就在哪执行; 所以是在切换函数中执行的,就是在change函数中的最后。 需求二:鼠标划上停止自动播放/离开恢复 思路分析: 鼠标划上: 左右箭头显示,这一步我们在CSS中已经实现 自动播放停止: 我们之前用定时器完成的自动播放; 所以鼠标划上时,我们清除定时器即可; 鼠标离开: 恢复播放:重新开启定时器即可 代码实现 // 鼠标经过停止自动轮播 container.onmouseenter = function () { clearInterval(autoTimer); autoTimer = null; } // 鼠标离开后开始自动轮播 container.onmouseleave = function () { autoTimer = setInterval(autoMove, interval); } 需求三:点击左右箭头实现上下切换图片 思路分析 右箭头:与我们现在自动播放的方向一致,所以只需要执行一次我们上面封装的图片切换函数即可; 左箭头:与原本的切换方向相反,所以,我们把图片切换调转一下即可 代码实现 // 点击右按钮切换下一张 changeRight.onclick = autoMove; // 点击左按钮切换上一张 changeLeft.onclick = function () { prev = step; step--; step < 0 ? (step = sliderList.length - 1) : null; change(); } 需求四:点击分页器跳转相应图片 思路分析 给每一个li标签绑定点击事件,点击某项时,找到与点击的这一项索引相同的图片的索引,让其展示即可 代码实现 [].forEach.call(paginationList, (item, index) => { item.onclick = function () { // 如果点击的这一项正好是当前展示的这张图片则不做处理 if (step === index) return; prev = step; step = index; change(); } }) 好了,现在我们所有需求都满足了,整合下代码即可 JS完整实现代码 let swipter = (function () { // 获取需要操作的元素 let container = document.querySelector('.container'), wrapper = container.querySelector('.wrapper'), sliderList = wrapper.querySelectorAll('.slider'), pagination = container.querySelector('.pagination'), paginationList = pagination.querySelectorAll('li'), changeLeft = container.querySelector('.changeLeft'), changeRight = container.querySelector('.changeRight'); // 需要用到定时器,设置定时器和切换时间初始值 let autoTimer = null, interval = 3000, prev = 0, step = 0; //切换函数封装 let change = function change() { // 让上一张不显示 sliderList[prev].style.zIndex = '0'; sliderList[prev].style.opacity = '0'; // 让当前张过渡显示 sliderList[step].style.zIndex = '1'; sliderList[step].style.opacity = '1'; sliderList[step].style.transition = 'opacity 2s'; // 自动切换的同时让焦点自动对其 focus(); } // 实现自动切换 let autoMove = function autoMove() { // prev保存上一张的索引 prev = step; // step代表即将显示的这一张 step++; // 如果step大于图片时,让step重新为0 step >= sliderList.length ? step = 0 : null; // 执行切换 change(); }; //利用定时器完成自动切换 autoTimer = setInterval(autoMove, interval); // 分页器自动对焦 let focus = function focus() { [].forEach.call(paginationList, (item, index) => { step === index ? item.className = 'active' : item.className = ''; }) }; // 鼠标经过停止自动轮播 container.onmouseenter = function () { clearInterval(autoTimer); autoTimer = null; } // 鼠标离开后开始自动轮播 container.onmouseleave = function () { autoTimer = setInterval(autoMove, interval); } // 鼠标点击分页器跳转相应图片 let clickFocus = function autoFocus() { [].forEach.call(paginationList, (item, index) => { item.onclick = function () { if (step === index) return; prev = step; step = index; change(); } }) } // 点击右按钮切换下一张 changeRight.onclick = autoMove; // 点击左按钮切换上一张 changeLeft.onclick = function () { prev = step; step--; step < 0 ? (step = sliderList.length - 1) : null; change(); } return { init() { clickFocus(); } } })(); swipter.init(); 虽然实现了功能,但是当我们频繁点击的时候还会有一些问题,所以需要做下节流或者防抖的优化,在这里就暂时不做赘述了,后面补充。  

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):