Код:
<style>
.castom-pagination__wrapper {
width: 100%;
max-width: 526px;
display: flex;
align-items: center;
justify-content: end;
padding: 14px 1px 5px 14px;
}
.castom-paginations {
display: flex;
align-items: center;
gap: 5px;
z-index: 100;
}
.castom-paginations__button-prev {
font-size: 14px;
font-weight: 500;
border: none;
border-radius: 2px;
padding: 3px 5px;
background-color: #d9d9d9;
opacity: 0.98;
z-index: 100;
-webkit-box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
-moz-box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
cursor: pointer;
transition: all 0.3s;
}
.castom-paginations__button-next {
font-size: 14px;
font-weight: 500;
border: none;
border-radius: 2px;
padding: 3px 5px;
background-color: #d9d9d9;
opacity: 0.98;
z-index: 100;
-webkit-box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
-moz-box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
cursor: pointer;
transition: all 0.3s;
}
.castom-paginations__button-prev:active {
background-color: #5081e5;
-webkit-box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
-moz-box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
}
.castom-paginations__button-next:active {
background-color: #5081e5;
-webkit-box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
-moz-box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
}
.castom-paginations__list {
display: flex;
list-style-type: none;
gap: 5px;
margin: 0;
padding: 0;
}
.castom-paginations__list-item {
z-index: 100;
display: flex;
}
.castom-paginations__list-button-page {
font-size: 14px;
font-weight: 500;
color: black;
border: none;
border-radius: 2px;
cursor: pointer;
padding: 3px 5px;
background-color: #d9d9d9;
opacity: 0.98;
z-index: 100;
-webkit-box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
-moz-box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
box-shadow: 0px 5px 10px 2px rgba(34, 60, 80, 0.2);
}
.castom-paginations__list-button-page:hover {
opacity: 0.7;
}
.castom-paginations__list-button-page--active {
background-color: #5081e5;
color: #fff;
-webkit-box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
-moz-box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
box-shadow: 5px 5px 5px -5px rgba(34, 60, 80, 0.6) inset;
}
.castom-paginations__list-item--hide {
display: none;
width: 0;
}
.castom-paginations__list-item--one-page::after {
content: '...';
text-align: center;
display: flex;
align-items: center;
padding: 0 5px 0 5px;
}
.castom-paginations__list-item--end-page::before {
content: '...';
text-align: center;
display: flex;
align-items: end;
padding: 0 5px 0 0;
}
@media(max-width:768px) {
.castom-paginations__list-button-page {
font-size: 16px;
}
}
</style>
- Пагинация JS
Код:
<script>
function createClassPagination(propsForPagination) {
class Pagination {
constructor(props) {
this.props = props
}
addCastomSelectorStyleMod() {
// кастомные стили к пагинации тегу nav
this.castomSelectorPagination =
this.pagination.classList[0] + '--' + this.props.castomSelectorMod
this.pagination.classList.add(this.castomSelectorPagination)
// кастомный селектор к тегу ul
this.castomSelectorListPages =
this.paginationListPages.classList[0] + '--' + this.props.castomSelectorMod
this.paginationListPages.classList.add(this.castomSelectorListPages)
// кастомный селектор к тегам li
if (this.listItemsAll[0]) {
this.castomSelectorListItem =
this.listItemsAll[0].classList[0] + '--' + this.props.castomSelectorMod
this.listItemsAll.forEach((item) => {
item.classList.add(this.castomSelectorListItem)
})
}
// кастомный селектор к тегам button
if (this.buttonsAll[0]) {
this.castomSelectorButton =
this.buttonsAll[0].classList[0] + '--' + this.props.castomSelectorMod
this.buttonsAll.forEach((button) => {
button.classList.add(this.castomSelectorButton)
})
}
}
// метод отрисовывает пагинацию
init() {
if (!this.props.countPages || this.props.countPages === 0 || !this.props.selectorForWrapper)
return
if (!this.props.range || this.props.range === 0 || this.props.range < 3) {
this.props.range = 5
}
this.pagination = document.createElement('nav')
this.pagination.classList.add('castom-paginations')
this.paginationListPages = document.createElement('ul')
this.paginationListPages.classList.add('castom-paginations__list')
this.pagination.append(this.paginationListPages)
this.renderPages()
this.wrapper = document.querySelector('.' + this.props.selectorForWrapper)
this.wrapper.append(this.pagination)
// инициализируем listItemsAll для дальнейшего использования в методах класса
this.listItemsAll = Array.from(
this.pagination.querySelectorAll('.castom-paginations__list-item')
)
// инициализируем buttonAll для дальнейшего использования в методах класса
this.buttonsAll = this.pagination.querySelectorAll('.castom-paginations__list-button-page')
this.handlers()
this.nextRanderPages()
if (this.props.castomSelectorMod) {
this.addCastomSelectorStyleMod()
}
}
// метод рендерит страницы при инициализации(используется в init)
renderPages() {
for (let i = 1; i <= this.props.countPages; i++) {
this.listItem = document.createElement('li')
this.listItem.classList.add('castom-paginations__list-item')
this.buttonPage = document.createElement('button')
this.buttonPage.setAttribute('data-index', i) // присваиваем data атрибут для определения страниц
this.buttonPage.classList.add('castom-paginations__list-button-page')
if (this.props.startPage && this.props.startPage === i) {
this.buttonPage.classList.add('castom-paginations__list-button-page--active')
}
if (i > this.props.range && i !== this.props.countPages) {
this.listItem.classList.add('castom-paginations__list-item--hide')
}
if (i === this.props.countPages && this.props.countPages > 5) {
this.listItem.classList.add('castom-paginations__list-item--end-page')
}
this.buttonPage.type = 'button'
this.buttonPage.textContent = i
this.listItem.append(this.buttonPage)
this.paginationListPages.append(this.listItem)
}
}
// метод сбрасывает на 1 страницу
reset() {
this.wrapper.textContent = ''
this.props.startPage = 1
this.init()
}
//метод очищает страницы пагинации
removeRenderPages() {
this.listItemsAll.forEach((item, idx) => {
if (idx !== 0 && idx !== this.props.countPages - 1)
item.classList.add('castom-paginations__list-item--hide')
})
}
// метод рендерит страницу при клике на соответстующий номер
nextRanderPages() {
if (this.props.countPages < 2) return
// Ecли клик по странице с индексом меньше, чем колличество отображемых страниц
if (this.props.startPage < this.props.range) {
this.removeRenderPages()
this.listItemsAll.forEach((item, idx) => {
if (idx <= this.props.range - 1) {
item.classList.remove('castom-paginations__list-item--hide')
}
})
this.listItemsAll[0].classList.remove('castom-paginations__list-item--one-page')
if (this.props.countPages > 5) {
this.listItemsAll[this.props.countPages - 1].classList.add(
'castom-paginations__list-item--end-page'
)
}
return
}
// Ecли клик по последней странице или меньше последней, но болше чем кол-во страниц минус кол-во отображаемых страниц
if (
this.props.startPage <= this.props.countPages &&
this.props.startPage > this.props.countPages - this.props.range &&
this.props.startPage !== this.props.countPages - this.props.range + 1
) {
this.removeRenderPages()
this.listItemsAll.forEach((item, idx) => {
if (idx < this.props.countPages && idx > this.props.countPages - this.props.range - 1) {
item.classList.remove('castom-paginations__list-item--hide')
}
})
this.listItemsAll[this.props.countPages - 1].classList.remove(
'castom-paginations__list-item--end-page'
)
if (this.props.countPages > 5) {
this.listItemsAll[0].classList.add('castom-paginations__list-item--one-page')
}
return
}
// В остальных случаях при клике на страницу
this.removeRenderPages()
// добавить многоточие после первой и перед последней страницей
if (this.props.countPages > 5) {
this.listItemsAll[0].classList.add('castom-paginations__list-item--one-page')
this.listItemsAll[this.props.countPages - 1].classList.add(
'castom-paginations__list-item--end-page'
)
}
for (let i = this.props.startPage; i > this.props.startPage - this.props.range / 2 - 1; i--) {
this.listItemsAll[i].classList.remove('castom-paginations__list-item--hide')
}
for (let i = this.props.startPage; i < this.props.startPage + this.props.range / 2 - 1; i++) {
this.listItemsAll[i].classList.remove('castom-paginations__list-item--hide')
}
}
handlers() {
this.pagination.addEventListener('click', (e) => {
if (e.target.closest('.castom-paginations__list-button-page')) {
this.buttonsAll.forEach((page) => {
if (page.closest('.castom-paginations__list-button-page--active')) {
page.classList.remove('castom-paginations__list-button-page--active')
}
})
e.target.classList.add('castom-paginations__list-button-page--active')
this.props.startPage = +e.target.dataset.index
this.nextRanderPages() // перерисовывает пагинацию относительно выбранной страницы
this.props.callback(this.props.startPage) // вызываем callback переданный из пропсов (должен принимать номер страницы)
}
})
}
}
return new Pagination(propsForPagination)
}
function insertPagination(quantityPages,call) {
if (!quantityPages || quantityPages === 0 || isNaN(quantityPages)) return
const propsForPagination = {
selectorForWrapper: 'castom-pagination__wrapper',
countPages: quantityPages, // кол-во страниц
range: 5, // сколько страниц отображать
startPage: 1, // номер активной страницы
callback: call, // callback function принимает номер страницы по которой выполнен click
}
const pagination = createClassPagination(propsForPagination)
pagination.init()
}
function clearPagination () {
document.querySelector('.castom-pagination__wrapper').textContent = ''
}
</script>
- ВКод Отрисовать пагинацию