(function () { var grid = document.querySelector('[data-search-grid]'); if (!grid) return; var cards = Array.from(grid.querySelectorAll('.search-card')); var pagination = document.querySelector('[data-pagination]'); var pageNumbers = pagination.querySelector('[data-page-numbers]'); var previous = pagination.querySelector('[data-page-prev]'); var next = pagination.querySelector('[data-page-next]'); var results = document.querySelector('.search-results'); var page = pageFromURL(); function pageFromURL() { var match = window.location.pathname.match(/\/page\/(\d+)\/?$/); var value = match ? Number(match[1]) : 1; return Number.isInteger(value) && value > 0 ? value : 1; } function updateURL(replace) { var basePath = window.location.pathname.replace(/\/page\/\d+\/?$/, '').replace(/\/$/, ''); var path = basePath || '/search'; if (page > 1) path += '/page/' + String(page); if (path !== window.location.pathname) { window.history[replace ? 'replaceState' : 'pushState']({}, '', path); } } function pageTokens(total, mobile) { var tokens = []; var visibleEdge = mobile ? 3 : 5; var i; if (total <= visibleEdge + 2) { for (i = 1; i <= total; i++) tokens.push(i); } else if (page <= (mobile ? 2 : 3)) { for (i = 1; i <= visibleEdge; i++) tokens.push(i); tokens.push('ellipsis', total); } else if (page >= total - (mobile ? 1 : 2)) { tokens.push(1, 'ellipsis'); for (i = total - visibleEdge + 1; i <= total; i++) tokens.push(i); } else if (mobile) { tokens.push(1, 'ellipsis', page, 'ellipsis', total); } else { tokens.push(1, 'ellipsis', page - 1, page, page + 1, 'ellipsis', total); } return tokens; } function render() { var mobile = window.matchMedia('(max-width: 900px)').matches; var pageSize = mobile ? 9 : 12; var totalPages = Math.max(1, Math.ceil(cards.length / pageSize)); var start; if (page > totalPages) { page = totalPages; updateURL(true); } start = (page - 1) * pageSize; cards.forEach(function (card, index) { card.hidden = index < start || index >= start + pageSize; }); previous.disabled = page === 1; next.disabled = page === totalPages; pageNumbers.replaceChildren(); pageTokens(totalPages, mobile).forEach(function (token) { if (token === 'ellipsis') { var dots = document.createElement('span'); dots.className = 'search-pagination__ellipsis'; dots.textContent = '…'; dots.setAttribute('aria-hidden', 'true'); pageNumbers.appendChild(dots); return; } var button = document.createElement('button'); button.type = 'button'; button.textContent = String(token); button.setAttribute('aria-label', '第 ' + token + ' 页'); if (token === page) { button.className = 'is-current'; button.setAttribute('aria-current', 'page'); } button.addEventListener('click', function () { goToPage(token); }); pageNumbers.appendChild(button); }); } function goToPage(number) { var totalPages = Math.max(1, Math.ceil(cards.length / (window.matchMedia('(max-width: 900px)').matches ? 9 : 12))); if (number < 1 || number > totalPages || number === page) return; page = number; updateURL(false); render(); results.scrollIntoView({ block: 'start' }); } previous.addEventListener('click', function () { goToPage(page - 1); }); next.addEventListener('click', function () { goToPage(page + 1); }); window.addEventListener('popstate', function () { page = pageFromURL(); render(); }); window.addEventListener('resize', render); render(); })();