JavaScript案例:轮播图

八、轮播图案例

8.1轮播图-静态页面

轮播图又称焦点图,是网页中较为常见的网页特效。

  • 页面布局:

 

1679385017800

  • 静态页面实现:

①编写静态页面后,要让图片浮动,置于同一行。

②若出现图片未一行的情况,是ul不够长,导致未能装下其中li的一个个小图片,只需将ul的宽度设置为400%,即外围大盒子的4倍即可。

html代码
    <div class="focus">
        <!-- 左侧按钮箭头 -->
        <a href="#" class="prev"> &lt; </a>
        <!-- 右侧按钮箭头 -->
        <a href="#" class="next"> &gt; </a>
         <!-- 滚动图片区域 -->
        <ul class="focus">
            <li>
                <a><img src="./img/01.png" alt=""></a>
            </li>
            <li>
                <a><img src="./img/02.png" alt=""></a>
            </li>
            <li>
                <a><img src="./img/03.png" alt=""></a>
            </li>
            <li>
                <a><img src="./img/03.png" alt=""></a>
            </li>
        </ul>
        <!-- 小圆点 -->
        <ul class="circle">
            <li class="current"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
css代码:
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        li {
            list-style: none;
        }
 
        .focus {
            position: relative;
            width: 520px;
            height: 280px;
            background-color: pink;
            margin: 100px auto;
        }
        .focus ul{
            /* 设置ul宽度为focus的4倍,使其可以装下多个浮动的li */
            width: 400%;
        }
        .focus img {
            width: 520px;
            height: 280px;
        }
 
        /* 并集选择器可以集体声明相同的样式 */
        .prev,
        .next {
            position: absolute;
            /* 绝对定位的盒子垂直居中 */
            top: 50%;
            margin-top: -15px;
            /* 加了绝对定位的盒子可以直接设置高度和宽度 */
            width: 20px;
            height: 30px;
            background: rgba(0, 0, 0, .3);
            text-align: center;
            line-height: 30px;
            color: #fff;
            text-decoration: none;
        }
 
        .prev {
            left: 0;
            /* border-radius: 15px; */
            border-top-right-radius: 15px;
            border-bottom-right-radius: 15px;
        }
 
        .next {
            /* 如果一个盒子既有left属性也有right属性,则默认会执行 left属性 同理  top  bottom  会执行 top */
            right: 0;
            /* border-radius: 15px; */
            border-top-left-radius: 15px;
            border-bottom-left-radius: 15px;
        }
        .focus ul li{
            float: left;
        }
        .circle {
            position: absolute;
            bottom: 15px;
            left: 50%;
            margin-left: -35px;
            width: 70px;
            height: 13px;
            /* background-color: pink; */
            background: rgba(255,255,255, .3);
            border-radius: 7px;
        }
        .circle li {
            float: left;
            width: 8px;
            height: 8px;
            background-color: #fff;
            border-radius: 50%;
            margin: 3px;
        }
        /* 不要忘记选择器权重的问题 */
       .circle .current {
            background-color: #ff5000;
        }
    </style>
8.2轮播图-js动态页面

1679741169313

(1)功能点:

①鼠标经过轮播图区域,出现← →

鼠标离开轮播图区域,隐藏← →

  • 先将↔按钮设为不可见

  • 利用mosouenter和mouseleave绑定鼠标事件即可

②点击左右按钮,图片可切换

③播放图片时,底部小圆圈相应变化选中状态

④点击小圆圈,可切换对应轮播图片

⑤鼠标离开,轮播图会自动播放

鼠标点击,轮播图会停止自动播放

(2)要求:

此时js代码较多,因单独新建js文件,引入页面中

添加load事件,防止页面元素未加载完全找不到元素

1️⃣左右箭头出现

利用mouseenter和mouseleave两事件

实现鼠标经过箭头显示,鼠标离开箭头消失

2️⃣动态生成小圆圈

圆圈个数和图片数一致

先得到ul中图片张数(即li的个数)

