轮播图实现原理

  1. 轮播图原理:给图片一个数字属性,播放下一张图片只要数字 + 1 即可实现;最后一张图片的处理方式是求余操作(求余操作能让小标回到0)
    <!-- data-imgs 是图片的总数 -->
    <!-- data-active 是当前显示的图片的下标 -->
    <!-- 我们要播放图片只需要获取data-active属性即可,比如打开图片:e("#id-image-" + "data-active") -->
    <div class="slide" data-imgs="3" data-active="0">
        <!-- active属性:显示图片 -->
        <img id="id-image-0" class="slide-image active" src="picture/1.jpg" alt="">
        <img id="id-image-1" class="slide-image" src="picture/2.jpg" alt="">
        <img id="id-image-2" class="slide-image" src="picture/3.jpg" alt="">

     

  2. 自动播放原理:利用setInterval(function, time)和setTimeout(function, time)实现:
    1. setInterval(function, time):定时器
          1. 函数含义:隔time时长,重复执行function函数,无限循环执行
          2. function:执行函数的函数名
          3. time:间隔时间,以毫秒为单位,1s = 1000ms
          4. 注意:setInterval() 会返回一个数字, 这个数字可以用来清除定时器
          5. 清除格式:clearInterval()
  3. setTimeout(function, time):定时器
        1. 函数含义:隔time时长,重复执行function函数,只执行一次
        2. function:执行函数的函数名
        3. time:间隔时间
        4. 注意:setTimeout() 会返回一个数字, 这个数字可以用来清除定时器
        5. 清除格式:clearTimeout()
    // 设置轮播图
    const autoPlay = function() {
        let interval = 2000
        setInterval(function() {
            // 每 2s 都会调用这个函数
            // 该函数会播放下一张图片
            playNextImage()
        }, interval)
    }

     

源代码(图片文件夹需要自建)html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>轮播图</title>
        <style>
            .hide {
                display: none;
            }
            .menu-content {
                height: 100px;
                border: 1px solid red;
            }
            .item {
                filter: grayscale(100%);
            }
            .item.highlight {
                filter: initial;
            }
            .item.highlight img {
                width: 150px;
                height: 150px;
            }
            img {
                /*transition 这个 css 指定了某个属性发生变化的时候自动使用动画效果和动画时间*/
                transition: width 1s, height 1s;
            }
            .item img {
                width: 100px;
                height: 100px;
            }
            .slide {
                position: relative;
                width: 600px;
            }
            .slide-image {
                display: none;
                max-width: 100%;
            }
            .active {
                display: inline-block;
            }
            .slide-button {
                width: 30px;
                height: 50px;
                color: #fff;
                border: 0;
                background: #000;
                opacity: 0.3;
                cursor: pointer;
                outline: 0;
            }
            .slide-button.left {
                left: 0;
            }
            .slide-button.right {
                right: 0;
            }
            /* 垂直居中 */
            .vertical-center {
                position: absolute;
                top: 50%;
                transform: translateY(-50%);
            }
            /* 水平居中 */
            .horizontal-center {
                position: absolute;
                left: 50%;
                transform: translateX(-50%);
            }
            .slide-indicators {
                bottom: 10px;
                width: 150px;
                margin: 0 auto;
                text-align: center;
            }
            .slide-indi {
                display: inline-block;
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background: red;
            }
            .white {
                background: white;
            }
        </style>
    </head>
    <body>
        <!-- 轮播图 -->
        <div class="lunbotu">
            <!-- data-imgs 是图片的总数 -->
            <!-- data-active 是当前显示的图片的下标 -->
            <!-- 我们要播放图片只需要获取data-active属性即可,比如打开图片:e("#id-image-" + "data-active") -->
            <div class="slide" data-imgs="3" data-active="0">
                <!-- active属性:显示图片 -->
                <img id="id-image-0" class="slide-image active" src="picture/1.jpg" alt="">
                <img id="id-image-1" class="slide-image" src="picture/2.jpg" alt="">
                <img id="id-image-2" class="slide-image" src="picture/3.jpg" alt="">
                <!-- html entry(实体) -->
                <!-- &lt:< -->
                <!-- &gt:> -->
                <button class="slide-button left vertical-center" data-offset="-1">&lt;</button>
                <button class="slide-button right vertical-center" data-offset="1">&gt;</button>
                <!-- 设置小圆点-->
                <div class="slide-indicators horizontal-center">
                    <!-- white属性:表示小圆点颜色为白色(默认为红色) -->
                    <div id="id-indicator-0" class="slide-indi white" data-index="0"></div>
                    <div id="id-indicator-1" class="slide-indi" data-index="1"></div>
                    <div id="id-indicator-2" class="slide-indi" data-index="2"></div>
                </div>
            </div>
        </div>
        <script src="milu.js"></script>
        <script src="ex.js"></script>
    </body>
</html>

milu.js:

// 输出函数log
const log = console.log.bind(console)


// condition表示的是一个Boolean值,message是一个字符串
// 测试函数
const ensure = function(condition, message) {
    // 在条件不成立的时候, 输出 message
    if (!condition) {
        log('*** 测试失败', message)
    } else {
        log('*** 测试成功')
    }
}


// 在全局打开第一个具有selector属性的选择器
// selector是元素选择器,可以是class选择器,也可以是id选择器,还可以是元素选择器
// 如果找到元素,则返回该元素,否则返回null并且提出一个警告
const e = function(selector) {
    let element = document.querySelector(selector)
    if (element === null) {
        let s = `selector ${selector} not found`
        alert(s)
        //
        return null
    } else {
        return element
    }
}


