* {
padding: 0;
margin: 0;
line-height: 1;
}
video {
width: 100%;
height: auto;
}
.slide-wrapper {
display: flex;
align-items: center;
height: 100vh;
width: 100%;
overflow: hidden
}
li, ul {
display: flex;
list-style: none;
width: 100%;
height: 100%;
}
li {
flex: none;
justify-content: center;
align-items: center;
width: inherit;
height: 100%;
}
slide: function () {
//默认值
var DEFAULTS = {
ul: $(this).children('ul'),
li: $(this).children().children('li'),
index: 0,
continuousScroll: false,
autoSwipe: false,
speed: 4000,
axisX: true,
transitionType: 'ease',
lazyLoad: false,
enabled: true,
firstCallback: function () {
},
onCallback: function () {
},
onTouchStart: function () {
}
};
// 检测
var support = {
touch: (win.Modernizr && Modernizr.touch === true) || (function () {
return !!(('ontouchstart' in win) || win.DocumentTouch && document instanceof DocumentTouch);
})()
};
var fn = function () {
var obj = {};
if (typeof arguments[0] == 'string') {
obj.src = arguments[0].toString();
} else {
obj = arguments[0];
}
// 参数
this.opts = $.extend({}, DEFAULTS, obj);
// 位移值
this._distance = 50;
this._index = this.opts.index;
this._length = this.opts.li.length;
if (this.opts.axisX) {
this.opts.ul.css('flex-flow', 'row')
} else {
this.opts.ul.css('flex-flow', 'column')
}
// 连续滚动,复制dom
if (this.opts.continuousScroll) {
this.opts.ul
.prepend(this.opts.li.last().clone())
.append(this.opts.li.first().clone());
this._length = this.opts.ul.children().length;
this._slideDistance = this.opts.axisX ? this.offsetWidth : this.offsetHeight;
this._index = 1;
fnScroll(this, 0);
}
this.opts.firstCallback(this);
// 触摸事件监听
$(this).on('touchstart', fnTouchstart);
$(this).on('touchmove', fnTouchmove);
$(this).on('touchend', fnTouchend);
// 横竖屏、窗口调整
$(win).on('onorientationchange' in win ? 'orientationchange' : 'resize', function () {
});
};
// css过渡
function fnTransition(dom, num) {
$(dom.opts.ul).css({
'transition': 'all ' + num + 's ' + dom.opts.transitionType
});
}
// css位移
function fnTranslate(dom, distance) {
var result = dom.opts.axisX ? distance + 'px,0,0' : '0,' + distance + 'px,0';
$(dom.opts.ul).css({
'transform': 'translate3d(' + result + ')'
});
}
function fnTouchstart(e) {
this.isScrolling = undefined;
this._moveDistance = 0;
this._slideDistance = this.opts.axisX ? this.offsetWidth : this.offsetHeight;
// 按下时的坐标
this._startX = support.touch ? e.touches[0].pageX : (e.pageX || e.clientX);
this._startY = support.touch ? e.touches[0].pageY : (e.pageY || e.clientY);
this.opts.onTouchStart(e);
}
function fnTouchmove(e) {
if (this.opts.enabled) {
// 触摸时的坐标
this._curX = support.touch ? e.touches[0].pageX : (e.pageX || e.clientX);
this._curY = support.touch ? e.touches[0].pageY : (e.pageY || e.clientY);
// 触摸时的距离
this._moveX = this._curX - this._startX;
this._moveY = this._curY - this._startY;
// 优化触摸禁止事件
if (typeof this.isScrolling == 'undefined') {
if (this.opts.axisX) {
this.isScrolling = !!(Math.abs(this._moveX) >= Math.abs(this._moveY));
} else {
this.isScrolling = !!(Math.abs(this._moveY) >= Math.abs(this._moveX));
}
}
// 距离
if (this.isScrolling) {
if (e.preventDefault) e.preventDefault();
else e.returnValue = false;
// 触摸时跟手
fnTransition(this, 0);
this._moveDistance = this.opts.axisX ? this._moveX : this._moveY;
}
fnTranslate(this, -(this._slideDistance * this._index - this._moveDistance));
}
}
function fnTouchend(e) {
if (!this.isScrolling) {
//自动轮播
fnAutoSlide(this);
}
// 移动距离大于 distance 滚动,否则回弹
if (Math.abs(this._moveDistance) <= this._distance) {
fnSlide(this, '', '.3');
} else {
// 手指触摸上一屏滚动
if (this._moveDistance > this._distance) {
fnSlide(this, 'prev', '.3');
// 手指触摸下一屏滚动
} else if (Math.abs(this._moveDistance) > this._distance) {
fnSlide(this, 'next', '.3');
}
}
this._moveDistance = 0;
this.opts.enabled = true;
}
// 轮播方法
function fnSlide(me, go, num) {
if (typeof go === 'number') {
me._index = go;
} else if (go == 'next') {
me._index++;
} else if (go == 'prev') {
me._index--
}
// 连续滚动
if (me.opts.continuousScroll) {
if (me._index >= me._length - 1) {
fnScroll(me, num);
me._index = 1;
setTimeout(function () {
fnScroll(me, 0);
return;
}, 300);
} else if (me._index < 1) {
fnScroll(me, num);
me._index = me._length - 2;
setTimeout(function () {
fnScroll(me, 0);
return;
}, 300);
} else {
fnScroll(me, num);
}
} else {
if (me._index >= me._length) {
me._index = me._length - 1;
} else if (me._index < 0) {
me._index = 0
}
fnScroll(me, num);
}
me.opts.onCallback(me);
}
// 轮播动作
function fnScroll(me, num) {
fnTransition(me, num);
fnTranslate(me, -( me._index * me._slideDistance ));
}
// 自动轮播
function fnAutoSlide(me) {
if (me.opts.autoSwipe) {
fnStopSlide(me);
me.autoSlide = setInterval(function () {
fnSlide(me, 'next', '.3');
}, me.opts.speed);
}
}
// 停止轮播
function fnStopSlide(me) {
clearInterval(me.autoSlide);
}
// 指定轮播 当连续滚动时 _index + 1
this.pageto = function (i) {
fnSlide(this[0], i, 0)
};
if (this.length) {
var args = arguments;
$.each(this, function (i, elem) {
fn.apply(elem, args)
});
return this
}
}
<div class="slide-wrapper" id="slide1">
<ul>
<li style="background: red;">
</li>
<li style="background: blue;">
</li>
<li style="background: black;">
<div class="slide-wrapper" id="slide2">
<ul>
<li style="background: yellow">
<video id="video2"></video>
</li>
<li style="background: darkred;">
<div id="image1" style="overflow: auto; width: 200px; height: 400px; background: #fff; display: flex; flex-flow: column nowrap; align-items: center; "></div>
</li>
</ul>
</div>
</li>
</ul>
</div>
<script>
$(function () {
var s2 = $('#slide2').slide({
axisX: false
});
var s1 = $('#slide1').slide({
firstCallback: function (me) {
console.log(me)
},
onCallback: function (me) {
}
});
});
</script>