first commit
This commit is contained in:
331
h5/js/utils/swiper.js
Normal file
331
h5/js/utils/swiper.js
Normal file
@@ -0,0 +1,331 @@
|
||||
(function () {
|
||||
/**
|
||||
* 构造函数
|
||||
* @param {*} ParentElement 父节点的选择器名称
|
||||
* @param {*} Configuration 插件的自定义设置项
|
||||
*/
|
||||
function Swiper(ParentElement, Configuration) {
|
||||
// 默认参数
|
||||
// slideChangeTransitionStart【完成】
|
||||
// slideTo【完成】
|
||||
this.defaultConf = {
|
||||
reverse: false,
|
||||
timer: '', // 保存自动播放的定时器
|
||||
ParentElement: '.swiper-container',
|
||||
wrapper: '.swiper-wrapper',
|
||||
slide: '.swiper-slide',
|
||||
config: {
|
||||
loop: false, // 是否开启循环播放【完成】
|
||||
time: 1, // 自动播放的间隔事件【完成】
|
||||
speed: 300, // 切换轮播图时候用的时间【完成】
|
||||
grabCursor: false, // 鼠标放到轮播图上是否显示为 小手【完成】
|
||||
initialSlide: 0, // 默认显示第一个【完成】
|
||||
auto: false, // 是否开启自动播放【完成】
|
||||
},
|
||||
// 小圆点的父标签选择器名称
|
||||
pagination: {
|
||||
el: '.swiper-pagination',
|
||||
},
|
||||
navigation: {
|
||||
nextEl: '.swiper-button-next', // 下一页
|
||||
prevEl: '.swiper-button-prev', // 上一页
|
||||
},
|
||||
}
|
||||
|
||||
this.defaultConf.ParentElement = ParentElement || this.defaultConf.ParentElement;
|
||||
this.defaultConf.config.loop = Configuration.loop || this.defaultConf.config.loop;
|
||||
this.defaultConf.config.time = Configuration.time || this.defaultConf.config.time;
|
||||
this.defaultConf.config.speed = Configuration.speed || this.defaultConf.config.speed;
|
||||
this.defaultConf.config.grabCursor = Configuration.grabCursor || this.defaultConf.config.grabCursor;
|
||||
this.defaultConf.config.initialSlide = Configuration.initialSlide || this.defaultConf.config.initialSlide;
|
||||
this.defaultConf.config.auto = Configuration.auto || this.defaultConf.config.auto;
|
||||
this.defaultConf.wrapper = Configuration.wrapper || this.defaultConf.wrapper;
|
||||
this.defaultConf.slide = Configuration.slide || this.defaultConf.slide;
|
||||
|
||||
this.slideArr = this._(`${this.defaultConf.wrapper} ${this.defaultConf.slide}`);
|
||||
|
||||
// 最外层 swiper-container 宽度
|
||||
this.f = this.$(this.defaultConf.ParentElement).offsetWidth;
|
||||
|
||||
// 判断小圆点
|
||||
if (Configuration.hasOwnProperty("pagination")) {
|
||||
this.defaultConf.pagination.el = Configuration.pagination.el;
|
||||
this.RenderDot()
|
||||
}
|
||||
|
||||
// 判断使用自定义前进后退按钮
|
||||
if (Configuration.hasOwnProperty("navigation")) {
|
||||
this.RenderNavigation()
|
||||
//判断下一页按钮的名称是否自定义
|
||||
if (Configuration.navigation.hasOwnProperty("nextEl")) {
|
||||
this.defaultConf.navigation.nextEl = Configuration.navigation.nextEl;
|
||||
}
|
||||
//判断上一页按钮的名称是否自定义
|
||||
if (Configuration.navigation.hasOwnProperty("prevEl")) {
|
||||
this.defaultConf.navigation.prevEl = Configuration.navigation.prevEl;
|
||||
}
|
||||
}
|
||||
|
||||
this.UserConfig = Configuration
|
||||
this.init()
|
||||
}
|
||||
|
||||
|
||||
// 类的方法
|
||||
Swiper.prototype = {
|
||||
init: function () {
|
||||
this.SetWrapperWidth();
|
||||
this.defaultConf.config.auto ? this.AutoPlay() : '';
|
||||
this.initSwiperSlide()
|
||||
},
|
||||
// 设置swiper-slide父类的宽度
|
||||
SetWrapperWidth: function () {
|
||||
|
||||
// 计算swiper-slide的宽度
|
||||
this.slideArr.forEach(v => v.style.width = `${this.f}px`)
|
||||
this.$(this.defaultConf.wrapper).style = `
|
||||
width: ${this.f * this.slideArr.length}px;
|
||||
left: -${this.f * this.defaultConf.config.initialSlide}px;
|
||||
transition: all ease ${this.defaultConf.config.speed / 1000}s;
|
||||
cursor: ${this.defaultConf.config.grabCursor ? 'pointer' : ''} ;
|
||||
`
|
||||
},
|
||||
|
||||
/**
|
||||
* 注册移动端滑动
|
||||
*/
|
||||
initSwiperSlide: function () {
|
||||
var fa = this.$(this.defaultConf.ParentElement),
|
||||
startX = 0,
|
||||
startY = 0;
|
||||
|
||||
fa.addEventListener('touchstart', function (e) {
|
||||
e.stopPropagation()
|
||||
startX = e.targetTouches[0].pageX
|
||||
startY = e.targetTouches[0].pageY
|
||||
})
|
||||
|
||||
var getDirection = function (startx, starty, endx, endy) {
|
||||
// 获得角度
|
||||
var getAngle = function(angx, angy) {
|
||||
return Math.atan2(angy, angx) * 180 / Math.PI;
|
||||
};
|
||||
|
||||
var angx = endx - startx;
|
||||
var angy = endy - starty;
|
||||
var result = 0;
|
||||
|
||||
// 如果滑动距离太短
|
||||
if (Math.abs(angx) < 2 && Math.abs(angy) < 2) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var angle = getAngle(angx, angy);
|
||||
if (angle >= -135 && angle <= -45) {
|
||||
result = 1;
|
||||
} else if (angle > 45 && angle < 135) {
|
||||
result = 2;
|
||||
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
|
||||
result = 3;
|
||||
} else if (angle >= -45 && angle <= 45) {
|
||||
result = 4;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fa.addEventListener('touchmove', (e) => {
|
||||
e.stopPropagation()
|
||||
var endX = e.changedTouches[0].pageX;
|
||||
var endY = e.changedTouches[0].pageY;
|
||||
|
||||
var direction = getDirection(startX, startY, endX, endY);
|
||||
if (direction == 3 || direction == 4) {
|
||||
var x = parseInt(endX - startX) - 40
|
||||
this.$(this.defaultConf.wrapper).style.webkitTransform = `translate3d(${x}px,0px,0px)`;
|
||||
}
|
||||
});
|
||||
|
||||
fa.addEventListener('touchend', (e) => {
|
||||
e.stopPropagation()
|
||||
var endX = e.changedTouches[0].pageX;
|
||||
var endY = e.changedTouches[0].pageY;
|
||||
|
||||
var direction = getDirection(startX, startY, endX, endY);
|
||||
|
||||
switch (direction) {
|
||||
case 0:
|
||||
console.log("未滑动!");
|
||||
break;
|
||||
case 1:
|
||||
console.log("向上!")
|
||||
break;
|
||||
case 2:
|
||||
console.log("向下!")
|
||||
break;
|
||||
case 3:
|
||||
this.$(this.defaultConf.wrapper).style.webkitTransform = `translate3d(0px,0px,0px)`;
|
||||
this.animation(-this.f)
|
||||
this.CallMethods()
|
||||
this.UserConfig.pagination && this.ChangeDotActive()
|
||||
console.log("向左!")
|
||||
break;
|
||||
case 4:
|
||||
this.$(this.defaultConf.wrapper).style.webkitTransform = `translate3d(0px,0px,0px)`;
|
||||
this.animation(this.f)
|
||||
this.CallMethods()
|
||||
this.UserConfig.pagination && this.ChangeDotActive()
|
||||
console.log("向右滑动");
|
||||
break;
|
||||
default:
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
CallMethods() {
|
||||
if (this.UserConfig.hasOwnProperty("on")) {
|
||||
var TotalLeft = Math.abs(parseInt(this.$(this.defaultConf.wrapper).style.left));
|
||||
index = TotalLeft / this.f;
|
||||
// 实现调用用户传入的方法,返回下标给用户
|
||||
this.UserConfig.on && this.UserConfig.on.slideChangeTransitionStart(index)
|
||||
}
|
||||
},
|
||||
|
||||
// 生成小圆点
|
||||
RenderDot: function () {
|
||||
this.slideArr.forEach((v, i) => {
|
||||
this.$(this.defaultConf.pagination.el).innerHTML +=
|
||||
`
|
||||
<div class="swiper-dot ${i == 0 ? 'swiper-active' : ''}"></div>
|
||||
`
|
||||
});
|
||||
|
||||
var Dot = this._(`${this.defaultConf.pagination.el} .swiper-dot`);
|
||||
Dot.forEach((v, i) => {
|
||||
v.onclick = () => {
|
||||
this.UserConfig.pagination && this.ChangeDotActive(i)
|
||||
this.$(this.defaultConf.wrapper).style.left = `-${i * this.f}px`;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 渲染左右前进后退按钮
|
||||
RenderNavigation: function () {
|
||||
var prev = this.$(this.defaultConf.navigation.prevEl);
|
||||
var next = this.$(this.defaultConf.navigation.nextEl);
|
||||
prev.innerText = "<";
|
||||
next.innerText = ">";
|
||||
this.BindNavigationClick(prev, next)
|
||||
},
|
||||
|
||||
// 为上一页下一页按钮绑定切换事件
|
||||
BindNavigationClick() {
|
||||
// var a = this
|
||||
// 下一页
|
||||
this.$(this.defaultConf.navigation.nextEl).onclick = () => {
|
||||
this.animation(-this.f)
|
||||
this.UserConfig.pagination && this.ChangeDotActive()
|
||||
}
|
||||
// 上一页
|
||||
this.$(this.defaultConf.navigation.prevEl).onclick = () => {
|
||||
this.animation(this.f)
|
||||
this.UserConfig.pagination && this.ChangeDotActive()
|
||||
}
|
||||
},
|
||||
|
||||
// 切换动画
|
||||
animation(offset) {
|
||||
var swiperWrapper = this.$(this.defaultConf.wrapper);
|
||||
var y = parseInt(swiperWrapper.style.left) + offset,
|
||||
max = -(this.f * (this.slideArr.length - 1));
|
||||
|
||||
// 如果时最后一张图
|
||||
if (y < max) {
|
||||
if (this.defaultConf.config.loop) {
|
||||
swiperWrapper.style.left = "0px";
|
||||
} else if (this.defaultConf.config.auto) {
|
||||
this.defaultConf.reverse = true
|
||||
this.animation(this.f)
|
||||
}
|
||||
return;
|
||||
|
||||
// 判断是不是第一张图
|
||||
} else if (y > 0) {
|
||||
if (this.defaultConf.config.loop == false && this.defaultConf.config.auto) {
|
||||
this.defaultConf.reverse = false
|
||||
swiperWrapper.style.left = `${y - this.f * 2}px`
|
||||
}
|
||||
if (this.defaultConf.config.loop) {
|
||||
swiperWrapper.style.left = `${max}px`
|
||||
}
|
||||
return
|
||||
} else {
|
||||
if (this.defaultConf.config.loop == false
|
||||
&& this.defaultConf.config.auto
|
||||
&& this.defaultConf.reverse) {
|
||||
swiperWrapper.style.left = `${y}px`
|
||||
} else {
|
||||
swiperWrapper.style.left = `${y}px`
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
ChangeDotActive(type = null) {
|
||||
var Dot = this._(`${this.defaultConf.pagination.el} .swiper-dot`);
|
||||
var index = "";
|
||||
if (type == null) {
|
||||
var TotalLeft = Math.abs(parseInt(this.$(this.defaultConf.wrapper).style.left));
|
||||
index = TotalLeft / this.f;
|
||||
} else {
|
||||
index = type;
|
||||
}
|
||||
|
||||
// 实现调用用户传入的方法,返回下标给用户
|
||||
this.CallMethods()
|
||||
|
||||
// 清除所有的激活样式
|
||||
Dot.forEach(val => val.className = "swiper-dot");
|
||||
// 为你点击的li加激活样式
|
||||
Dot[index].className = "swiper-dot swiper-active";
|
||||
},
|
||||
|
||||
AutoPlay() {
|
||||
this.defaultConf.timer = setInterval(() => {
|
||||
if (this.defaultConf.config.loop == false
|
||||
&& this.defaultConf.config.auto
|
||||
&& this.defaultConf.reverse) {
|
||||
this.animation(this.f)
|
||||
} else {
|
||||
this.animation(-this.f)
|
||||
}
|
||||
this.UserConfig.pagination && this.ChangeDotActive()
|
||||
}, this.defaultConf.config.time * 1000)
|
||||
|
||||
this.$(this.defaultConf.ParentElement).onmouseover = function () {
|
||||
clearInterval(this.defaultConf.timer)
|
||||
}
|
||||
|
||||
this.$(this.defaultConf.ParentElement).onmouseout = () => {
|
||||
this.AutoPlay()
|
||||
}
|
||||
},
|
||||
|
||||
// 通过js调用此方法,实现轮播图的切换
|
||||
slideTo(index) {
|
||||
this.$(this.defaultConf.wrapper).style.left = `-${index * this.f}px`;
|
||||
this.UserConfig.pagination && this.ChangeDotActive()
|
||||
},
|
||||
$: function (className) {
|
||||
return document.querySelector(className)
|
||||
},
|
||||
_: function (className) {
|
||||
return document.querySelectorAll(className)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.swiper = Swiper
|
||||
|
||||
|
||||
})()
|
||||
Reference in New Issue
Block a user