vant/packages/swipe/scroll.js
2017-08-22 17:52:16 +08:00

147 lines
3.8 KiB
JavaScript
Executable File

import { EventEmitter, extend } from './utils';
const setElementsStyles = (elems, styles) => {
Array.prototype.forEach.call(elems, item => {
extend(item.style, styles);
});
};
function Scroll(wrapElem, options) {
EventEmitter.apply(this, arguments);
this.wrapElem = wrapElem;
this.wrapSize = {
width: () => wrapElem.clientWidth,
height: () => wrapElem.clientHeight
};
this.options = extend({
loop: true,
autoPlay: false,
startIndex: 0
}, options);
this.init.apply(this, arguments);
}
Scroll.prototype = Object.create(new EventEmitter());
extend(Scroll.prototype, {
init: function() {
this.update();
},
getCurrentDist: function() {
return this.mCache.currentDist;
},
update: function() {
const oldPages = this.pages;
this.pages = this.wrapElem.querySelectorAll('.van-swipe-item');
if (oldPages && oldPages.length === this.pages.length) {
const isSame = Array.prototype.every.call(this.pages, (elem, index) => {
return this.pages[index] === oldPages[index];
});
if (isSame) {
return;
}
}
var defaultStyle = {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%'
};
setElementsStyles(this.pages, defaultStyle);
this.mCache = {
dist: 0,
offsetPage: 0
};
this.setCurrentPage(0);
this.movePage(this.options.startIndex * this.wrapSize.width(), true);
},
renderPage: function(dist = 0, currentOffsetPage = 0) {
var wrapWidth = this.wrapSize.width();
var offset = currentOffsetPage * wrapWidth - dist;
var page;
var leftPage;
var rightPage;
var leftOffset = offset - wrapWidth;
var rightOffset = offset + wrapWidth;
leftPage = this.pages[this.mapLoopPage(currentOffsetPage - 1)];
if (leftPage) {
if (Math.abs(leftOffset) <= wrapWidth) {
leftPage.style['-webkit-transform'] = 'translate3d(' + leftOffset + 'px, 0, 0)';
} else {
if (this.pages.length > 2) {
leftPage.style['-webkit-transform'] = 'translate3d(-9999px, 0, 0)';
}
}
}
rightPage = this.pages[this.mapLoopPage(currentOffsetPage + 1)];
if (rightPage) {
if (Math.abs(rightOffset) <= wrapWidth) {
rightPage.style['-webkit-transform'] = 'translate3d(' + rightOffset + 'px, 0, 0)';
} else {
if (this.pages.length > 2) {
rightPage.style['-webkit-transform'] = 'translate3d(-9999px, 0, 0)';
}
}
}
page = this.getCurrentPage();
if (page) {
page.style['-webkit-transform'] = 'translate3d(' + offset + 'px, 0, 0)';
page.style['display'] = 'block';
}
},
movePage: function(dist, isEnd) {
var currentOffsetPage;
this.mCache.currentDist = dist + this.mCache.dist;
if (isEnd) {
this.mCache.dist += dist;
}
currentOffsetPage = Math.round(this.mCache.currentDist / this.wrapSize.width()) || 0;
if (currentOffsetPage !== this.mCache.offsetPage) {
this.setCurrentPage(currentOffsetPage);
// 翻页
this.emit('pageChangeEnd', this.getCurrentPage()
, this.currentIndex, this.mCache.offsetPage);
this.mCache.offsetPage = currentOffsetPage;
}
this.renderPage(this.mCache.currentDist, currentOffsetPage);
},
getCurrentPage: function() {
return this.pages[this.currentIndex];
},
mapLoopPage: function(num) {
if (this.options.loop) {
var direction = num < 0 ? -1 : 1;
var l = this.pages.length;
return Math.abs(l + direction * Math.abs(num) % l) % l;
} else {
if (num >= this.pages.length || num < 0) {
return this.pages.length;
} else {
return num;
}
}
},
setCurrentPage: function(num) {
this.currentIndex = this.mapLoopPage(num);
}
});
export default Scroll;