赞
踩
目的:用于自己做记录,记录制作的过程以及遇到的一些问题。内容参考来自b站的up主:黑马前端 的pink老师JavaScript基础语法课程。
(1)当鼠标经过轮播图,左右两边的按钮出现,离开则隐藏按钮;
(2)点击左侧按钮,图片向右播放一张,以此类推,右侧同理;
(3)图片播放的同时,下面的小圆圈也会随之变化;
(4)点击小圆圈,可以播放相应的图片;
(5)鼠标不经过轮播图,轮播图会自动播放图片
html代码
- <!DOCTYPE html>
- <html lang="zh-CN">
-
- <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>
- <link rel="stylesheet" href="css/index.css">
- <!-- animate要写在上面,因为是index.js使用 -->
- <script src="js/animate.js"></script>
- <script src="js/index.js"></script>
- </head>
-
- <body>
- <div class="focus">
- <!-- 滚动图 -->
- <ul class="images">
- <li><a href="#"><img src="images/focus.jpg" alt=""></a></li>
- <li><a href="#"><img src="images/focus1.jpg" alt=""></a></li>
- <li><a href="#"><img src="images/focus2.jpg" alt=""></a></li>
- <li><a href="#"><img src="images/focus3.jpg" alt=""></a></li>
- </ul>
- <!-- 小于 -->
- <a href="#">
- <sapn class="left"><</sapn>
- </a>
- <!-- 大于 -->
- <a href="#">
- <sapn class="right">></sapn>
- </a>
- <!-- 小圆圈 -->
- <ol class="circle">
- </ol>
- </div>
- </body>
-
- </html>
css代码
- * {
- margin: 0;
- padding: 0;
- }
-
- ul,
- ol {
- /* 去点 */
- list-style: none;
- }
-
- .focus {
- position: relative;
- width: 721px;
- height: 455px;
- overflow: hidden;
- }
-
- .focus ul {
- /* 添加定位使用动画效果 */
- position: absolute;
- top: 0;
- left: 0;
- width: 600%;
- }
-
- .focus ul li {
- /* 需要给ul足够的宽度才能让其左浮动 */
- float: left;
- }
-
- .focus .left,
- .right {
- display: none;
- position: absolute;
- top: 216px;
- left: 0;
- width: 27px;
- height: 20px;
- background-color: black;
- opacity: 0.5;
- text-align: center;
- line-height: 20px;
- color: #fff;
- }
-
- .focus .right {
- left: 694px;
- }
-
- .circle {
- position: absolute;
- top: 420px;
- left: 20%;
- }
-
- .circle li {
- float: left;
- width: 10px;
- height: 10px;
- border: 1px solid #fff;
- border-radius: 10px;
- margin-left: 3px;
- }
-
- .current {
- background-color: #fff;
- }
思路:获取焦点图和左右两个按钮元素,运用mouseenter和mouseleave实现该功能
- // 获取元素
- var focus = document.querySelector('.focus');
- var left = document.querySelector('.left');
- var right = document.querySelector('.right');
- // 1.(1)当鼠标经过时,左右按钮出现
- focus.addEventListener('mouseenter', function () {
- left.style.display = 'block';
- right.style.display = 'block';
- })
- // 1.(2)当鼠标离开时,左右按钮消失
- focus.addEventListener('mouseleave', function () {
- left.style.display = 'none';
- right.style.display = 'none';
- })
思路:由于小圆圈的个数由图片决定,所以我们应该先获得图片的个数,然后利用for循环动态生成小圆圈,生成的小圆圈需要放在ol里面,此时则需要生成节点(createElement),再插入节点(appendChild)
(1)怎么得到图片的个数?要得到图片的个数,说先需要获取存放图片的ul和存放小圆圈的ol元素,然后通过ul.children.length得到图片数量
(2)如何动态生成小圆圈?通过for循环遍历,在循环里先创建小圆圈li元素,将li追加到ol中;同时先将第一个小圆圈添加样式
- // 2.动态生成小圆圈
- // 2.1获取元素
- // 注意要限制是focus的,因为文档中可能存在很多ul和ol
- var ul = focus.querySelector('.images');
- var ol = focus.querySelector('.circle');
- // console.log(ul.children.length);//输出4,为图片张数
- // 2.2动态生成小圆圈
- for (var i = 0; i < ul.children.length; i++) {
- // 创建小圆点li元素
- var li = this.document.createElement('li');
- // 将li插入到ol中
- ol.appendChild(li);
- }
- // 2.3把ol里面的第一个li设置类名current
- ol.children[0].className = 'current';
思路:运用排他思想(点击谁,谁就添加样式current类,其他则移除current类),因为要添加事件,所以应该先给小圆圈li绑定点击事件
- // 3.小圆圈的排他思想,在生成小圆圈的同时直接绑定点击事件
- li.addEventListener('click', function () {
- // 3.1清除所有li
- for (var i = 0; i < ol.children.length; i++) {
- ol.children[i].className = '';
- }
- // 3.2给当前点击的li添加类 this指向函数调用者(li)
- this.className = 'current';
- })
思路:图片的滑动要用到动画效果,先将封装好的动画函数(animate.js)引入进来
animate.js
- function animate(obj, target, callback) {
- clearInterval(obj.timer);
- obj.timer = setInterval(function () {
- var step = (target - obj.offsetLeft) / 10;
- step = step > 0 ? Math.ceil((target - obj.offsetLeft) / 10) : Math.floor(step);
- if (obj.offsetLeft == target) {
- clearInterval(obj.timer);
- if (callback) {
- callback();
- }
- }
- obj.style.left = obj.offsetLeft + step + 'px';
- }, 15);
- }
要使用动画效果需要添加定位,此处是ul要使用动画效果,因此要给ul添加定位。然后需要确定每次点击小圆圈ul需要走多少距离能够实现切换。同时因为是按下小圆圈移动,所以移动应写在小圆圈点击事件里面
(1)如何确定按下小圆点ul需要走多远的距离?通过小圆点的索引号×图片的宽度(比如索引号为0时,假设图片宽度为100,0×100=0,位于第一张)
(2)如何得到小圆圈的索引号?通过自定义属性index,然后将当前i的值复制给index(li.setAttribute('index', i);)
- // 4.点击小圆圈,移动图片
- // animate(obj, target, callback)
- // target:移动距离,索引号×图片宽度,注意是负值,因为此时是往左走
- // 当我们点击了某个小li,就拿到了当前li的索引号
- var index = this.getAttribute('index');
- console.log(index);
- var focusWidth = focus.offsetWidth;
- console.log(focusWidth);
- animate(ul, -index * focusWidth);
思路:定义一个num变量,点击一次自增1,然后用num*图片宽度,就是滚动的距离。此时可以实现点击按钮图片滚动,但点击到最后一张时再次点击会出现背景而不是回到第一张,如图:
于是我们实现图片无缝滚动:在html代码中将第一张图复制一份放在最后,利用if进行判断,当图片滚动到最后一张图(复制的那张)时,让ul的left值改为0,同时num赋值为0,这样当再次点击时则会出现第二张图
- // 5.点击右侧按钮,图片滚动一张
- var num = 0;//全局变量
- right.addEventListener('click', function () {
- // alert(11);//测试事件是否绑定
- // 如果走到了最后复制的一张,此时我们的ul要快速复原left改为0,实现无缝滚动
- if (num == ul.children.length - 1) {
- ul.style.left = 0;
- num = 0;
- }
- num++;
- animate(ul, -num * focusWidth);
- })
但是这样设置以后会出现问题:首先下面的小圆圈会变成5个,同时采用手动复制的方式相当有局限性。因此我们可以在js中直接克隆第一张图片,利用cloneNode(),加true为深克隆,会复制里面的子节点,false为浅克隆,克隆后的添加到ul最后面(appendChild)
- // 克隆第一张图片(li)放到ul最后面 写在小圆圈的后面,所以小圆圈不会多
- var first = ul.children[0].cloneNode(true);
- ul.appendChild(first);
思路:定义一个新的全局变量circle,每次自增一,运用排他思想,给circle所在的小圆圈添加current类,其他移除current类。同时由于最后一张图片是克隆的,所以要给circle添加一个判断条件,当circle等于小圆圈的总个数时,说明走到最后一张了,此时给circle赋值0
- // 6.点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
- 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';
同时,要将小圆圈与按钮建立联系,否则会出现点击了某一个小圆圈,再点击按钮播放下一张却播放图片与小圆圈对不上号的现象。
- // 当我们点击了某个小圆圈,就要把li的索引号给num
- num = index;
- // 当我们点击了某个小圆圈,就要把li的索
- circle = index;
思路:当num等于0时,位于第一张图片,此时点击左侧按钮,应该移动到克隆的前一张,同时图片是快速的移动到第三张所以应该为负值
- // 7.左侧按钮
- left.addEventListener('click', function () {
- if (num == 0) {
- num = ul.children.length - 1;
- ul.style.left = -num * focusWidth + 'px';
- }
- num--;//注意是--,反向的
- animate(ul, -num * focusWidth);
- circle--;
- // 如果circle<0,说明第一张图片,则小圆圈要改为第四个小圆圈
- if (circle < 0) {
- circle = ol.children.length - 1;
- }
- // 清除其余小圆圈的current类名
- for (var i = 0; i < ol.children.length; i++) {
- ol.children[i].className = '';
- }
- // 留下当前的小圆圈current类
- ol.children[circle].className = 'current';
- });
思路:自动播放,则用到定时器;其中自动播放功能类似于我们点击右侧按钮,因此我们可以手动调用右侧按钮的点击事件;当鼠标经过时,停止自动播放,在鼠标经过事件中停止定时器,在鼠标离开事件中使用定时器
- // 8.自动播放功能
- var timer = setInterval(function () {
- // 手动调用事件
- right.click();
- }, 2000);
- focus.addEventListener('mouseenter', function () {
- left.style.display = 'block';
- right.style.display = 'block';
- clearInterval(timer);
- timer = null;//清除定时器
- })
- focus.addEventListener('mouseleave', function () {
- left.style.display = 'none';
- right.style.display = 'none';
- timer = setInterval(function () {
- // 手动调用事件
- right.click();
- }, 1000);
- })
思路:节流阀是当上一个函数动画内容执行完毕后,再去执行下一个函数动画,让事件无法连续触发。利用回调函数,添加一个变量,利用变量来锁住和解锁函数
- // flag 节流阀
- var flag = true;
- right.addEventListener('click', function () {
- if (flag) {
- flag = false;//关闭节流阀
- // alert(11);//测试事件是否绑定
- // 如果走到了最后复制的一张,此时我们的ul要快速复原left改为0,实现无缝滚动
- if (num == ul.children.length - 1) {
- ul.style.left = 0;
- num = 0;
- }
- num++;
- animate(ul, -num * focusWidth, function () {
- flag = true;//打开节流阀
- });
- // 6.点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
- circle++;
- // 如果circle==4,说明走到克隆图片了
- if (circle == ol.children.length) {
- circle = 0;
- }
- //调用函数
- circleChange();
- }
- });
最后的效果图就不放了,因为太大了放不上来。
所有js的代码
- // 因为js是写在外部的,所以需要添加load事件:页面全部加载完之后再执行js
- window.addEventListener('load', function () {
- // 获取元素
- var focus = document.querySelector('.focus');
- var left = document.querySelector('.left');
- var right = document.querySelector('.right');
- var focusWidth = focus.offsetWidth;
- // 1.(1)当鼠标经过时,左右按钮出现
- focus.addEventListener('mouseenter', function () {
- left.style.display = 'block';
- right.style.display = 'block';
- clearInterval(timer);
- timer = null;//清除定时器
- })
- // 1.(2)当鼠标离开时,左右按钮消失
- focus.addEventListener('mouseleave', function () {
- left.style.display = 'none';
- right.style.display = 'none';
- timer = setInterval(function () {
- // 手动调用事件
- right.click();
- }, 1000);
- })
- // 2.动态生成小圆圈
- // 2.1获取元素
- // 注意要限制是focus的,因为文档中可能存在很多ul和ol
- var ul = focus.querySelector('.images');
- var ol = focus.querySelector('.circle');
- // console.log(ul.children.length);//输出4,为图片张数
- // 2.2动态生成小圆圈
- for (var i = 0; i < ul.children.length; i++) {
- // 创建小圆点li元素
- var li = this.document.createElement('li');
- // 记录当前小圆圈的索引号,通过自定义属性来做
- li.setAttribute('index', i);
- // 将li插入到ol中
- ol.appendChild(li);
- // 3.小圆圈的排他思想,在生成小圆圈的同时直接绑定点击事件
- li.addEventListener('click', function () {
- // 3.1清除所有li
- for (var i = 0; i < ol.children.length; i++) {
- ol.children[i].className = '';
- }
- // 3.2给当前点击的li添加类 this指向函数调用者(li)
- this.className = 'current';
- // 4.点击小圆圈,移动图片
- // animate(obj, target, callback)
- // target:移动距离,索引号×图片宽度,注意是负值,因为此时是往左走
- // 当我们点击了某个小li,就拿到了当前li的索引号
- var index = this.getAttribute('index');
- // 当我们点击了某个小圆圈,就要把li的索引号给num
- num = index;
- // 当我们点击了某个小圆圈,就要把li的索
- circle = index;
- console.log(index);
- // var focusWidth = focus.offsetWidth;//由于下面要使用,所以应该把它作为全局变量,放在外面
- console.log(focusWidth);
- animate(ul, -index * focusWidth);
- })
- }
- // 2.3把ol里面的第一个li设置类名current
- ol.children[0].className = 'current';
- // 克隆第一张图片(li)放到ul最后面 写在小圆圈的后面,所以小圆圈不会多
- var first = ul.children[0].cloneNode(true);
- ul.appendChild(first);
- // 5.点击右侧按钮,图片滚动一张
- var num = 0;//全局变量
- var circle = 0;
- // flag 节流阀
- var flag = true;
- right.addEventListener('click', function () {
- if (flag) {
- flag = false;//关闭节流阀
- // alert(11);//测试事件是否绑定
- // 如果走到了最后复制的一张,此时我们的ul要快速复原left改为0,实现无缝滚动
- if (num == ul.children.length - 1) {
- ul.style.left = 0;
- num = 0;
- }
- num++;
- animate(ul, -num * focusWidth, function () {
- flag = true;//打开节流阀
- });
- // 6.点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
- circle++;
- // 如果circle==4,说明走到克隆图片了
- if (circle == ol.children.length) {
- circle = 0;
- }
- //调用函数
- circleChange();
- }
- });
- // 7.左侧按钮
- left.addEventListener('click', function () {
- if (flag) {
- flag = false;
- if (num == 0) {
- num = ul.children.length - 1;
- ul.style.left = -num * focusWidth + 'px';
- }
- num--;//注意是--,反向的
- animate(ul, -num * focusWidth, function () {
- flag = true;
- });
- circle--;
- // 如果circle<0,说明第一张图片,则小圆圈要改为第四个小圆圈
- // if (circle < 0) {
- // circle = ol.children.length - 1;
- // }改为三元表达式更简洁
- circle = circle < 0 ? ol.children.length - 1 : circle;
- circleChange();
- }
- });
- function circleChange() {
- // 清除其余小圆圈的current类名
- for (var i = 0; i < ol.children.length; i++) {
- ol.children[i].className = '';
- }
- // 留下当前的小圆圈current类
- ol.children[circle].className = 'current';
- }
- // 8.自动播放功能
- var timer = setInterval(function () {
- // 手动调用事件
- right.click();
- }, 2000);
- })
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。