// 在全局内返回所有具有selector属性的元素,且该返回值是一个数组
// selector是元素选择器,可以是class选择器,也可以是id选择器,还可以是元素选择器
// 如果找到元素,则返回该元素,否则返回null并且提出一个警告
const es = function(selector) {
    let elements = document.querySelectorAll(selector)
    if (elements.length === 0) {
        let s = `selector ${selector} not found`
        alert(s)
        //
        return []
    } else {
        return elements
    }
}


// selector元素的属性
// eventName是时间的名字
// callback是一个函数
// 该函数是把带有selector元素绑定一个事件callback,且该事件的触发函数是eventName
const bindAll = function(selector, eventName, callback) {
    let elements = es(selector)
    for (let i = 0; i < elements.length; i++) {
        let tag = elements[i]
        // log(tag)
        tag.addEventListener(eventName, callback)
    }
}


// element是一个元素选择器,表示某一个元素
// html是要添加的元素,其类型是html字符串
// 该函数表示将html元素添加到element元素的最末端
const appendHtml = function(element, html) {
    element.insertAdjacentHTML('beforeend', html)
}


// element是一个元素选择器,表示一个元素
// eventName表示响应事件
// callback表示响应函数
// 该函数表示给element元素添加一个响应事件,响应的类型为eventName,响应函数为callback
const bindEvent = function(element, eventName, callback) {
    element.addEventListener(eventName, callback)
}


// class表示一个class属性
// 该函数表示移除全局所有带有className属性的元素的class属性
const removeClassAll = function(className) {
    let selector = '.' + className
    let elements = es(selector)
    for (let i = 0; i < elements.length; i++) {
        let e = elements[i]
        log('classname', className, e)
        e.classList.remove(className)
    }
}


// element表示是一个元素选择器,表示一个元素
// selector是一个元素的属性
// 在element元素中,打开带有selector属性的元素
const find = function(element, selector) {
    let e = element.querySelector(selector)
    if (e === null) {
        let s = `元素没找到,选择器 ${selector} 没有找到或者 js 没有放在 body 里`
        alert(s)
        return null
    } else {
        return e
    }
}

ex.js:

const showIndicatorAtIndex = function(index) {
    let nextIndex = index
    // 切换小圆点
    // 1. 删除当前小圆点的 class
    let indicatorClass = 'white'
    removeClassAll(indicatorClass)
    // 2. 得到下一个小圆点的选择器
    let indicatorSelector = '#id-indicator-' + String(nextIndex)
    let indicator = e(indicatorSelector)
    indicator.classList.add(indicatorClass)
}

// 显示对应的小圆点
const showImageAtIndex = function(slide, index) {
    log('index', index)
    let nextIndex = index
    // 设置父节点的 data-active
    slide.dataset.active = nextIndex
    log('nextIndex', nextIndex)
    let nextSelector = '#id-image-' + String(nextIndex)
    // 删除当前图片的 class 给下一张图片加上 class
    let className = 'active'
    removeClassAll(className)
    let img = e(nextSelector)
    img.classList.add(className)

    // 显示小圆点
    showIndicatorAtIndex(nextIndex)
}

// 求出下一张图片的坐标
const nextIndex = function(slide, offset) {
    let numberOfImgs = parseInt(slide.dataset.imgs, 10)
    let activeIndex = parseInt(slide.dataset.active, 10)
    // log('click slide')
    // 求出 button 的 data-offset
    // 上一张按钮的 offset 是 1
    // 下一张按钮的 offset 是 -1
    // let offset = Number(button.dataset.offset)
    // 求出下一张图片的 id
    let i = (activeIndex + offset) % numberOfImgs
    return i
}

// 给按钮绑定事件
const bindEventSlide = function() {
    // 打开button
    let selector = '.slide-button'
    bindAll(selector, 'click', function(event) {
        log('click next')
        // 找到 slide div
        let button = event.target
        let slide = button.parentElement
        // log('slide 哈哈', slide)
        let offset = Number(button.dataset.offset)
        // 求出下一个图片的 index
        let index = nextIndex(slide, offset)
        // 显示下一张图片
        showImageAtIndex(slide, index)
    })
}

// 给小圆点绑定事件
const bindEventIndicator = function() {
    let selector = '.slide-indi'
    bindAll(selector, 'click', function(event) {
        log('indicator')
        let self = event.target
        let index = Number(self.dataset.index)
        log('index', index, typeof index)
        // 得到 slide
        let slide = self.closest('.slide')
        // 直接播放第 n 张图片
        showImageAtIndex(slide, index)
    })
}

// 自动播放函数
const playNextImage = function() {
    let slide = e('.slide')
    // 求出下一个图片的 index
    let index = nextIndex(slide, 1)
    log('index in next', index)
    // 显示下一张图片
    showImageAtIndex(slide, index)
}

// 完成对按钮和小圆点元素的事件绑定
const bindEvents = function() {

    bindEventSlide()
    bindEventIndicator()
}

// 设置轮播图
const autoPlay = function() {
    let interval = 2000
    setInterval(function() {
        // 每 2s 都会调用这个函数
        playNextImage()
    }, interval)
}

const __main = function() {
    // 设置左右按钮,并完成事件绑定
    bindEvents()
    // 设置自动播放
    autoPlay()
}

__main()

 

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值