金色小芝麻

vuePress-theme-reco 金色小芝麻    2021 - 2023
金色小芝麻 金色小芝麻

Choose mode

  • dark
  • auto
  • light
主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
author-avatar

金色小芝麻

83

文章

27

标签

主页
分类
  • JavaScript
  • BUG复盘
  • SVG笔记
  • TypeScript
  • 个人总结
  • CSS笔记
  • 开发工具
  • 前端入门
  • Vue2.0
  • 性能优化
  • 架构学习
  • 每日一题
标签
时间轴
社交
  • 掘金 (opens new window)
  • 前端入门

    • 博客搭建过程及相关配置
    • 数组中的16种常用方法
    • JS中的数据类型简析——基本数据类型值
    • JS中的数据类型object基础
    • JS中三种常见的判断
    • 数据类型之间的区别(堆内存Heap VS 栈内存Stack)
    • JS基础练习题及解析
    • 开关灯的小案例
    • JS中数据类型检测方法——typeof
    • 条件判断几个小练习
    • JS循环——for循环
    • 自定义属性实现选项卡小案例
    • 字符串中的12种常用方法
    • DOM操作的简单原理
    • JS实现隔行变色鼠标跟随小案例
    • JS中function的基础知识
    • JS中数组去重的三种方法
    • JS中时间格式化的三种方法
    • JS中URL参数处理的三种方法
    • JS小案例——获取随机验证码
    • DOM操作之——获取DOM标签的9种方式
    • DOM操作之——DOM节点类型及属性
    • DOM操作之——元素的增删改、样式修改、插入内容
    • JS中THIS相关问题梳理
    • JS中的变量提升机制
    • 在全局:私有上下文中:带VAR和不带VAR的区别
    • 作用域和作用域链查找机制
    • JS中堆栈内存的释放问题
    • JS中的闭包机制
    • ES3和ES6定义变量的区别
    • JS中的单例和工厂设计模式
    • JS中的面向对象OOP理论基础
    • 构造函数创建自定义类
    • JS中的原型和原型链
    • Math中常用的9种方法
    • 从一道阿里经典面试题剖析函数三种角色
    • 重写内置call
    • 重写一个内置new
    • 浏览器渲染页面的主体流程
    • 减少DOM的回流和重绘
    • JS中的多种继承方式
    • JS中数据类型检测四种方式的优缺点
    • JS中的正则表达式&&全面梳理
    • 非严格模式 🆚 严格模式的区别
    • 数组方法reduce、filter、flat
    • 获取数组中最大值/最小值的三种基础方法
    • 轮播图——渐隐渐显版
    • 深克隆 VS 浅克隆|深比较 VS 浅比较|回调函数
    • 轮播图——左右切换版
    • 事件及事件绑定、事件对象及事件传播
    • 从在地址栏输入网址到看到页面的过程&&AJAX基础
    • 想自学JS吗?想提升JS底层原理吗?76张脑图带你彻底搞懂原生JS
    • 面试手写API系列
    • 30张脑图带你从零开始学VUE
    • JS中的盒子模型
    • 初识JS-基础中的基础
    • 前端发展简史
    • JS中的三大类输出方式

轮播图——渐隐渐显版

vuePress-theme-reco 金色小芝麻    2021 - 2023

轮播图——渐隐渐显版

金色小芝麻 2020-06-25

今天我们自己手写一个渐隐渐显版的轮播图,先上效果图👇

img

由于文件太大,只能压缩成这样给大家看了😓

既然不能传大文件,那大家就委屈一下先听听小芝麻描述一下具体的需求吧😄

# 一、需求

❝

1、实现渐隐渐显自动轮播效果;

❞

就如上面效果图一样;

❝

2、鼠标划上:

  • 显示左右切换箭头
  • 停止自动轮播;

❞

如图:此时小芝麻鼠标在图上,所以显示左右箭头,并且不再自动轮播 img

❝

3、鼠标离开:

  • 隐藏左右切换箭头
  • 继续自动轮播;

❞

与👆效果图一致

❝

4、点击左右箭头实现上下切换图片

❞

如图: img

❝

5、点击分页器跳转相应图片

❞

如图:小芝麻点击了第三个分页器,娜美就出来了😄

img

好了现在需求已经提完了,开始我们表演的时候到了

img

# 二、代码实现

# HTML

结构中我们需要:

  • 图片容器
    • 这里小芝麻放了6张图片着实有点多,但看见哪一张都舍不得删😭所以看着有些乱;
    • 小伙伴们可根据自己的需求调整
  • 分页器容器
  • 左右按钮容器

即可

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>金色小芝麻—渐隐渐显版轮播图-原生</title>
    <!-- IMPORT CSS -->
    <link rel="stylesheet" href="css/index.css">
</head>

<body>
    <!-- 轮播图容器 -->
    <div class="container">
        <!-- WRAPPER存放所有的图 -->
        <div class="wrapper">
            <!-- SLIDER每一个轮播图 -->
            <div class="slider">
                <img src="images/banner1.jpg" alt="">
            </div>
            <div class="slider">
                <img src="images/banner2.jpg" alt="">
            </div>
            <div class="slider">
                <img src="images/banner3.jpeg" alt="">
            </div>
            <div class="slider">
                <img src="images/banner4.jpeg" alt="">
            </div>
            <div class="slider">
                <img src="images/banner5.jpeg" alt="">
            </div>
            <div class="slider">
                <img src="images/banner6.jpg" alt="">
            </div>
        </div>

        <!-- PAGENATION分页器 -->
        <ul class="pagination">
            <li class="active"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>

        <!-- 左右按钮 -->
        <a href="javascript:;" class="arrow changeLeft"></a>
        <a href="javascript:;" class="arrow changeRight"></a>
    </div>

    <!-- IMPORT JS -->
    <script src="js/index.js"></script>
</body>

</html>

现在是这样的: img 接下来我们开始调整样式

# 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;
}

左右切换按钮,小芝麻是以背景图的方式插入的,这里提供给大家

img

现在我们来预览下效果

img

已经成型,接下来我们继续实现交互即可

# 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 = '';
    })
};

函数写出来了,那在哪里执行呢?

我们要让图片切换的时候,分页器跟随图片一起运动,所以图片切换在哪,分页器就在哪执行;

所以是在切换函数中执行的,就是如图这里: img

现在我们打开浏览器看一看,渐隐渐显的效果已经实现了,我们再来看下面的需求;

# 需求二:鼠标划上停止自动播放/离开恢复

# 思路分析:

❝

鼠标划上:

  • 左右箭头显示,这一步我们在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();

虽然实现了功能,但是当我们频繁点击的时候还会有一些问题,所以需要做下节流或者防抖,由于后面小芝麻打算先重点梳理防抖和节流的知识点,所以这里就没有在继续完善,各位小伙伴们如果有需要可自己加上😄

敬请期待小芝麻的知识总结哦,感谢大家的支持!

欢迎来到 金色小芝麻
看板娘