利用循环动态生成小圆圈(放入ol中)

  • 创建节点 createElement('li')
  • 插入节点 ol.appendChild('li')
  • 绑定点击事件+排他思想
    • 可以创建节点的同时绑定事件哦!!

第一个小圆圈默认添加current类

  • 默认轮播开始的第一张

3️⃣引入动画js文件+添加定位

将动画函数写入单独js文件,引入js文件

  • 当其他js文件,需要使用动画函数js时,要将动画函数js放在其上方。

为移动区域ul,添加absolute绝对定位

  • 注意是ul在移动,而非li

  • 因为动画函数的使用,要求元素必须有定位

3️⃣实现点击圆圈图片滚动

滚动的核心算法:小圆圈索引号*图片的宽度=ul的移动距离

创建节点后,定义小圆圈的自定义属性

  • 定义自定义data-index属性

  • 使用setAttribute('属性名',属性值)

    • 属性名 data-index
    • 属性值 循环变量---i

在小圆圈的点击事件中,计算ul移动距离+调用动画函数

  • offsetWidth得到图片宽度

  • getAttribute得到圆圈下标属性

    • ❗:在事件函数中,最好用this

    • 否则取下标的时候出不来

  • 求ul移动距离:当前点击圆圈下标值*图片宽度

最后,调用动画函数。

4️⃣图片随着右侧按钮变化

先将ul的第一个li克隆,追加到ul最后

  • 克隆:element.clone(true);true表示深克隆,复制其中子节点
  • 追加:append(节点)

声明一个变量num,绑定点击事件

  • 声明 num =0;

每次点击,判断是否是最后一张

  • 是--》回到第一张
    • ul的left值为0,同时num清0
  • 否--》num++,调用动画函数
    • 调用:animate(移动对象,移动距离)
      • 移动距离:第几张图*图片宽度

当滚到最后一张时,让ul快速回到最左侧:left为0

同时重新赋值num=0

5️⃣小圆圈随右侧按钮变化

声明一个circle变量,每次点击右侧按钮时+1【注意声明全局变量】

判断circle是否等于ol中的children

  • 是,circle为0
  • 否,设置小圆圈为选中状态【排他思想】

❗:点击小圆圈到第三张图,点击下一张,小圆圈不匹配

  • 得到小圆圈索引值时,要将其赋给num和circle

6️⃣轮播图自动播放

先设置定时器setInterve

  • 将定时器命名为timer,方便之后清除

自动播放:相当于手动调用右侧按钮点击事件

  • element.click()相当于直接调用点击事件

鼠标经过focus,停止定时器

  • 在鼠标

鼠标离开focus,开启定时器

动画函数js
// obj目标对象,target目标位置
// 给不同的元素指定不同的定时器
function animate(obj, targt, callback) {
    // 当我们不断地点击按钮,元素的速度越来越快,因为开启了太多定时器
    // 解决方案,让元素只有一个定时器(清除上一个定时器,只保留当前的定时器)
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        // 步长值
        // 把步长值改为正直 ,向上取整
        var step = (targt - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == targt) {
            // 停止定时器
            clearInterval(obj.timer);
            // if (callback) {
            //     callback(); //回调函数
            // }
            callback && callback();
        }
        // 把每次+1这个步长值逐渐变小,步长公式  (目标位置值 - 现在的位置)/10 
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 15);
}
轮播图js(基于动画函数js)
window.addEventListener('load',function(){
    
    //1.获取元素
        // ①左按钮,右按钮
        var prev = this.document.querySelector('.prev');
        var next = this.document.querySelector('.next');
        // ②滑动区域
        var focus = this.document.querySelector('.focus');
        // ③小圆点
        var ol = this.document.querySelector('.circle');
        var ImgWidth = focus.offsetWidth;//图片宽度
        // ④图片选中位置
        var num = 0;//控制左右滑动
        // ⑤小圆圈选中位置  
        var circle = 0;//控制小圆圈的播放

    //2.鼠标经过再显示左右按钮
      focus.addEventListener('mouseenter',function(){
        prev.style.display = 'block';
        next.style.display = 'block';
        //停止定时器
        clearInterval(timer);
        //将定时器置null
        timer = null;
       })
    //3.鼠标离开隐藏左右按钮
      focus.addEventListener('mouseleave',function(){
        prev.style.display = 'none';
        next.style.display = 'none';
        //开启定时器,因为下方已经声明,所以只需要重新定义即可
        timer = setInterval(function(){
          //调用右侧点击事件
          next.click();
        },3000)
      })
    //4.动态生成小圆圈:图有几个,○就有几个
     var ul = focus.querySelector('ul');
      //获取图片张数 ul的li数量
      for(var i = 0;i < ul.children.length; i ++){
        //依次循环,创建li节点
        var li = document.createElement('li');
        //设置自定义属性
        li.setAttribute('data-index',i);
        //插入到ol中
        ol.appendChild(li);
        //生成圆圈的同时绑定事件
        li.addEventListener('click',function(){
           //干掉所有人
          for(var i = 0; i < ol.children.length; i++){
            //清除他人的类
            ol.children[i].className = '';
          }
          //留下自己
          this.className = 'current';
    //5.点击小圆圈,放图片的ul对应移动
        //得到图片宽度+自定义圆圈索引号
        // var ImgWidth = focus.offsetWidth;//图片宽度
         var index = this.getAttribute('data-index');//索引号
         num = index;
         circle = index;
         console.log('看看当前的图片宽度'+ImgWidth);
         console.log('看看索引号'+index);
         //求ul移动的距离:小圆圈下标*图片宽度
         var target = index*ImgWidth;
         //②调用动画函数
         animate(ul,-target);
         })
      }
      //默认设置第一个圆圈为选中
      ol.children[0].className = 'current';
    
      //6.克隆ul的第一个li,放到ul最后
      var first = ul.children[0].cloneNode(true);
      ul.appendChild(first);
    /*!!!!!!!!!!!!!右侧按钮事件!!!!!!!!!!!!!!!!!*/ 
      //7.点击右滑按钮,图片向右滚动一张
      // var num = 0;//控制左右滑动
      // var circle = 0;//控制小圆圈的播放
      next.addEventListener('click',function(){
         if(num == ul.children.length - 1 ){
           ul.style.left = 0;
           num = 0;
         }
        num++;
        animate(ul,-num*ImgWidth);
        //让小圆圈随之变化
        circle++;
        //保证滑到ol中克隆出来的最后一张图时,会跳转到第一张。
        if(circle == ol.children.length){
          circle = 0;
        }
        circleChange();
      })
     /*!!!!!!!!!点击左滑按钮,小圆圈随着一起变化!!!!!!!!!!!*/
          //8.左滑按钮的点击事件
          prev.addEventListener('click',function(){
             //如果滑到第一张,就跳到最后一张图片去
            if(num == 0 ){
              //跳到最后一张:left=ol的最后一个下标*图片宽度
              num = ol.children.length-1;
              ul.style.left =  - num * ImgWidth + 'px';
              
            }
           num--;
           animate(ul,-num*ImgWidth);
           //让小圆圈随之变化
           circle--;
           //如果circle<0,说明小圆圈要跳到ol的最后一个
           if(circle < 0 ){
             circle = ol.children.length-1;
           }
           circleChange();
         })
      //10.自动播放轮播图的定时器
       //在鼠标移动+鼠标离开时,添加相应步骤
      var timer = this.setInterval(function(){
         next.click();
      },1000)

//9.封装的圆圈选中变化函数
      function circleChange(){
         //清除其他小圆圈的current类名
         for(var i = 0; i < ol.children.length;i++){
          ol.children[i].className = '';
          }
       //留下当前小圆圈的current类名
       ol.children[circle].className = 'current';
      }

})

为防止轮播图切换过快,可以定义一个flag变量,初值为true

执行左/右点击事件后,当flag为true时,flag变为false,图片执行切换效果;而在动画函数的回调函数中,flag恢复为true。保证下一次切换效果。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓六日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值