diff --git a/README.md b/README.md index 54d1a70..c661477 100755 --- a/README.md +++ b/README.md @@ -2,18 +2,21 @@ > 基于原作者v1.2.5代码修改 -#### v1.2.5-7补丁 +#### v1.2.5-8 1. 重写作文目录、置顶样式 2. 更换(通知书等)域名 3. 修复搜索结果无法PJAX跳转(依赖搜索插件v1.7.1-1) 4. 修复日记过多时无法搜索(依赖瞬间插件v1.13.1-1,基于源仓库) -5. 朋友圈内容支持搜索与跳转(依赖朋友圈插件v1.4.3-5) +5. 朋友圈内容支持搜索与跳转;大幅优化性能(依赖朋友圈插件v1.4.3-6) 6. 压缩、更换图片 7. 模板端全面支持page与tag参数(常驻显示,同步新增向上翻阅功能) 8. 取消自动恢复源内容功能 9. 前台编辑、发布日记将采用PJAX更新 10. 手机端播放器新增进度条 -11. 清除无效代码 +11. 抽象重复代码至函数、清理无效代码 +12. 当前激活的标签将在导航栏中居中显示 +13. 优化不同宽度下的显示效果 +14. 重构分享海报布局 #### v1.2.5-7 1. 适配新接口(基于新版API-Python) diff --git a/templates/assets/css/main.css b/templates/assets/css/main.css index c3bd921..717eac1 100644 --- a/templates/assets/css/main.css +++ b/templates/assets/css/main.css @@ -5599,7 +5599,7 @@ a.m_loop { width: 330px; padding: 5px; border-radius: 5px; - min-height: 550px; + min-height: 450px; } .poster_box .loading_box { diff --git a/templates/assets/css/mobile.css b/templates/assets/css/mobile.css index fda1e9a..735ed13 100644 --- a/templates/assets/css/mobile.css +++ b/templates/assets/css/mobile.css @@ -218,7 +218,7 @@ /** * 小屏平板 (<= 960px) - * 保持原样 + * 540-960px 增加手机端底部导航 */ @media only screen and (max-width:960px) { @@ -276,6 +276,35 @@ .top_menu_box { border-radius: 8px; } + + /* 540-960px 也显示手机端底部导航,但不显示发布按钮 */ + .footer_menu { + display: block; + } + + .footer_nav_box { + top: 56px; + z-index: -1; + } + + .footer_nav_box .footer_player { + min-height: auto; + } + + body.mod_third_s .footer_nav_box .right { + width: 100%; + } + + .footer_main { + position: relative; + padding-bottom: 110px; + } + + .footer_menu a.playing-music, + .footer_menu a.playing-music i, + .footer_menu a.playing-music .title { + color: #4CAF50; + } } /** diff --git a/templates/assets/js/anian.js b/templates/assets/js/anian.js index 37da05e..ff2f741 100644 --- a/templates/assets/js/anian.js +++ b/templates/assets/js/anian.js @@ -595,6 +595,9 @@ function init_douban_page() { requestList(1, state.type, false, { onSuccess: function () { $this.addClass('active').parent().siblings().children('.cat-link').removeClass('active'); + if (window.pix && typeof pix.centerCategoryNavActive === 'function') { + pix.centerCategoryNavActive($this); + } var currentUrl = new URL(window.location.href); if (!targetTag || targetTag === '全部') { @@ -653,12 +656,18 @@ function init_douban_page() { }).first(); if ($matchedTag.length > 0) { $matchedTag.addClass('active').parent().siblings().children('.cat-link').removeClass('active'); + if (window.pix && typeof pix.centerCategoryNavActive === 'function') { + pix.centerCategoryNavActive($matchedTag); + } state.type = $matchedTag.attr('data-type') || ''; } else { state.type = $('.douban_cat_nav .cat-link.active').attr('data-type') || ''; } } else { state.type = $('.douban_cat_nav .cat-link.active').attr('data-type') || ''; + if (window.pix && typeof pix.centerCategoryNavActive === 'function') { + pix.centerCategoryNavActive($('.douban_cat_nav .cat-link.active').first()); + } } } diff --git a/templates/assets/js/app.js b/templates/assets/js/app.js index e024fc3..5dab993 100644 --- a/templates/assets/js/app.js +++ b/templates/assets/js/app.js @@ -1,5 +1,10 @@ var $body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body'); var storage = window.localStorage; +const HTML_PAGE_AJAX_HEADERS = { + Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" +}; +const DEFAULT_LIST_LOADING_HTML = '
'; +const PHOTO_LIST_LOADING_HTML = '
'; var lazyLoadInstance = new LazyLoad({}); @@ -57,23 +62,6 @@ function highlightMenu() { } } - -//全局loading -function loading_template() { - tag = '
'; - tag += ''; - - return tag; -} - -function loading_start(target) { - target.append(loading_template()); -} - -function loading_done(target) { - target.children('.loader').remove(); -} - function closeMomentPushModal() { const modal = document.getElementById('create_post_box'); if (!modal || !window.UIkit || typeof UIkit.modal !== 'function') return; @@ -225,12 +213,16 @@ function getPreviousPageContext() { return $(data).find('.moment_list .p_item'); }, insert: function ($items) { - this.$list.prepend($items.hide().fadeIn(300)); + const $previousButton = this.$list.children('#prev_pagination').first(); + if ($previousButton.length) { + $previousButton.after($items.hide().fadeIn(300)); + } else { + this.$list.prepend($items.hide().fadeIn(300)); + } return $items.last(); }, afterLoad: function () { - const postListElement = document.getElementById("post_item"); - window.pjax && window.pjax.refresh(postListElement); + refreshAjaxPostList(); getMomentAudio(); initAgree(); if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update(); @@ -248,12 +240,16 @@ function getPreviousPageContext() { return $(data).find('.norpost_list').children(); }, insert: function ($items) { - this.$list.prepend($items.hide().fadeIn(400)); + const $previousButton = this.$list.children('#prev_pagination').first(); + if ($previousButton.length) { + $previousButton.after($items.hide().fadeIn(400)); + } else { + this.$list.prepend($items.hide().fadeIn(400)); + } return $items.last(); }, afterLoad: function () { - const postListElement = document.getElementById("post_item"); - window.pjax && window.pjax.refresh(postListElement); + refreshAjaxPostList(); initAgree(); if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update(); } @@ -263,32 +259,42 @@ function getPreviousPageContext() { return null; } -function initPreviousPageButton() { - const currentPage = getPageNumberFromUrl(window.location.href); +function initPreviousPageButton(page) { const context = getPreviousPageContext(); const $oldButton = $('#prev_pagination'); - if (!context || currentPage <= 1) { + if (!context) { + $oldButton.remove(); + return; + } + + if ((page === undefined || page === null) && $oldButton.length) { + return; + } + + const previousPage = page !== undefined && page !== null + ? parseInt(page, 10) + : getPageNumberFromUrl(window.location.href) - 1; + + if (!previousPage || previousPage < 1) { $oldButton.remove(); return; } - const previousPage = currentPage - 1; const previousUrl = buildPageUrlFromCurrent(previousPage); const buttonText = (window.Theme && Theme.prev_page) ? Theme.prev_page : '翻阅更多'; if ($oldButton.length) { + $oldButton.addClass('uk-width-1-1'); $oldButton.find('a').attr('data', previousUrl).attr('data-page', previousPage).text(buttonText).show(); - if (!$oldButton.next().is(context.$list)) { - context.$list.before($oldButton); - } + context.$list.prepend($oldButton); animatePreviousPageButton($oldButton); return; } const $button = $('
', { id: 'prev_pagination', - class: 'prev-pagination' + class: 'prev-pagination uk-width-1-1' }); const $paging = $('
', { class: 'post-paging' }); const $link = $('', { @@ -297,16 +303,61 @@ function initPreviousPageButton() { }).attr('data', previousUrl).attr('data-page', previousPage); $button.append($paging.append($link)); - context.$list.before($button); + context.$list.prepend($button); animatePreviousPageButton($button); } -function restorePreviousPageState($list, oldListHtml, oldButtonHtml) { - $list.html(oldListHtml); - if ($('#prev_pagination').length) { - $('#prev_pagination').replaceWith(oldButtonHtml); - } else if (oldButtonHtml) { - $list.before(oldButtonHtml); +function createAjaxPageSnapshot(options) { + options = options || {}; + const $content = options.$content || (options.contentSelector ? $(options.contentSelector) : $()); + const $pagination = options.$pagination || (options.paginationSelector ? $(options.paginationSelector) : $()); + const $pagingArea = options.$pagingArea || (options.pagingAreaSelector ? $(options.pagingAreaSelector) : $()); + + return { + $content: $content, + contentHtml: $content.length ? $content.html() : '', + paginationSelector: options.paginationSelector, + paginationHtml: $pagination.length ? $pagination.prop('outerHTML') : '', + paginationInsert: options.paginationInsert || 'after', + $paginationAnchor: options.$paginationAnchor || $content, + $pagingArea: $pagingArea, + pagingHtml: $pagingArea.length ? $pagingArea.html() : '' + }; +} + +function restoreAjaxPageSnapshot(snapshot, options) { + if (!snapshot) return; + + options = options || {}; + const restoreContent = options.content !== false; + const restorePagination = options.pagination !== false; + const restorePaging = options.paging === true; + + if (restoreContent && snapshot.$content && snapshot.$content.length) { + snapshot.$content.html(snapshot.contentHtml); + } + + if (restorePagination && snapshot.paginationSelector) { + const $currentPagination = $(snapshot.paginationSelector); + if (snapshot.paginationHtml) { + if ($currentPagination.length) { + $currentPagination.replaceWith(snapshot.paginationHtml); + } else if (snapshot.$paginationAnchor && snapshot.$paginationAnchor.length) { + if (snapshot.paginationInsert === 'before') { + snapshot.$paginationAnchor.before(snapshot.paginationHtml); + } else if (snapshot.paginationInsert === 'prepend') { + snapshot.$paginationAnchor.prepend(snapshot.paginationHtml); + } else { + snapshot.$paginationAnchor.after(snapshot.paginationHtml); + } + } + } else if ($currentPagination.length) { + $currentPagination.remove(); + } + } + + if (restorePaging && snapshot.$pagingArea && snapshot.$pagingArea.length) { + snapshot.$pagingArea.html(snapshot.pagingHtml); } } @@ -321,6 +372,141 @@ function animatePreviousPageButton($button) { }); } +function getLoadMoreText() { + return (window.Theme && Theme.site_page) ? Theme.site_page : '翻阅更多'; +} + +function ensureLoadMoreButton(paginationSelector, insertAfterSelector) { + let $pagination = $(paginationSelector); + + if (!$pagination.length) { + const paginationId = paginationSelector.charAt(0) === '#' ? paginationSelector.slice(1) : ''; + $pagination = $('
', paginationId ? { id: paginationId } : {}); + $(insertAfterSelector).last().after($pagination); + } + + let $postPaging = $pagination.find('.post-paging').first(); + if (!$postPaging.length) { + $postPaging = $('
', { class: 'post-paging' }); + $pagination.empty().append($postPaging); + } + + let $button = $postPaging.find('a').first(); + if (!$button.length) { + $button = $(''); + $postPaging.empty().append($button); + } + + return $button; +} + +function updateLoadMorePagination(paginationSelector, insertAfterSelector, data, fallbackPaginationSelector) { + const $data = $(data); + const $newPagination = $data.find(paginationSelector).first(); + let newHref = $newPagination.find('a').attr('data'); + + if (newHref === undefined && fallbackPaginationSelector) { + newHref = $data.find(fallbackPaginationSelector + ' a').attr('data'); + } + + if (newHref !== undefined) { + const newPaginationHtml = $newPagination.length ? $newPagination.prop('outerHTML') : ''; + let $pagination = $(paginationSelector); + + if (newPaginationHtml) { + if ($pagination.length) { + $pagination.replaceWith(newPaginationHtml); + } else { + $(insertAfterSelector).last().after(newPaginationHtml); + } + } + + const $paginationBtn = ensureLoadMoreButton(paginationSelector, insertAfterSelector); + $paginationBtn.attr('data', newHref).text(getLoadMoreText()).show(); + $(paginationSelector).show(); + $(paginationSelector + ' .post-paging').show(); + } else { + $(paginationSelector + ' a').hide(); + $(paginationSelector).hide(); + } + + return newHref; +} + +function showListLoading(selector, loadingHtml) { + $(selector).html(loadingHtml || DEFAULT_LIST_LOADING_HTML); +} + +function setCategoryLinkActive($link, childSelector) { + $link.addClass('active').parent().siblings().children(childSelector || 'a').removeClass('active'); + if (window.pix && typeof pix.centerCategoryNavActive === 'function') { + pix.centerCategoryNavActive($link); + } +} + +function cacheCommentFormForAjax() { + var temp = $("#comment_form_reset"); + var formHtml = $("#t_commentform").prop('outerHTML'); + temp.html(formHtml); +} + +function refreshAjaxPostList() { + const postListElement = document.getElementById("post_item"); + window.pjax && window.pjax.refresh(postListElement); +} + +function restoreAjaxSnapshotWithError(pageSnapshot, restoreOptions, message) { + restoreAjaxPageSnapshot(pageSnapshot, restoreOptions); + cocoMessage.error(message || '内容获取失败'); +} + +function restorePagingSnapshotWithError(pageSnapshot, message) { + restoreAjaxSnapshotWithError(pageSnapshot, { content: false, pagination: false, paging: true }, message); +} + +function buildMediaLibraryUrl(page) { + return `/apis/${Theme.moments.attachments_api}/v1alpha1/attachments?group=&page=${page}&size=10&ungrouped=false&accepts=image/*&accepts=video/*`; +} + +function buildMediaLibraryItem(value) { + var src = value.status.permalink; + var mediaType = value.spec.mediaType || ''; + + if (mediaType.startsWith('video/')) { + return `
  • + +
  • `; + } + + return `
  • + +
  • `; +} + +function renderMediaLibraryList(data) { + $(".wp_get_media_list").empty(); + $.each(data.items || [], function (i, value) { + $(".wp_get_media_list").append(buildMediaLibraryItem(value)); + }); +} + +function updateMediaLibraryPagination(page, totalPages) { + $(".attch_nav .nex").toggle(totalPages > page); + $(".attch_nav .pre").toggle(page > 1); +} + +function loadMediaLibraryPage(page) { + $.ajax({ + type: "get", + url: buildMediaLibraryUrl(page), + contentType: "application/json", + success: function (data) { + renderMediaLibraryList(data); + updateMediaLibraryPagination(page, data.totalPages); + } + }); +} + //话题表情添加 $(document).on('click', 'a.smile_btn', function () { @@ -486,34 +672,7 @@ $(document).on('click', '.up_from_media a', function () { $(".attch_nav").attr('paged', '1'); $(".wp_get_media_list").empty(); $(".show_media_box").show(); - $.ajax({ - type: "get", - url: `/apis/${Theme.moments.attachments_api}/v1alpha1/attachments?group=&page=1&size=10&ungrouped=false&accepts=image/*&accepts=video/*`, - contentType: "application/json", - beforeSend: function () { }, - success: function (data) { - var list = data.items; - $.each(list, function (i, value) { - var thum = value.status.permalink; - var src = value.status.permalink; - var mediaType = value.spec.mediaType || ''; - var wf_media = ''; - - if (mediaType.startsWith('video/')) { - wf_media = `
  • - -
  • `; - } else { - wf_media = `
  • - -
  • `; - } - $(".wp_get_media_list").append(wf_media); - }); - var max = data.totalPages; - $(".attch_nav .nex").toggle(max > 1); - } - }); + loadMediaLibraryPage(1); }); //媒体库分页(功能不变) @@ -529,37 +688,7 @@ $(document).on('click', '.attch_nav a', function () { } $(".attch_nav").attr('paged', paged); - $.ajax({ - type: "get", - url: `/apis/${Theme.moments.attachments_api}/v1alpha1/attachments?group=&page=${paged}&size=10&ungrouped=false&accepts=image/*&accepts=video/*`, - contentType: "application/json", - beforeSend: function () { }, - success: function (data) { - $(".wp_get_media_list").empty(); - var list = data.items; - $.each(list, function (i, value) { - var thum = value.status.permalink; - var src = value.status.permalink; - var mediaType = value.spec.mediaType; - var wf_media = ''; - - if (mediaType.startsWith('video/')) { - wf_media = `
  • - -
  • `; - } else { - wf_media = `
  • - -
  • `; - } - $(".wp_get_media_list").append(wf_media); - }); - - var max = data.totalPages; - $(".attch_nav .nex").toggle(max > paged); - $(".attch_nav .pre").toggle(paged > 1); - } - }); + loadMediaLibraryPage(paged); }); //收起媒体库(无修改) @@ -829,7 +958,6 @@ $(document).on('click', '.push_item', function () { success() { closeLoading?.() cocoMessage.success('发布成功!'); - const currentScrollTop = window.scrollY || document.documentElement.scrollTop; release(); closeMomentPushModal(); reloadCurrentPageByPjax('create'); @@ -884,7 +1012,6 @@ $(document).on('click', '.push_item', function () { success() { closeLoading?.() cocoMessage.success('更新成功!'); - const currentScrollTop = window.scrollY || document.documentElement.scrollTop; release(); closeMomentPushModal(); reloadCurrentPageByPjax('update'); @@ -1030,14 +1157,14 @@ $(document).on('click', '.moment_cat_nav ul li a', function () { } $('.moment_cat_nav ul li a').addClass('disabled'); - var temp = $("#comment_form_reset"); - var formHtml = $("#t_commentform").prop('outerHTML'); - temp.html(formHtml); + cacheCommentFormForAjax(); // --- 1. 保存旧内容--- var $momentList = $(".moment_list"); - var oldContent = $momentList.html(); - var oldPagination = $('#t_pagination').prop('outerHTML'); + var pageSnapshot = createAjaxPageSnapshot({ + $content: $momentList, + paginationSelector: '#t_pagination' + }); $(".moment_list").empty(); $('#t_pagination a').hide(); @@ -1047,31 +1174,17 @@ $(document).on('click', '.moment_cat_nav ul li a', function () { $.ajax({ type: "GET", url: cat, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - $('.moment_list').html('
    '); + showListLoading('.moment_list'); }, success: function (data) { - $this.addClass('active').parent().siblings().children().removeClass('active'); + setCategoryLinkActive($this); $('.moment_list .loading_box').remove(); var result = $(data).find(".moment_list .p_item"); $(".moment_list").append(result.fadeIn(300)); - var $newPagination = $(data).find("#t_pagination"); - var newHref = $newPagination.find("a").attr("data"); - - // 检查当前页面是否有分页容器,如果没有则补齐 - if ($('#t_pagination').length === 0 && $newPagination.length > 0) { - $(".moment_list").after($newPagination.prop('outerHTML')); - } - - var $paginationBtn = $('#t_pagination a'); - - if (newHref === undefined) { - $paginationBtn.hide(); - } else { - $paginationBtn.attr("data", newHref).text(Theme.site_page).show(); - $('#t_pagination').show(); - } + updateLoadMorePagination('#t_pagination', '.moment_list', data); getMomentAudio(); initAgree(); if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update(); @@ -1080,31 +1193,14 @@ $(document).on('click', '.moment_cat_nav ul li a', function () { // if (typeof modify_moment_video_size === 'function') modify_moment_video_size(); if (cat.indexOf('tag=') !== -1) { const displayUrl = removePageParamFromUrl(cat); - history.pushState({ url: displayUrl }, '', displayUrl); + history.replaceState({ url: displayUrl }, '', displayUrl); } else { - history.pushState({ url: cat }, '', '/'); - } - initPreviousPageButton(); - if (window._tagSwitchCallback) { - window._tagSwitchCallback.resolve(); // 标记成功 - window._tagSwitchCallback = null; // 清理临时变量 + history.replaceState({ url: cat }, '', '/'); } }, error: function () { $('.moment_cat_nav ul li a').removeClass('disabled'); - cocoMessage.error('内容获取失败'); - $('.moment_list .loading_box').remove(); - // 恢复列表内容 - $momentList.html(oldContent); - if ($('#t_pagination').length > 0) { - $('#t_pagination').replaceWith(oldPagination); - } else { - $momentList.after(oldPagination); - } - if (window._tagSwitchCallback) { - window._tagSwitchCallback.reject(); // 标记失败 - window._tagSwitchCallback = null; // 清理临时变量 - } + restoreAjaxSnapshotWithError(pageSnapshot); } }); }); @@ -1121,14 +1217,14 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () { $('.friends_cat_nav .cat-link').addClass('disabled'); // 保留原有的表单重置逻辑(如果不需要可删除) - var temp = $("#comment_form_reset"); - var formHtml = $("#t_commentform").prop('outerHTML'); - temp.html(formHtml); + cacheCommentFormForAjax(); // --- 1. 保存旧内容--- var $momentList = $(".moment_list"); - var oldContent = $momentList.html(); - var oldPagination = $('#t_pagination').prop('outerHTML'); + var pageSnapshot = createAjaxPageSnapshot({ + $content: $momentList, + paginationSelector: '#t_pagination' + }); // 清空列表并隐藏分页 $(".moment_list").empty(); @@ -1144,12 +1240,13 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () { $.ajax({ type: "GET", url: url, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { // 显示加载动画 - $('.moment_list').html('
    '); + showListLoading('.moment_list'); }, success: function (data) { - $this.addClass('active').parent().siblings().children().removeClass('active'); + setCategoryLinkActive($this); // 移除加载动画 $('.moment_list .loading_box').remove(); @@ -1158,22 +1255,7 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () { $(".moment_list").append(result.fadeIn(300)); // 处理分页逻辑 - var $newPagination = $(data).find("#t_pagination"); - var newHref = $newPagination.find("a").attr("data"); - - // 检查当前页面是否有分页容器,如果没有则补齐 - if ($('#t_pagination').length === 0 && $newPagination.length > 0) { - $(".moment_list").after($newPagination.prop('outerHTML')); - } - - var $paginationBtn = $('#t_pagination a'); - - if (newHref === undefined) { - $paginationBtn.hide(); - } else { - $paginationBtn.attr("data", newHref).text(Theme.site_page).show(); - $('#t_pagination').show(); - } + updateLoadMorePagination('#t_pagination', '.moment_list', data); // --- 功能初始化区域(根据您的实际情况启用/禁用) --- if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update(); @@ -1183,29 +1265,12 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () { // 更新浏览器历史状态 if (typeof url === 'string') { const displayUrl = removePageParamFromUrl(url.replace('author', 'tag')); - history.pushState({ url: displayUrl }, '', displayUrl); - } - initPreviousPageButton(); - if (window._tagSwitchCallback) { - window._tagSwitchCallback.resolve(); // 标记成功 - window._tagSwitchCallback = null; // 清理临时变量 + history.replaceState({ url: displayUrl }, '', displayUrl); } }, error: function () { $('.friends_cat_nav .cat-link').removeClass('disabled'); - if (window._tagSwitchCallback) { - window._tagSwitchCallback.reject(); // 标记失败 - window._tagSwitchCallback = null; // 清理临时变量 - } - cocoMessage.error('内容获取失败'); - $('.moment_list .loading_box').remove(); - // 恢复列表内容 - $momentList.html(oldContent); - if ($('#t_pagination').length > 0) { - $('#t_pagination').replaceWith(oldPagination); - } else { - $momentList.after(oldPagination); - } + restoreAjaxSnapshotWithError(pageSnapshot); } }); }); @@ -1221,18 +1286,20 @@ $(document).on('click', '#prev_pagination a', function () { const previousPage = parseInt($btn.attr('data-page'), 10) || Math.max(getPageNumberFromUrl(window.location.href) - 1, 1); const $pagingArea = $('#prev_pagination .post-paging'); - const oldPagingHtml = $pagingArea.html(); - const oldButtonHtml = $('#prev_pagination').prop('outerHTML'); - const oldListHtml = context.$list.html(); + const pageSnapshot = createAjaxPageSnapshot({ + $content: context.$list, + paginationSelector: '#prev_pagination', + paginationInsert: 'prepend', + $paginationAnchor: context.$list, + $pagingArea: $pagingArea + }); const scrollTopBeforeLoad = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; const listHeightBeforeLoad = context.$list[0] ? context.$list[0].scrollHeight : 0; $.ajax({ type: "GET", url: href, - headers: { - Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" - }, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { $btn.addClass('disabled').attr('aria-disabled', 'true'); $pagingArea.html('
    '); @@ -1240,15 +1307,15 @@ $(document).on('click', '#prev_pagination a', function () { success: function (data) { const $items = context.extract(data); if (!$items.length) { - restorePreviousPageState(context.$list, oldListHtml, oldButtonHtml); - cocoMessage.error('内容获取失败'); + restoreAjaxSnapshotWithError(pageSnapshot); return; } - $pagingArea.html(oldPagingHtml); + restoreAjaxPageSnapshot(pageSnapshot, { content: false, pagination: false, paging: true }); context.insert($items, data); context.afterLoad(); - initPreviousPageButton(); + initPreviousPageButton(previousPage - 1); + syncPageParamToUrl(previousPage); const listHeightAfterLoad = context.$list[0] ? context.$list[0].scrollHeight : listHeightBeforeLoad; const heightDelta = Math.max(0, listHeightAfterLoad - listHeightBeforeLoad); @@ -1256,8 +1323,7 @@ $(document).on('click', '#prev_pagination a', function () { $body.animate({ scrollTop: '-=100' }, 500); }, error: function () { - restorePreviousPageState(context.$list, oldListHtml, oldButtonHtml); - cocoMessage.error('内容获取失败'); + restoreAjaxSnapshotWithError(pageSnapshot); } }); @@ -1266,24 +1332,15 @@ $(document).on('click', '#prev_pagination a', function () { //ajax加载片刻 $(document).on('click', '#t_pagination a', function () { - const postListElement = document.getElementById("post_item"); var href = $(this).attr('data'); - let currentPage = 1; - try { - const url = new URL(href, window.location.origin); - const pageParam = parseInt(url.searchParams.get('page'), 10); - const pathPage = url.pathname.match(/\/page\/(\d+)/); - currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1); - } catch (e) { - const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/); - currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1; - } + const currentPage = getPageNumberFromUrl(href); const $pagingArea = $('#t_pagination .post-paging'); - const originalPagingHtml = $pagingArea.html(); + const pageSnapshot = createAjaxPageSnapshot({ $pagingArea: $pagingArea }); $.ajax({ type: "GET", url: href, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { $('#t_pagination .post-paging').html('
    '); }, @@ -1292,7 +1349,7 @@ $(document).on('click', '#t_pagination a', function () { var result = $(posts).find(".moment_list .p_item"); $('#t_pagination .post-paging').html(`
    ${Theme.site_page}`); $(".moment_list").append(result.fadeIn(300)); - window.pjax && window.pjax.refresh(postListElement) + refreshAjaxPostList(); var newhref = $(posts).find("#t_pagination a").attr("data"); if (newhref != undefined) { @@ -1312,9 +1369,7 @@ $(document).on('click', '#t_pagination a', function () { } }, error: function () { - $pagingArea.html(originalPagingHtml); - $('#t_pagination a').show(); - cocoMessage.error('内容获取失败'); + restorePagingSnapshotWithError(pageSnapshot); } }); return false; @@ -1348,41 +1403,27 @@ $(document).ready(function () { // --- 1. 保存旧内容 (关键修改) --- var $photosItem = $("#photos_item"); - var oldPhotosContent = $photosItem.html(); // 保存图库列表内容 - var oldPagination = $('#p_pagination').length > 0 ? $('#p_pagination').prop('outerHTML') : ''; // 保存分页结构 + var pageSnapshot = createAjaxPageSnapshot({ + $content: $photosItem, + paginationSelector: '#p_pagination' + }); $.ajax({ type: "GET", url: url, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - $("#photos_item").html( - '
    ' - ); + showListLoading("#photos_item", PHOTO_LIST_LOADING_HTML); $('#p_pagination').hide(); }, success: function (data) { - $this.addClass('active').parent().siblings().children().removeClass('active'); + setCategoryLinkActive($this); var $data = $(data); var newContent = $data.find("#photos_item").html(); $("#photos_item").html(newContent); - var $newPagination = $data.find("#p_pagination"); - if ($newPagination.length > 0) { - var newHref = $newPagination.find("a").attr("data"); - if (newHref) { - if ($('#p_pagination').length === 0) { - $("#photos_item").after($newPagination.prop('outerHTML')); - } else { - $('#p_pagination').replaceWith($newPagination.prop('outerHTML')); - } - $('#p_pagination').show(); - } else { - $('#p_pagination').hide(); - } - } else { - $('#p_pagination').hide(); - } + updateLoadMorePagination('#p_pagination', '#photos_item', data); if (typeof pix !== 'undefined' && pix.initGalleryPhotos) { pix.initGalleryPhotos(); @@ -1396,31 +1437,11 @@ $(document).ready(function () { $('.photos_cat_nav ul li a').removeClass('disabled'); - history.pushState({ path: displayUrl }, '', displayUrl); - initPreviousPageButton(); - if (window._tagSwitchCallback) { - window._tagSwitchCallback.resolve(); // 标记成功 - window._tagSwitchCallback = null; // 清理临时变量 - } + history.replaceState({ path: displayUrl }, '', displayUrl); }, error: function () { - // --- 2. 还原旧内容 (关键修改) --- - $photosItem.html(oldPhotosContent); // 恢复图库列表内容 - - // 恢复分页结构 - if (oldPagination) { - if ($('#p_pagination').length > 0) { - $('#p_pagination').replaceWith(oldPagination); - } else { - $photosItem.after(oldPagination); - } - } + restoreAjaxSnapshotWithError(pageSnapshot); $('.photos_cat_nav ul li a').removeClass('disabled'); - cocoMessage.error('内容获取失败'); - if (window._tagSwitchCallback) { - window._tagSwitchCallback.reject(); // 标记失败 - window._tagSwitchCallback = null; // 清理临时变量 - } } }); @@ -1431,22 +1452,14 @@ $(document).ready(function () { //ajax加载图库 $(document).on('click', '#p_pagination a', function () { var href = $(this).attr('data'); - let currentPage = 1; - try { - const url = new URL(href, window.location.origin); - const pageParam = parseInt(url.searchParams.get('page'), 10); - const pathPage = url.pathname.match(/\/page\/(\d+)/); - currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1); - } catch (e) { - const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/); - currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1; - } + const currentPage = getPageNumberFromUrl(href); const $pagingArea = $('#p_pagination .post-paging'); - const originalPagingHtml = $pagingArea.html(); + const pageSnapshot = createAjaxPageSnapshot({ $pagingArea: $pagingArea }); const targetOffsetTop = $('#p_pagination a').offset().top; $.ajax({ type: "GET", url: href, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { $('#p_pagination .post-paging').html('
    '); }, @@ -1471,9 +1484,7 @@ $(document).on('click', '#p_pagination a', function () { } }, error: function () { - $pagingArea.html(originalPagingHtml); - $('#p_pagination a').show(); - cocoMessage.error('内容获取失败'); + restorePagingSnapshotWithError(pageSnapshot); } }); return false; @@ -1623,7 +1634,6 @@ function getMomentAudio() { $(document).on('click', '.posts_cat_nav ul li a', function (e) { e.preventDefault(); var $this = $(this); - const postListElement = document.getElementById("post_item"); var t = $('.posts_cat_nav ul li a'); if (t.hasClass('disabled')) { @@ -1633,8 +1643,10 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) { // --- 1. 保存旧内容--- var $momentList = $(".norpost_list"); - var oldContent = $momentList.html(); - var oldPagination = $('#pagination').prop('outerHTML'); + var pageSnapshot = createAjaxPageSnapshot({ + $content: $momentList, + paginationSelector: '#pagination' + }); $(".norpost_list").empty(); $('#pagination a').hide(); @@ -1661,88 +1673,43 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) { $.ajax({ type: "GET", url: cat, // 完全保留原有请求URL,不修改 - headers: { - Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" - }, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - $('.norpost_list').html('
    '); + showListLoading('.norpost_list'); }, success: function (data) { - $this.addClass('active').parent().siblings().children().removeClass('active'); + setCategoryLinkActive($this); $('#pagination a').text(Theme.site_page); var result = $(data).find(".norpost_list").children(); $(".norpost_list").append(result.fadeIn(300)); - window.pjax && window.pjax.refresh(postListElement); + refreshAjaxPostList(); - const $newPagination = $(data).find("#pagination"); - let newhref = $newPagination.find("a").attr("data") || $(data).find(".arc_pagenav a").attr("data"); - - if ($('#pagination').length === 0 && $newPagination.length > 0) { - $(".norpost_list").after($newPagination.prop('outerHTML')); - } - - if (newhref != undefined) { - $("#pagination a").attr("data", newhref); - $('#pagination a').text(Theme.site_page); - $('#pagination a').show(); - $('#pagination').show(); - } else { - $('#pagination a').hide(); - } + updateLoadMorePagination('#pagination', '.norpost_list', data, '.arc_pagenav'); $('.loading_box').remove(); initAgree(); lazyLoadInstance.update(); $('.posts_cat_nav ul li a').removeClass('disabled'); - history.pushState({ url: displayUrl }, '', displayUrl); - initPreviousPageButton(); - if (window._tagSwitchCallback) { - window._tagSwitchCallback.resolve(); // 标记成功 - window._tagSwitchCallback = null; // 清理临时变量 - } + history.replaceState({ url: displayUrl }, '', displayUrl); }, error: function () { $('.posts_cat_nav ul li a').removeClass('disabled'); - cocoMessage.error('内容获取失败'); - $('.norpost_list .loading_box').remove(); - // 恢复列表内容 - $momentList.html(oldContent); - if ($('#pagination').length > 0) { - $('#pagination').replaceWith(oldPagination); - } else { - $momentList.after(oldPagination); - } - if (window._tagSwitchCallback) { - window._tagSwitchCallback.reject(); // 标记失败 - window._tagSwitchCallback = null; // 清理临时变量 - } + restoreAjaxSnapshotWithError(pageSnapshot); } }); }); //ajax加载文章 $('body').on('click', '#pagination a', function () { - const postListElement = document.getElementById("post_item"); const $pagingArea = $('#pagination .post-paging'); - const originalPagingHtml = $pagingArea.html(); + const pageSnapshot = createAjaxPageSnapshot({ $pagingArea: $pagingArea }); var href = $(this).attr('data'); - let currentPage = 1; - try { - const url = new URL(href, window.location.origin); - const pageParam = parseInt(url.searchParams.get('page'), 10); - const pathPage = url.pathname.match(/\/page\/(\d+)/); - currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1); - } catch (e) { - const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/); - currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1; - } + const currentPage = getPageNumberFromUrl(href); $.ajax({ type: "GET", url: href, - headers: { - Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" - }, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { $('#pagination .post-paging').html('
    '); }, @@ -1752,7 +1719,7 @@ $('body').on('click', '#pagination a', function () { $('#pagination .post-paging').html(`${Theme.site_page}`); $('.norpost_list').append($(result).fadeIn(400)); - window.pjax && window.pjax.refresh(postListElement) + refreshAjaxPostList(); var newhref = $(data).find("#pagination a").attr("data") || $(data).find(".arc_pagenav a").attr("data"); //找出新的下一页链接 @@ -1771,9 +1738,7 @@ $('body').on('click', '#pagination a', function () { } }, error: function () { - $pagingArea.html(originalPagingHtml); - $('#pagination a').show(); - cocoMessage.error('内容获取失败'); + restorePagingSnapshotWithError(pageSnapshot); } }); return false; @@ -1783,30 +1748,17 @@ $('body').on('click', '#pagination a', function () { $('body').on('click', '.arc_pagenav a', function () { // 【新增】保存分页区域的原始HTML,用于失败时恢复 const $pagingArea = $('.arc_pagenav'); - const originalPagingHtml = $pagingArea.html(); - const postListElement = document.getElementById("post_item"); + const pageSnapshot = createAjaxPageSnapshot({ $pagingArea: $pagingArea }); var href = $(this).attr('data'); - let currentPage = 1; - try { - const url = new URL(href, window.location.origin); - const pageParam = parseInt(url.searchParams.get('page'), 10); - const pathPage = url.pathname.match(/\/page\/(\d+)/); - currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1); - } catch (e) { - const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/); - currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1; - } + const currentPage = getPageNumberFromUrl(href); $(this).hide(); var content = $('.norpost_list'); - var href = $(this).attr('data'); if (href != undefined) { $.ajax({ type: "GET", url: href, - headers: { - Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" - }, + headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { $('.arc_pagenav').append('
    '); }, @@ -1814,7 +1766,7 @@ $('body').on('click', '.arc_pagenav a', function () { var post = $(data).find(".norpost_list").children(); content.append(post.fadeIn(300)); - window.pjax && window.pjax.refresh(postListElement) + refreshAjaxPostList(); var newhref = $(data).find(".arc_pagenav a").attr("data"); //找出新的下一页链接 if (newhref != undefined) { @@ -1830,8 +1782,7 @@ $('body').on('click', '.arc_pagenav a', function () { syncPageParamToUrl(currentPage); }, error: function () { - $pagingArea.html(originalPagingHtml); - cocoMessage.error('内容获取失败'); + restorePagingSnapshotWithError(pageSnapshot); } }); } @@ -2042,6 +1993,12 @@ if (Theme.pjax) { cacheBust: false, }); + let isPopNav = false; + // 监听popstate(用户点浏览器前进、后退按钮) + window.addEventListener('popstate', function () { + isPopNav = true; + }); + document.addEventListener('pjax:send', function () { NProgress.start(); }) @@ -2054,6 +2011,17 @@ if (Theme.pjax) { initBlog(); 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() + } }) } @@ -3056,7 +3024,6 @@ function initjump() { targetLink.trigger('click'); } } - initPreviousPageButton(); // 功能2:登录登出、发布更新等操作后,显示提示信息 let closeLoading = null; @@ -3148,14 +3115,14 @@ function initBlog() { pix.loadLightbox(), pix.topCategoriesBarScroll(), pix.topTableBarScroll(), + pix.centerCategoryNavActive(), getMomentAudio(), Theme.toc.all_open && autotree(), highlightActiveMenu(), syncFooterWithAudioState(), highlightMenu(), - initializeMomentFold(), - initPreviousPageButton() + initializeMomentFold() // nextBanner() } @@ -3165,6 +3132,7 @@ $(document).ready(function () { pix.roleMoments(); initBlog(); + initPreviousPageButton() setPageGrayscale(); anian_renderLunarUI(); updateMusicBtnColor('default'); diff --git a/templates/assets/js/pix.js b/templates/assets/js/pix.js index b837940..aa32e84 100644 --- a/templates/assets/js/pix.js +++ b/templates/assets/js/pix.js @@ -163,6 +163,31 @@ var pix = { }, + centerCategoryNavActive: function ($link) { + var $activeLink = $link && $link.length ? $link : $('.moment_cat_nav .active, .posts_cat_nav .active, .photos_cat_nav .active, .douban_cat_nav .active, .friends_cat_nav .active').first(); + if (!$activeLink || !$activeLink.length) { + return; + } + + var navEl = $activeLink.closest('.moment_cat_nav, .posts_cat_nav, .photos_cat_nav, .douban_cat_nav, .friends_cat_nav').find('ul').get(0); + if (!navEl) { + return; + } + + var linkEl = $activeLink.get(0); + var maxScrollLeft = navEl.scrollWidth - navEl.clientWidth; + if (maxScrollLeft <= 0) { + return; + } + + var navRect = navEl.getBoundingClientRect(); + var linkRect = linkEl.getBoundingClientRect(); + var targetScrollLeft = navEl.scrollLeft + (linkRect.left - navRect.left) - (navRect.width / 2 - linkRect.width / 2); + targetScrollLeft = Math.max(0, Math.min(maxScrollLeft, targetScrollLeft)); + + $(navEl).stop(true).animate({ scrollLeft: targetScrollLeft }, 220); + }, + topCategoriesBarScroll: function () { if (document.getElementById("cat_nav_items")) { let xscroll = document.getElementById("cat_nav_items"); diff --git a/templates/assets/js/pixplayer.js b/templates/assets/js/pixplayer.js index 07bc587..737e536 100644 --- a/templates/assets/js/pixplayer.js +++ b/templates/assets/js/pixplayer.js @@ -361,10 +361,9 @@ function mu_box_show() { function mu_box_hide(time = 2000) { clearTimeout(trigger); trigger = setTimeout(function () { - // 获取屏幕宽度判断是否为手机端(与歌词容器响应式逻辑保持一致) - const isMobile = $(window).width() <= 767; - // 手机端隐藏时额外向下偏移50px(可根据需要调整数值),非手机端保持默认0px - const hideTop = isMobile ? "50px" : "0px"; + const hasBottomMenu = $(window).width() <= 960; + // 底部导航可见时,播放器收起到导航栏后面。 + const hideTop = hasBottomMenu ? "50px" : "0px"; // 执行隐藏动画 $('.footer_nav_box').animate({ diff --git a/templates/assets/js/poster.js b/templates/assets/js/poster.js index dda80ce..9489190 100644 --- a/templates/assets/js/poster.js +++ b/templates/assets/js/poster.js @@ -5,7 +5,7 @@ const poster = (function() { const DEBUG = false const WIDTH = 700 - const HEIGHT = 1160 + const HEIGHT = 850 /** * 将图片URL加载为Image对象,并返回Promise @@ -47,9 +47,12 @@ const poster = (function() { const $title = createDom('canvas', 'id', 'title') const $content = createDom('canvas', 'id', 'content') const $logo = createDom('canvas', 'id', 'logo') + const $siteName = createDom('canvas', 'id', 'siteName') const $description = createDom('canvas', 'id', 'description') + const $customText1 = createDom('canvas', 'id', 'customText1') + const $customText2 = createDom('canvas', 'id', 'customText2') - appendChilds($wrapper, $canvas, $day, $date, $title, $content, $logo, $description) + appendChilds($wrapper, $canvas, $day, $siteName, $date, $title, $content, $logo, $description, $customText1, $customText2) $container.appendChild($wrapper) const date = new Date() @@ -83,6 +86,58 @@ const poster = (function() { titleStyle.position = (config.titleStyle && config.titleStyle.position) || titleStyle.position drawMoreLines($title, titleStyle, config.title) + // site name canvas + const siteNameStyle = { + font: '40px Helvetica', + lineHeight: 1.3, + color: 'rgba(255, 255, 255, 0.95)', + position: 'left' + } + siteNameStyle.font = (config.siteNameStyle && config.siteNameStyle.font) || siteNameStyle.font + siteNameStyle.color = (config.siteNameStyle && config.siteNameStyle.color) || siteNameStyle.color + siteNameStyle.lineHeight = (config.siteNameStyle && config.siteNameStyle.lineHeight) || siteNameStyle.lineHeight + siteNameStyle.position = (config.siteNameStyle && config.siteNameStyle.position) || siteNameStyle.position + drawMoreLines($siteName, siteNameStyle, config.siteName) + + // description canvas + const descriptionStyle = { + font: '25px Helvetica', + color: 'rgba(236, 241, 255, 1)', + lineHeight: 1.2, + position: 'left' + } + descriptionStyle.font = (config.descriptionStyle && config.descriptionStyle.font) || descriptionStyle.font + descriptionStyle.color = (config.descriptionStyle && config.descriptionStyle.color) || descriptionStyle.color + descriptionStyle.lineHeight = (config.descriptionStyle && config.descriptionStyle.lineHeight) || descriptionStyle.lineHeight + descriptionStyle.position = (config.descriptionStyle && config.descriptionStyle.position) || descriptionStyle.position + drawMoreLines($description, descriptionStyle, config.description) + + // custom text 1 canvas + const customText1Style = { + font: '28px Helvetica', + lineHeight: 1.3, + position: 'left', + color: 'rgba(0, 0, 0, 1)' + } + customText1Style.font = (config.customText1Style && config.customText1Style.font) || customText1Style.font + customText1Style.color = (config.customText1Style && config.customText1Style.color) || customText1Style.color + customText1Style.lineHeight = (config.customText1Style && config.customText1Style.lineHeight) || customText1Style.lineHeight + customText1Style.position = (config.customText1Style && config.customText1Style.position) || customText1Style.position + drawMoreLines($customText1, customText1Style, config.customText1 || '') + + // custom text 2 canvas + const customText2Style = { + font: '28px Helvetica', + lineHeight: 1.3, + position: 'left', + color: 'rgba(0, 0, 0, 1)' + } + customText2Style.font = (config.customText2Style && config.customText2Style.font) || customText2Style.font + customText2Style.color = (config.customText2Style && config.customText2Style.color) || customText2Style.color + customText2Style.lineHeight = (config.customText2Style && config.customText2Style.lineHeight) || customText2Style.lineHeight + customText2Style.position = (config.customText2Style && config.customText2Style.position) || customText2Style.position + drawMoreLines($customText2, customText2Style, config.customText2 || '') + // content canvas const contentStyle = { font: '22px Helvetica', @@ -96,15 +151,6 @@ const poster = (function() { contentStyle.position = (config.contentStyle && config.contentStyle.position) || contentStyle.position drawMoreLines($content, contentStyle, config.content); - // description canvas - const descriptionStyle = { - font: '24px Helvetica', - color: 'rgba(180, 180, 180, 1)', - lineHeight: 1.2, - position: 'left' - } - drawMoreLines($description, descriptionStyle, config.description) - // ------------------ 【修复点 1:使用 Promise.all 等待所有图片加载】 ------------------ Promise.all([ @@ -126,7 +172,7 @@ const poster = (function() { ctx.drawImage(image, imgRect.sx, imgRect.sy, imgRect.sWidth, imgRect.sHeight, 20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40); // 3. 绘制覆盖层 - ctx.fillStyle="rgba(0, 0, 0, 0.3)"; + ctx.fillStyle="rgba(0, 0, 0, 0.6)"; ctx.fillRect(20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40); // 4. 绘制时间 (使用预先绘制好的 Canvas) @@ -134,17 +180,20 @@ const poster = (function() { ctx.drawImage($date, -21, 125) // 5. 绘制 Logo - var logoh = 60; + var logoh = 140; var cwidth = logoh * (logo.width / logo.height); - ctx.drawImage(logo, 60, $canvas.height / 1.2 + 30, cwidth, logoh); + ctx.drawImage(logo, 20, $canvas.height / 1.2 - 10, cwidth, logoh); // 6. 绘制二维码 - ctx.drawImage(qrcode, $canvas.width - 160, $canvas.height / 1.2 + 20, 120, 120); + ctx.drawImage(qrcode, $canvas.width - 150, $canvas.height / 1.2 + 10, 120, 120); // 7. 绘制文字 (使用预先绘制好的 Canvas) - ctx.drawImage($title, 20, $canvas.height / 2 + 20) + ctx.drawImage($siteName, 10, 60) + ctx.drawImage($description, 10, 120) + ctx.drawImage($customText1, 270, $canvas.height / 2 + 310) + ctx.drawImage($customText2, 215, $canvas.height / 2 + 360) + ctx.drawImage($title, 20, $canvas.height / 2 + 60) ctx.drawImage($content, 20, $canvas.height / 2 + 120) - ctx.drawImage($description, 20, $canvas.height / 1.2 + 110) ctx.strokeStyle = 'rgba(122, 122, 122, 0.5)'; // 8. 转换并显示最终图片 @@ -204,19 +253,14 @@ const poster = (function() { } } - // 覆盖函数(不变) + // 覆盖函数:按目标区域等比缩放并居中裁切,尽量不留白 function coverImg(box_w, box_h, source_w, source_h) { - var sx = 0, - sy = 0, - sWidth = source_w, - sHeight = source_h; - if (source_w > source_h || (source_w == source_h && box_w < box_h)) { - sWidth = box_w * sHeight / box_h; - sx = (source_w - sWidth) / 2; - } else if (source_w < source_h || (source_w == source_h && box_w > box_h)) { - sHeight = box_h * sWidth / box_w; - sY = (source_h - sHeight) / 2; - } + const scale = Math.max(box_w / source_w, box_h / source_h); + const sWidth = box_w / scale; + const sHeight = box_h / scale; + const sx = (source_w - sWidth) / 2; + const sy = (source_h - sHeight) / 2; + return { sx, sy, @@ -397,7 +441,8 @@ $('body').on('click', '.cr_poster', function () { var content = content_element.innerText; var content_length = content.length; var permalink = t_content.length > 0 ? window.location.origin + '/moments/' + post_id : window.location.origin + window.location.pathname; - var title = t_content.length > 0 ? Theme.site_title + '-瞬间' : document.title; + var title = t_content.length > 0 ? '瞬间' : (document.title || '').split(' - ')[0]; + var siteName = Theme.site_title; // 确保 QRious 库可用 if (typeof QRious === 'undefined') { @@ -430,7 +475,7 @@ $('body').on('click', '.cr_poster', function () { // ----------------------------------------------------------------------- if (content_length > 120) { - content = content.substring(0, 80) + '...' + content = content.substring(0, 82) + '...' } // 海报生成回调 @@ -456,10 +501,21 @@ $('body').on('click', '.cr_poster', function () { selector: modal + ' .poster_box', container: $posterBox[0], title: title, + siteName: siteName, + description: Theme.admin_des, content: content, logo: Theme.site_logo, qrcode: $('#twoCode').attr('src'), - description: Theme.admin_des, + customText1: '扫描右侧二维码', + customText2: '或访问:https://anian.net', + customText1Style: { + font: '24px Helvetica', + color: 'rgba(0, 0, 0, 1)' + }, + customText2Style: { + font: '24px Helvetica', + color: 'rgba(0, 0, 0, 1)' + }, callback: Posterdown }); }); @@ -565,4 +621,4 @@ function handleShare(e, pic, title, pathname) { break } -} \ No newline at end of file +} diff --git a/templates/friends.html b/templates/friends.html index 30fc6a1..099a850 100755 --- a/templates/friends.html +++ b/templates/friends.html @@ -9,9 +9,8 @@
    @@ -23,16 +22,16 @@
  • + th:classappend="${#strings.isEmpty(selectedTag) ? 'active' : ''}" class="cat-link"> 全部
  • - +
  • - +
  • @@ -115,14 +114,8 @@
    -
    - - - +
    diff --git a/templates/modules/footer.html b/templates/modules/footer.html index 1be5216..595c5fe 100644 --- a/templates/modules/footer.html +++ b/templates/modules/footer.html @@ -1,5 +1,5 @@ - +
    diff --git a/templates/modules/head.html b/templates/modules/head.html index 163ce2d..890436e 100644 --- a/templates/modules/head.html +++ b/templates/modules/head.html @@ -1,4 +1,4 @@ - + diff --git a/templates/modules/layouts/layout.html b/templates/modules/layouts/layout.html index afac5a0..8086aba 100644 --- a/templates/modules/layouts/layout.html +++ b/templates/modules/layouts/layout.html @@ -47,7 +47,7 @@
    -
    +
    diff --git a/theme.yaml b/theme.yaml index affdbd3..67e84db 100644 --- a/theme.yaml +++ b/theme.yaml @@ -17,7 +17,7 @@ spec: issues: "https://github.com/chengzhongxue/halo-theme-pix/issues" settingName: "theme-pix-setting" configMapName: "theme-pix-configMap" - version: "1.2.5-7" + version: "1.2.5-8" require: ">=2.20.0" customTemplates: page: