1 Star 0 Fork 0

小明 / carousel

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
index.js 7.25 KB
一键复制 编辑 原始数据 按行查看 历史
小明 提交于 2022-11-27 18:50 . Project
const imgData = [
'./img/1.webp',
'./img/2.webp',
'./img/3.webp',
'./img/4.webp',
]
// 防抖函数
function debounceEvent (Callback, delayTime) {
let timer = null
return function (...agmes) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
Callback.apply(this, [...agmes])
}, delayTime)
}
}
// 节流函数
function throttleEvent (Callback, delayTime) {
// 上一次执行的时间,
let constTime = 0
// 可以认为时节流的阀门。
let valve = false
return function (...agmes) {
let createTime = new Date().getTime()
let day = (createTime - constTime) / 1000
valve = !constTime || day > delayTime ? true : false
if (valve) {
Callback.apply(this, [...agmes])
constTime = createTime
}
}
}
// 滚动容器
const carousel = document.querySelector('.carousel')
// 一些要用的公共配置属性
const config = {
cont: imgData.length,
width: carousel.clientWidth,// 图片宽度
timeNum: 3000,
_actveIndex: 0, // 当前展示的图标下标
ionTime: 600,// 过度时间
}
let time = null // 全局定时器
window.addEventListener('resize', debounceEvent(() => {
config.width = carousel.clientWidth
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
}, 500))
Object.defineProperty(config, 'actveIndex', {
get () {
return this._actveIndex
},
set (value) {
this._actveIndex = value
const indexArr = document.querySelectorAll('.indexBox span')
indexArr.forEach(item => {
item.classList.remove('actve')
})
indexArr[value] ? indexArr[value].classList.add('actve') : indexArr[0].classList.add('actve')
}
})
// 鼠标移入和移出事件
function mouseen () {
// 鼠标移入时暂停定时器
carousel.addEventListener('mouseenter', () => {
clearInterval(time)
})
// 移出开启定时器
carousel.addEventListener('mouseleave', () => {
animation()
})
}
// 上下页事件
function btnEvent () {
const left = document.querySelector('.left')
const right = document.querySelector('.right')
// 上一张
left?.addEventListener('click', throttleEvent(() => {
clearInterval(time) // 点击时关闭定时器
// 判断是否为第一张,如果是第一张,暂停过度,跳到最后一张,在开启动画往
if (config.actveIndex == 0) {
carousel.style.transition = 'none 0s'
config.actveIndex = config.cont
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
}
setTimeout(() => {
config.actveIndex--
carousel.style.transition = `all ${config.ionTime / 1000}s`
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
}, 5);
}, config.ionTime / 1000))
// 下一张
right?.addEventListener('click', throttleEvent(() => {
// 判断是否正在过度,如果在则暂停
if (config.transition) return
clearInterval(time) // 点击时关闭定时器
transformRight()
animation() //
}, config.ionTime / 1000))
}
// 下一页逻辑
function transformRight () {
carousel.style.transition = `all ${config.ionTime / 1000}s`
config.actveIndex++
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
// 判断是否是最后一张,如果是最后一张则暂停过度回到第一张
if (config.actveIndex == config.cont) {
// 在当前动画过度完成后回到第一张
setTimeout(() => {
carousel.style.transition = 'none 0s'
config.actveIndex = 0
carousel.style.transform = `translateX(-${0}px)`
}, config.ionTime);
}
}
// 定时器函数
function animation () {
if (imgData.length < 2) return
time = setInterval(() => transformRight(), config.timeNum);
}
// 跑马灯事件
function findIndexEvent () {
document.querySelector('.indexBox').onclick = function (e) {
if (e.target.nodeName == 'SPAN') {
clearInterval(time)
config.actveIndex = e.target.dataset.index
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
animation()
}
}
}
// 创建dom开启轮播动画
function createDom (imgArr) {
const arr = [...imgArr]
if (arr.length > 1) {
arr.push(arr[0]) // 为了完成无缝滚动,所以把第一张图复制一个放到最后一张
let leftdiv = document.createElement('div')
let rightdiv = document.createElement('div')
leftdiv.className = 'left'
rightdiv.className = 'right'
let mian = document.getElementById('mian')
mian.append(leftdiv)
mian.append(rightdiv)
}
const elFrag = document.createDocumentFragment()
arr.forEach(item => {
let img = document.createElement('img')
img.src = item
elFrag.append(img)
})
carousel.append(elFrag)
const spanFra = document.createDocumentFragment()
imgArr.forEach((_item, index) => {
let span = document.createElement('span')
span.dataset.index = index
if (index === 0) { span.classList.add('actve') }
spanFra.append(span)
})
document.querySelector('.indexBox').append(spanFra)
animation() // 定时器
mouseen() // 鼠标事件
btnEvent() // 左右切换事件
findIndexEvent() // 跑马灯事件
slideEvent(imgArr.length) // h5手指滑动切换
}
// h5手指滑动切换
function slideEvent (imgLength) {
let stateX // 手指按下的位置
let translate // 当前位移值
// 手指触摸开始时
carousel.addEventListener('touchstart', (e) => {
clearInterval(time)
let pageX = e.changedTouches[0].pageX
stateX = pageX
translate = config.actveIndex * config.width
})
// 手指开始滑动时
carousel.addEventListener('touchmove', (e) => {
let pageX = e.changedTouches[0].pageX
carousel.style.transition = 'none 0.1s'
if (stateX > pageX) { // 往左滑动(下一张)
carousel.style.transform = `translateX(-${translate + (stateX - pageX)}px)`
} else {
if (config.actveIndex == 0 && imgLength > 1) {
carousel.style.transition = 'none 0s'
config.actveIndex = config.cont
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
return setTimeout(() => {
carousel.style.transition = `all ${config.ionTime / 1000}s`
carousel.style.transform = `translateX(-${translate - (pageX - stateX)}px)`
}, 5);
}
if (imgLength == 1) {
return carousel.style.transform = `translateX(${(pageX - stateX)}px)`
}
carousel.style.transition = `all ${config.ionTime / 1000}s`
carousel.style.transform = `translateX(-${translate - (pageX - stateX)}px)`
}
})
// 触摸结束
carousel.addEventListener('touchend', (e) => {
let pageX = e.changedTouches[0].pageX
if (imgLength < 2) {
carousel.style.transition = `all ${config.ionTime / 1000}s`
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
return
}
if (stateX > pageX) { // 往左滑动
if (stateX - pageX > config.width / 3.5) {// 如果滑动大于下定外都自动翻页,如果小于则回弹
return transformRight()
}
} else {
if (pageX - stateX > config.width / 3.5) {
config.actveIndex--
}
}
carousel.style.transition = `all ${config.ionTime / 1000}s`
carousel.style.transform = `translateX(-${config.actveIndex * config.width}px)`
animation()
})
}
createDom(imgData)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ren_jinming/carousel.git
git@gitee.com:ren_jinming/carousel.git
ren_jinming
carousel
carousel
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891