import $ from '../../utils/dom';
|
import Utils from '../../utils/utils';
|
|
const Pagination = {
|
update() {
|
// Render || Update Pagination bullets/items
|
const swiper = this;
|
const rtl = swiper.rtl;
|
const params = swiper.params.pagination;
|
if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
|
const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
|
const $el = swiper.pagination.$el;
|
// Current/Total
|
let current;
|
const total = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
|
if (swiper.params.loop) {
|
current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);
|
if (current > slidesLength - 1 - (swiper.loopedSlides * 2)) {
|
current -= (slidesLength - (swiper.loopedSlides * 2));
|
}
|
if (current > total - 1) current -= total;
|
if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
|
} else if (typeof swiper.snapIndex !== 'undefined') {
|
current = swiper.snapIndex;
|
} else {
|
current = swiper.activeIndex || 0;
|
}
|
// Types
|
if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
|
const bullets = swiper.pagination.bullets;
|
let firstIndex;
|
let lastIndex;
|
let midIndex;
|
if (params.dynamicBullets) {
|
swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);
|
$el.css(swiper.isHorizontal() ? 'width' : 'height', `${swiper.pagination.bulletSize * (params.dynamicMainBullets + 4)}px`);
|
if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
|
swiper.pagination.dynamicBulletIndex += (current - swiper.previousIndex);
|
if (swiper.pagination.dynamicBulletIndex > (params.dynamicMainBullets - 1)) {
|
swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1;
|
} else if (swiper.pagination.dynamicBulletIndex < 0) {
|
swiper.pagination.dynamicBulletIndex = 0;
|
}
|
}
|
firstIndex = current - swiper.pagination.dynamicBulletIndex;
|
lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
|
midIndex = (lastIndex + firstIndex) / 2;
|
}
|
bullets.removeClass(`${params.bulletActiveClass} ${params.bulletActiveClass}-next ${params.bulletActiveClass}-next-next ${params.bulletActiveClass}-prev ${params.bulletActiveClass}-prev-prev ${params.bulletActiveClass}-main`);
|
if ($el.length > 1) {
|
bullets.each((index, bullet) => {
|
const $bullet = $(bullet);
|
const bulletIndex = $bullet.index();
|
if (bulletIndex === current) {
|
$bullet.addClass(params.bulletActiveClass);
|
}
|
if (params.dynamicBullets) {
|
if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
|
$bullet.addClass(`${params.bulletActiveClass}-main`);
|
}
|
if (bulletIndex === firstIndex) {
|
$bullet
|
.prev()
|
.addClass(`${params.bulletActiveClass}-prev`)
|
.prev()
|
.addClass(`${params.bulletActiveClass}-prev-prev`);
|
}
|
if (bulletIndex === lastIndex) {
|
$bullet
|
.next()
|
.addClass(`${params.bulletActiveClass}-next`)
|
.next()
|
.addClass(`${params.bulletActiveClass}-next-next`);
|
}
|
}
|
});
|
} else {
|
const $bullet = bullets.eq(current);
|
const bulletIndex = $bullet.index();
|
$bullet.addClass(params.bulletActiveClass);
|
if (params.dynamicBullets) {
|
const $firstDisplayedBullet = bullets.eq(firstIndex);
|
const $lastDisplayedBullet = bullets.eq(lastIndex);
|
for (let i = firstIndex; i <= lastIndex; i += 1) {
|
bullets.eq(i).addClass(`${params.bulletActiveClass}-main`);
|
}
|
if (swiper.params.loop) {
|
if (bulletIndex >= bullets.length - params.dynamicMainBullets) {
|
for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {
|
bullets.eq(bullets.length - i).addClass(`${params.bulletActiveClass}-main`);
|
}
|
bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(`${params.bulletActiveClass}-prev`);
|
} else {
|
$firstDisplayedBullet
|
.prev()
|
.addClass(`${params.bulletActiveClass}-prev`)
|
.prev()
|
.addClass(`${params.bulletActiveClass}-prev-prev`);
|
$lastDisplayedBullet
|
.next()
|
.addClass(`${params.bulletActiveClass}-next`)
|
.next()
|
.addClass(`${params.bulletActiveClass}-next-next`);
|
}
|
} else {
|
$firstDisplayedBullet
|
.prev()
|
.addClass(`${params.bulletActiveClass}-prev`)
|
.prev()
|
.addClass(`${params.bulletActiveClass}-prev-prev`);
|
$lastDisplayedBullet
|
.next()
|
.addClass(`${params.bulletActiveClass}-next`)
|
.next()
|
.addClass(`${params.bulletActiveClass}-next-next`);
|
}
|
}
|
}
|
if (params.dynamicBullets) {
|
const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
|
const bulletsOffset = (((swiper.pagination.bulletSize * dynamicBulletsLength) - (swiper.pagination.bulletSize)) / 2) - (midIndex * swiper.pagination.bulletSize);
|
const offsetProp = rtl ? 'right' : 'left';
|
bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);
|
}
|
}
|
if (params.type === 'fraction') {
|
$el.find(`.${params.currentClass}`).text(params.formatFractionCurrent(current + 1));
|
$el.find(`.${params.totalClass}`).text(params.formatFractionTotal(total));
|
}
|
if (params.type === 'progressbar') {
|
let progressbarDirection;
|
if (params.progressbarOpposite) {
|
progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
|
} else {
|
progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
|
}
|
const scale = (current + 1) / total;
|
let scaleX = 1;
|
let scaleY = 1;
|
if (progressbarDirection === 'horizontal') {
|
scaleX = scale;
|
} else {
|
scaleY = scale;
|
}
|
$el.find(`.${params.progressbarFillClass}`).transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed);
|
}
|
if (params.type === 'custom' && params.renderCustom) {
|
$el.html(params.renderCustom(swiper, current + 1, total));
|
swiper.emit('paginationRender', swiper, $el[0]);
|
} else {
|
swiper.emit('paginationUpdate', swiper, $el[0]);
|
}
|
$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);
|
},
|
render() {
|
// Render Container
|
const swiper = this;
|
const params = swiper.params.pagination;
|
if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
|
const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
|
|
const $el = swiper.pagination.$el;
|
let paginationHTML = '';
|
if (params.type === 'bullets') {
|
const numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
|
for (let i = 0; i < numberOfBullets; i += 1) {
|
if (params.renderBullet) {
|
paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
|
} else {
|
paginationHTML += `<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`;
|
}
|
}
|
$el.html(paginationHTML);
|
swiper.pagination.bullets = $el.find(`.${params.bulletClass}`);
|
}
|
if (params.type === 'fraction') {
|
if (params.renderFraction) {
|
paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
|
} else {
|
paginationHTML = `<span class="${params.currentClass}"></span>`
|
+ ' / '
|
+ `<span class="${params.totalClass}"></span>`;
|
}
|
$el.html(paginationHTML);
|
}
|
if (params.type === 'progressbar') {
|
if (params.renderProgressbar) {
|
paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
|
} else {
|
paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
|
}
|
$el.html(paginationHTML);
|
}
|
if (params.type !== 'custom') {
|
swiper.emit('paginationRender', swiper.pagination.$el[0]);
|
}
|
},
|
init() {
|
const swiper = this;
|
const params = swiper.params.pagination;
|
if (!params.el) return;
|
|
let $el = $(params.el);
|
if ($el.length === 0) return;
|
|
if (
|
swiper.params.uniqueNavElements
|
&& typeof params.el === 'string'
|
&& $el.length > 1
|
) {
|
$el = swiper.$el.find(params.el);
|
}
|
|
if (params.type === 'bullets' && params.clickable) {
|
$el.addClass(params.clickableClass);
|
}
|
|
$el.addClass(params.modifierClass + params.type);
|
|
if (params.type === 'bullets' && params.dynamicBullets) {
|
$el.addClass(`${params.modifierClass}${params.type}-dynamic`);
|
swiper.pagination.dynamicBulletIndex = 0;
|
if (params.dynamicMainBullets < 1) {
|
params.dynamicMainBullets = 1;
|
}
|
}
|
if (params.type === 'progressbar' && params.progressbarOpposite) {
|
$el.addClass(params.progressbarOppositeClass);
|
}
|
|
if (params.clickable) {
|
$el.on('click', `.${params.bulletClass}`, function onClick(e) {
|
e.preventDefault();
|
let index = $(this).index() * swiper.params.slidesPerGroup;
|
if (swiper.params.loop) index += swiper.loopedSlides;
|
swiper.slideTo(index);
|
});
|
}
|
|
Utils.extend(swiper.pagination, {
|
$el,
|
el: $el[0],
|
});
|
},
|
destroy() {
|
const swiper = this;
|
const params = swiper.params.pagination;
|
if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
|
const $el = swiper.pagination.$el;
|
|
$el.removeClass(params.hiddenClass);
|
$el.removeClass(params.modifierClass + params.type);
|
if (swiper.pagination.bullets) swiper.pagination.bullets.removeClass(params.bulletActiveClass);
|
if (params.clickable) {
|
$el.off('click', `.${params.bulletClass}`);
|
}
|
},
|
};
|
|
export default {
|
name: 'pagination',
|
params: {
|
pagination: {
|
el: null,
|
bulletElement: 'span',
|
clickable: false,
|
hideOnClick: false,
|
renderBullet: null,
|
renderProgressbar: null,
|
renderFraction: null,
|
renderCustom: null,
|
progressbarOpposite: false,
|
type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom'
|
dynamicBullets: false,
|
dynamicMainBullets: 1,
|
formatFractionCurrent: (number) => number,
|
formatFractionTotal: (number) => number,
|
bulletClass: 'swiper-pagination-bullet',
|
bulletActiveClass: 'swiper-pagination-bullet-active',
|
modifierClass: 'swiper-pagination-', // NEW
|
currentClass: 'swiper-pagination-current',
|
totalClass: 'swiper-pagination-total',
|
hiddenClass: 'swiper-pagination-hidden',
|
progressbarFillClass: 'swiper-pagination-progressbar-fill',
|
progressbarOppositeClass: 'swiper-pagination-progressbar-opposite',
|
clickableClass: 'swiper-pagination-clickable', // NEW
|
lockClass: 'swiper-pagination-lock',
|
},
|
},
|
create() {
|
const swiper = this;
|
Utils.extend(swiper, {
|
pagination: {
|
init: Pagination.init.bind(swiper),
|
render: Pagination.render.bind(swiper),
|
update: Pagination.update.bind(swiper),
|
destroy: Pagination.destroy.bind(swiper),
|
dynamicBulletIndex: 0,
|
},
|
});
|
},
|
on: {
|
init() {
|
const swiper = this;
|
swiper.pagination.init();
|
swiper.pagination.render();
|
swiper.pagination.update();
|
},
|
activeIndexChange() {
|
const swiper = this;
|
if (swiper.params.loop) {
|
swiper.pagination.update();
|
} else if (typeof swiper.snapIndex === 'undefined') {
|
swiper.pagination.update();
|
}
|
},
|
snapIndexChange() {
|
const swiper = this;
|
if (!swiper.params.loop) {
|
swiper.pagination.update();
|
}
|
},
|
slidesLengthChange() {
|
const swiper = this;
|
if (swiper.params.loop) {
|
swiper.pagination.render();
|
swiper.pagination.update();
|
}
|
},
|
snapGridLengthChange() {
|
const swiper = this;
|
if (!swiper.params.loop) {
|
swiper.pagination.render();
|
swiper.pagination.update();
|
}
|
},
|
destroy() {
|
const swiper = this;
|
swiper.pagination.destroy();
|
},
|
click(e) {
|
const swiper = this;
|
if (
|
swiper.params.pagination.el
|
&& swiper.params.pagination.hideOnClick
|
&& swiper.pagination.$el.length > 0
|
&& !$(e.target).hasClass(swiper.params.pagination.bulletClass)
|
) {
|
const isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass);
|
if (isHidden === true) {
|
swiper.emit('paginationShow', swiper);
|
} else {
|
swiper.emit('paginationHide', swiper);
|
}
|
swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass);
|
}
|
},
|
},
|
};
|