新增页码跳转;修复异常;优化效果

This commit is contained in:
2026-07-25 15:34:40 +08:00
parent 7d56858616
commit 711cff953b
7 changed files with 423 additions and 93 deletions
+145 -2
View File
@@ -1446,13 +1446,25 @@ a.close_local {
#pagination,
#p_pagination,
#prev_pagination {
padding: 30px;
padding: 18px 10px;
text-align: center;
display: flex;
justify-content: center;
border-top: 1px solid var(--pix-background);
}
#t_pagination .post-paging,
#pagination .post-paging,
#p_pagination .post-paging,
#prev_pagination .post-paging {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 15px;
width: 100%;
}
#t_pagination a,
#pagination a,
#p_pagination a,
@@ -1464,6 +1476,137 @@ a.close_local {
display: flex;
}
#t_pagination .page-jump-form,
#pagination .page-jump-form,
#p_pagination .page-jump-form {
display: inline-flex;
align-items: center;
gap: 4px;
color: #7aa1a1;
font-size: 15px;
line-height: 1;
}
#t_pagination .page-jump-input,
#pagination .page-jump-input,
#p_pagination .page-jump-input {
width: 48px;
height: 30px;
padding: 0 4px;
border: 1px solid var(--pix-background);
border-radius: 0;
background: #fff;
color: #55716a;
font-size: 15px;
line-height: 30px;
text-align: center;
box-sizing: border-box;
-moz-appearance: textfield;
}
#t_pagination .page-jump-input-wrap,
#pagination .page-jump-input-wrap,
#p_pagination .page-jump-input-wrap {
display: inline-flex;
height: 30px;
align-items: stretch;
flex: 0 0 auto;
}
#t_pagination .page-jump-step,
#pagination .page-jump-step,
#p_pagination .page-jump-step {
width: 18px;
height: 30px;
flex: 0 0 18px;
padding: 0;
border: 1px solid var(--pix-background);
border-radius: 0;
background: #e8f5ed;
color: var(--pix-theme);
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
line-height: 1;
font-family: inherit;
transition: background-color .2s ease, color .2s ease, opacity .2s ease;
}
#t_pagination .page-jump-step-down,
#pagination .page-jump-step-down,
#p_pagination .page-jump-step-down {
border-right: 0;
border-radius: 4px 0 0 4px;
}
#t_pagination .page-jump-step-up,
#pagination .page-jump-step-up,
#p_pagination .page-jump-step-up {
border-left: 0;
border-radius: 0 4px 4px 0;
}
#t_pagination .page-jump-step:hover:not(:disabled),
#pagination .page-jump-step:hover:not(:disabled),
#p_pagination .page-jump-step:hover:not(:disabled) {
background: var(--pix-theme);
color: #fff;
}
#t_pagination .page-jump-step:disabled,
#pagination .page-jump-step:disabled,
#p_pagination .page-jump-step:disabled {
opacity: .35;
cursor: not-allowed;
}
#t_pagination .page-jump-step i,
#pagination .page-jump-step i,
#p_pagination .page-jump-step i {
font-size: 12px;
}
#t_pagination .page-jump-input:focus,
#pagination .page-jump-input:focus,
#p_pagination .page-jump-input:focus {
border-color: var(--pix-theme);
}
#t_pagination .page-jump-input::-webkit-inner-spin-button,
#t_pagination .page-jump-input::-webkit-outer-spin-button,
#pagination .page-jump-input::-webkit-inner-spin-button,
#pagination .page-jump-input::-webkit-outer-spin-button,
#p_pagination .page-jump-input::-webkit-inner-spin-button,
#p_pagination .page-jump-input::-webkit-outer-spin-button {
margin: 0;
-webkit-appearance: none;
appearance: none;
}
#t_pagination .page-jump-submit,
#pagination .page-jump-submit,
#p_pagination .page-jump-submit {
width: 30px;
height: 30px;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
color: var(--pix-theme);
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-family: inherit;
}
#t_pagination .page-jump-submit i,
#pagination .page-jump-submit i,
#p_pagination .page-jump-submit i {
font-size: 20px;
}
#prev_pagination {
overflow: hidden;
max-height: 0;
@@ -5599,7 +5742,7 @@ a.m_loop {
width: 330px;
padding: 5px;
border-radius: 5px;
min-height: 450px;
max-height: 450px;
}
.poster_box .loading_box {
+184 -75
View File
@@ -60,6 +60,16 @@ function highlightMenu() {
}
})
}
// 高亮完成后再滚动,确保当前项在导航容器内可见并尽量居中。
const activeMenuLink = document.querySelector('.left_menu_box ul li.current-pjax-item a');
if (activeMenuLink && typeof activeMenuLink.scrollIntoView === 'function') {
activeMenuLink.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
});
}
}
function closeMomentPushModal() {
@@ -122,8 +132,16 @@ function syncPageParamToUrl(page) {
url.searchParams.delete('page');
}
const displayUrl = buildRelativeUrl(url);
const currentState = history.state && typeof history.state === 'object' ? history.state : {};
history.replaceState(Object.assign({}, currentState, { page: pageNumber }), '', buildRelativeUrl(url));
// PJAX uses history.state.url when restoring a popstate entry. Keep it in
// sync with the visible URL after AJAX pagination changes the current page.
history.replaceState(
Object.assign({}, currentState, { url: displayUrl, page: pageNumber }),
'',
displayUrl
);
}
function getPageNumberFromUrl(urlValue) {
@@ -268,6 +286,7 @@ function initPreviousPageButton(page) {
return;
}
// 有BUG:PJAX加载失败后可能会新增本不该存在的上一页按钮,不管了
if ((page === undefined || page === null) && $oldButton.length) {
return;
}
@@ -409,27 +428,34 @@ function updateLoadMorePagination(paginationSelector, insertAfterSelector, data,
newHref = $data.find(fallbackPaginationSelector + ' a').attr('data');
}
if (newHref !== undefined) {
const newPaginationHtml = $newPagination.length ? $newPagination.prop('outerHTML') : '';
let $pagination = $(paginationSelector);
const newPaginationHtml = $newPagination.length ? $newPagination.prop('outerHTML') : '';
let $pagination = $(paginationSelector);
if (newPaginationHtml) {
if ($pagination.length) {
$pagination.replaceWith(newPaginationHtml);
} else {
$(insertAfterSelector).last().after(newPaginationHtml);
}
if (newPaginationHtml) {
if ($pagination.length) {
$pagination.replaceWith(newPaginationHtml);
} else {
$(insertAfterSelector).last().after(newPaginationHtml);
}
$pagination = $(paginationSelector);
}
if (newHref !== undefined) {
const $paginationBtn = ensureLoadMoreButton(paginationSelector, insertAfterSelector);
$paginationBtn.attr('data', newHref).text(getLoadMoreText()).show();
$(paginationSelector).show();
$(paginationSelector + ' .post-paging').show();
} else if (newPaginationHtml) {
// 最后一页仍保留页码跳转控件,只隐藏不存在的下一页按钮。
$(paginationSelector + ' .post-paging > a').hide();
$(paginationSelector).show();
$(paginationSelector + ' .post-paging').show();
} else {
$(paginationSelector + ' a').hide();
$(paginationSelector).hide();
}
initPageJumpSteppers();
return newHref;
}
@@ -1176,7 +1202,12 @@ $(document).on('click', '.moment_cat_nav ul li a', function () {
url: cat,
headers: HTML_PAGE_AJAX_HEADERS,
beforeSend: function () {
showListLoading('.moment_list');
const $pagingArea = $('#t_pagination .post-paging');
if ($pagingArea.length) {
$pagingArea.html('<div uk-spinner></div>');
} else {
showListLoading('.moment_list');
}
},
success: function (data) {
setCategoryLinkActive($this);
@@ -1242,8 +1273,12 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () {
url: url,
headers: HTML_PAGE_AJAX_HEADERS,
beforeSend: function () {
// 显示加载动画
showListLoading('.moment_list');
const $pagingArea = $('#t_pagination .post-paging');
if ($pagingArea.length) {
$pagingArea.html('<div uk-spinner></div>');
} else {
showListLoading('.moment_list');
}
},
success: function (data) {
setCategoryLinkActive($this);
@@ -1319,7 +1354,7 @@ $(document).on('click', '#prev_pagination a', function () {
const listHeightAfterLoad = context.$list[0] ? context.$list[0].scrollHeight : listHeightBeforeLoad;
const heightDelta = Math.max(0, listHeightAfterLoad - listHeightBeforeLoad);
window.scrollTo(0, scrollTopBeforeLoad + heightDelta);
window.scrollTo(0, scrollTopBeforeLoad + heightDelta - 50);
$body.animate({ scrollTop: '-=100' }, 500);
},
error: function () {
@@ -1330,6 +1365,117 @@ $(document).on('click', '#prev_pagination a', function () {
return false;
});
function updatePageJumpStepperState(input) {
const value = Number(input.value);
const min = Number(input.min);
const max = Number(input.max);
const $stepper = $(input).closest('.page-jump-input-wrap');
$stepper.find('.page-jump-step-up').prop('disabled', Number.isFinite(value) && value >= max);
$stepper.find('.page-jump-step-down').prop('disabled', !Number.isFinite(value) || value <= min);
}
function validatePageJumpInput(input, notify) {
const value = input.value.trim();
const min = input.min === '' ? null : Number(input.min);
const max = input.max === '' ? null : Number(input.max);
const page = Number(value);
let message = '';
if (!value) {
message = '请输入页码';
} else if (!Number.isInteger(page)) {
message = '请输入有效页码';
} else if (Number.isFinite(min) && page < min) {
message = `页码不能小于 ${min}`;
} else if (Number.isFinite(max) && page > max) {
message = `页码不能大于 ${max}`;
}
const wasInvalid = input.dataset.pageJumpInvalid === 'true';
input.setCustomValidity(message);
input.dataset.pageJumpInvalid = message ? 'true' : 'false';
if (notify && message && message !== '请输入页码' && !wasInvalid
&& window.cocoMessage && typeof window.cocoMessage.warning === 'function') {
window.cocoMessage.warning(message);
}
return !message;
}
function stepPageJumpInput(input, direction) {
const min = Number(input.min);
const max = Number(input.max);
const step = Number(input.step) > 0 ? Number(input.step) : 1;
const current = Number(input.value);
const value = Number.isFinite(current) ? current + direction * step : min;
input.value = String(Math.min(max, Math.max(min, value)));
input.dispatchEvent(new Event('input', { bubbles: true }));
input.focus();
}
function initPageJumpSteppers() {
$('.page-jump-input').each(function () {
updatePageJumpStepperState(this);
});
}
$(document).on('click', '.page-jump-step', function (event) {
event.preventDefault();
if (this.disabled) return;
const input = $(this).closest('.page-jump-input-wrap').find('.page-jump-input')[0];
if (input) {
stepPageJumpInput(input, $(this).hasClass('page-jump-step-up') ? 1 : -1);
}
});
$(document).on('keydown', '.page-jump-input', function (event) {
if (event.ctrlKey || event.metaKey || event.altKey) return;
const allowedKeys = ['Backspace', 'Delete', 'Tab', 'Enter', 'Escape', 'ArrowLeft', 'ArrowRight', 'Home', 'End'];
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
event.preventDefault();
stepPageJumpInput(this, event.key === 'ArrowUp' ? 1 : -1);
return;
}
if (!allowedKeys.includes(event.key) && !/^[0-9]$/.test(event.key)) {
event.preventDefault();
}
});
$(document).on('input', '.page-jump-input', function () {
this.value = this.value.replace(/[^0-9]/g, '').replace(/^0+(?=\d)/, '');
validatePageJumpInput(this, true);
updatePageJumpStepperState(this);
});
// 跳转到指定页:沿用当前 URL 的分类或标签参数,通过 PJAX 加载目标页。
$(document).on('submit', '.page-jump-form', function (event) {
event.preventDefault();
const $form = $(this);
const input = $form.find('.page-jump-input')[0];
validatePageJumpInput(input, true);
if (!this.checkValidity()) {
input.focus();
if (typeof input.reportValidity === 'function') input.reportValidity();
return false;
}
const targetPage = parseInt($form.find('.page-jump-input').val(), 10);
const href = buildPageUrlFromCurrent(targetPage);
if (window.pjax && typeof window.pjax.loadUrl === 'function') {
window.pjax.loadUrl(href);
} else {
window.location.assign(href);
}
return false;
});
//ajax加载片刻
$(document).on('click', '#t_pagination a', function () {
var href = $(this).attr('data');
@@ -1347,21 +1493,15 @@ $(document).on('click', '#t_pagination a', function () {
success: function (posts) {
if (posts) {
var result = $(posts).find(".moment_list .p_item");
$('#t_pagination .post-paging').html(`<a>${Theme.site_page}</a>`);
$(".moment_list").append(result.fadeIn(300));
refreshAjaxPostList();
var newhref = $(posts).find("#t_pagination a").attr("data");
if (newhref != undefined) {
$("#t_pagination a").attr("data", newhref);
$('#t_pagination a').show();
} else {
$("#t_pagination a").hide();
updateLoadMorePagination('#t_pagination', '.moment_list', posts);
if (result.length) {
$body.animate({ scrollTop: result.first().offset().top - 58 }, 500);
}
$body.animate({ scrollTop: result.offset().top - 58 }, 500);
getMomentAudio();
initAgree();
lazyLoadInstance.update();
if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
initializeMomentFold();
syncPageParamToUrl(currentPage);
} else {
@@ -1413,8 +1553,12 @@ $(document).ready(function () {
url: url,
headers: HTML_PAGE_AJAX_HEADERS,
beforeSend: function () {
showListLoading("#photos_item", PHOTO_LIST_LOADING_HTML);
$('#p_pagination').hide();
const $pagingArea = $('#p_pagination .post-paging');
if ($pagingArea.length) {
$pagingArea.html('<div uk-spinner></div>');
} else {
showListLoading("#photos_item", PHOTO_LIST_LOADING_HTML);
}
},
success: function (data) {
setCategoryLinkActive($this);
@@ -1466,15 +1610,8 @@ $(document).on('click', '#p_pagination a', function () {
success: function (photos) {
if (photos) {
var result = $(photos).find(".norpost_list .gallery-photo");
$('#p_pagination .post-paging').html(`<a>${Theme.site_page}</a>`);
$(".gallery-photos").append(result.fadeIn(300));
var newhref = $(photos).find("#p_pagination a").attr("data"); //找出新的下一页链接
if (newhref != undefined) {
$("#p_pagination a").attr("data", newhref);
$('#p_pagination a').show();
} else {
$("#p_pagination a").hide(); //如果没有下一页了,隐藏
}
updateLoadMorePagination('#p_pagination', '#photos_item', photos);
$body.animate({ scrollTop: targetOffsetTop - 358 }, 500);
pix.initGalleryPhotos();
if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
@@ -1675,7 +1812,12 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) {
url: cat, // 完全保留原有请求URL,不修改
headers: HTML_PAGE_AJAX_HEADERS,
beforeSend: function () {
showListLoading('.norpost_list');
const $pagingArea = $('#pagination .post-paging');
if ($pagingArea.length) {
$pagingArea.html('<div uk-spinner></div>');
} else {
showListLoading('.norpost_list');
}
},
success: function (data) {
setCategoryLinkActive($this);
@@ -1716,22 +1858,15 @@ $('body').on('click', '#pagination a', function () {
success: function (data) {
if (data) {
var result = $(data).find(".norpost_list ").children();
$('#pagination .post-paging').html(`<a>${Theme.site_page}</a>`);
$('.norpost_list').append($(result).fadeIn(400));
refreshAjaxPostList();
var newhref = $(data).find("#pagination a").attr("data") || $(data).find(".arc_pagenav a").attr("data"); //找出新的下一页链接
if (newhref != undefined) {
$("#pagination a").attr("data", newhref);
$('#pagination a').show();
} else {
$("#pagination a").hide(); //如果没有下一页了,隐藏
updateLoadMorePagination('#pagination', '.norpost_list', data, '.arc_pagenav');
if (result.length) {
$body.animate({ scrollTop: result.first().offset().top - 58 }, 500);
}
$body.animate({ scrollTop: result.offset().top - 58 }, 500);
initAgree()
lazyLoadInstance.update();
if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
syncPageParamToUrl(currentPage);
} else {
$("#pagination a").hide();
@@ -1993,12 +2128,6 @@ if (Theme.pjax) {
cacheBust: false,
});
let isPopNav = false;
// 监听popstate(用户点浏览器前进、后退按钮)
window.addEventListener('popstate', function () {
isPopNav = true;
});
document.addEventListener('pjax:send', function () {
NProgress.start();
})
@@ -2009,19 +2138,10 @@ if (Theme.pjax) {
typeof Prism === 'object' && Prism.highlightAll();
autoload_posts_music();
initBlog();
initPageJumpSteppers();
refreshCommentWidget();
NProgress.done();
if (isPopNav) {
// 用户点击前进后退:删除page参数
isPopNav = false;
const cleanUrl = removePageParamFromUrl(window.location.href);
if (cleanUrl !== window.location.pathname + window.location.search + window.location.hash) {
history.replaceState(history.state || {}, '', cleanUrl);
}
} else {
// 用户点击链接
initPreviousPageButton()
}
initPreviousPageButton()
})
}
@@ -2108,18 +2228,6 @@ $(document).scroll(function () {
});
// 获取当前具有 "current" 类的元素
var currentElement = document.querySelector('.current');
// 检查是否找到了具有 "current" 类的元素
if (currentElement) {
// 将当前元素滚动到视图中
currentElement.scrollIntoView({
behavior: 'smooth', // 平滑滚动
block: 'start' // 将当前元素顶部对齐到视口顶部
});
}
$('body').on('click', '.listree-btn', function (event) {
event.preventDefault();
setListreeOpen(!$('.listree-box').hasClass('is-open'));
@@ -3131,6 +3239,7 @@ function initBlog() {
$(document).ready(function () {
pix.roleMoments();
initBlog();
initPageJumpSteppers();
initPreviousPageButton()
setPageGrayscale();