轮播图实现原理

  1. 轮播图原理:给图片一个数字属性,播放下一张图片只要数字 + 1 即可实现;最后一张图片的处理方式是求余操作(求余操作能让小标回到0)
    
    
    
    

     

  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:



    
        
        轮播图
        
    
    
        
        

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()

 

你可能感兴趣的:(前端)