208 lines
7.0 KiB
JavaScript
208 lines
7.0 KiB
JavaScript
// 自执行函数
|
||
(function () {
|
||
|
||
class Swiper {
|
||
constructor(el, option) {
|
||
|
||
// 插件的默认配置参数
|
||
this.defaultOption = {
|
||
timer: null,
|
||
el: '.swiper-container',
|
||
wrapper: '.swiper-wrapper',
|
||
slide: '.swiper-slide',
|
||
loop: false,
|
||
autoPlay: false, // 完成
|
||
autoTime: 3000, // 完成
|
||
initialSlide: 0, // 完成
|
||
navigation: {
|
||
nextEl: '.swiper-button-next',
|
||
prevEl: '.swiper-button-prev',
|
||
},
|
||
length: function () {
|
||
return _(`${this.el} ${this.slide}`).length - 1;
|
||
},
|
||
width: function () {
|
||
return $(this.el).offsetWidth;
|
||
},
|
||
container: function() {
|
||
return $(this.el);
|
||
},
|
||
wrap: function(offset) {
|
||
return $(`${this.el} ${this.wrapper}`).left(offset)
|
||
},
|
||
next: function () {
|
||
return $(`${this.el} ${this.navigation.nextEl}`)
|
||
},
|
||
prev: function () {
|
||
return $(`${this.el} ${this.navigation.prevEl}`)
|
||
},
|
||
pag: function () {
|
||
return $(`${this.el} ${this.pagination.el}`)
|
||
},
|
||
child: function () {
|
||
return _(`${this.el} ${this.pagination.el} ${this.pagination.child}`)
|
||
},
|
||
pagination: {
|
||
el: '.swiper-pagination',
|
||
child: '.pagination'
|
||
},
|
||
// 事件控制中心
|
||
EventController: {
|
||
}
|
||
|
||
}
|
||
// 必传参数的校验
|
||
if (typeof el == "string" && document.querySelector(el) != null) {
|
||
|
||
|
||
// 可选参数
|
||
this.defaultOption.el = el || this.defaultOption.el;
|
||
this.defaultOption.loop = option.loop || this.defaultOption.loop;
|
||
this.defaultOption.autoPlay = option.autoPlay || this.defaultOption.autoPlay;
|
||
this.defaultOption.autoTime = option.autoTime || this.defaultOption.autoTime;
|
||
this.defaultOption.initialSlide = option.initialSlide || this.defaultOption.initialSlide;
|
||
|
||
|
||
for (const key in option.on) {
|
||
this.defaultOption.EventController[key] = option.on[key]
|
||
}
|
||
|
||
this.defaultOption.navigation.nextEl = option?.navigation?.nextEl || this.defaultOption.navigation.nextEl;
|
||
this.defaultOption.navigation.prevEl = option?.navigation?.prevEl || this.defaultOption.navigation.prevEl;
|
||
this.defaultOption.pagination.el = option?.pagination?.el || this.defaultOption.pagination.el;
|
||
|
||
|
||
if (this.defaultOption.initialSlide > this.defaultOption.length()) {
|
||
throw new Error("initialSlide 下标不合理")
|
||
}
|
||
|
||
// console.log();
|
||
this.init();
|
||
} else {
|
||
throw new Error("el必须是字符串,且class类名有效!!")
|
||
}
|
||
}
|
||
|
||
init() {
|
||
this.prototypeMethods()
|
||
this.createdPagination()
|
||
this.setInitialSlide()
|
||
this.next()
|
||
this.prev()
|
||
|
||
this.defaultOption.autoPlay ? this.autoPlay() : ''
|
||
|
||
this.defaultOption.autoPlay
|
||
? this.defaultOption.container().onmouseout = () => this.autoPlay()
|
||
: ''
|
||
|
||
this.defaultOption.container().onmouseover = () => clearInterval(this.defaultOption.timer);
|
||
}
|
||
|
||
|
||
/**
|
||
* 下一页按钮的点击事件
|
||
*/
|
||
next() {
|
||
this.defaultOption.next().onclick = () => {
|
||
this.motion(-this.defaultOption.width())
|
||
}
|
||
}
|
||
|
||
prev() {
|
||
this.defaultOption.prev().onclick = () => {
|
||
this.motion(this.defaultOption.width())
|
||
}
|
||
}
|
||
|
||
setInitialSlide() {
|
||
this.defaultOption.wrap(this.defaultOption.initialSlide * -this.defaultOption.width())
|
||
this.changePagination(this.defaultOption.initialSlide)
|
||
}
|
||
|
||
motion(offset) {
|
||
var maxOffset = -this.defaultOption.length() * this.defaultOption.width();
|
||
var totalOffset = this.defaultOption.wrap() + offset;
|
||
|
||
if (totalOffset > 0) {
|
||
this.defaultOption.loop ? totalOffset = maxOffset : totalOffset = -0
|
||
}
|
||
|
||
if (totalOffset < maxOffset) {
|
||
this.defaultOption.loop ? totalOffset = 0 : totalOffset = maxOffset
|
||
}
|
||
|
||
|
||
this.defaultOption.EventController.slideChange &&
|
||
this.defaultOption.EventController.slideChange(
|
||
Math.abs(totalOffset / this.defaultOption.width())
|
||
)
|
||
|
||
this.changePagination(totalOffset / this.defaultOption.width() * -1)
|
||
this.defaultOption.wrap(totalOffset)
|
||
}
|
||
|
||
createdPagination() {
|
||
for (var i = 0; i <= this.defaultOption.length(); i++) {
|
||
this.defaultOption.pag().innerHTML += `
|
||
<div class="pagination ${i == 0 ? 'active' : ''}"></div>
|
||
`
|
||
}
|
||
|
||
this.defaultOption.child().forEach((v, i) => {
|
||
v.onclick = () => {
|
||
this.changePagination(i)
|
||
this.defaultOption.wrap(i * -this.defaultOption.width())
|
||
}
|
||
})
|
||
}
|
||
|
||
changePagination(index) {
|
||
var pagination = this.defaultOption.child()
|
||
pagination.forEach(v => {
|
||
v.classList.remove("active")
|
||
})
|
||
pagination[index].classList.add("active");
|
||
}
|
||
|
||
autoPlay() {
|
||
this.defaultOption.timer = setInterval(() => {
|
||
this.motion(-this.defaultOption.width())
|
||
}, this.defaultOption.autoTime)
|
||
}
|
||
|
||
on(methodsName, callback) {
|
||
this.defaultOption.EventController[methodsName] = callback
|
||
}
|
||
|
||
slideTo(index) {
|
||
this.changePagination(index)
|
||
this.defaultOption.wrap(index * -this.defaultOption.width())
|
||
}
|
||
|
||
|
||
prototypeMethods() {
|
||
HTMLDivElement.prototype.left = function (offset) {
|
||
if (this.className.includes("swiper-wrapper")) {
|
||
if (offset == undefined) {
|
||
return parseInt(this.style.left)
|
||
} else {
|
||
this.style.left = `${offset}px`
|
||
}
|
||
}
|
||
|
||
return null
|
||
}
|
||
}
|
||
}
|
||
|
||
function $(className) {
|
||
return document.querySelector(className)
|
||
}
|
||
|
||
function _(className) {
|
||
return document.querySelectorAll(className)
|
||
}
|
||
|
||
window.Swiper = Swiper
|
||
})() |