超级加倍优化更新

This commit is contained in:
Han 2025-03-08 14:36:33 +08:00
parent 5cf4fe36fe
commit 68d5f36a26
13 changed files with 99 additions and 56 deletions

View File

@ -2,8 +2,14 @@
import mdx from '@astrojs/mdx'; import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap'; import sitemap from '@astrojs/sitemap';
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import remarkDirective from "remark-directive"; /* Handle directives */ import Compress from "@playform/compress";
import { remarkNote, addClassNames } from './src/plugins/markdown.formate' // Markdown 配置================
import remarkMath from "remark-math";
import rehypeSlug from "rehype-slug";
import rehypeKatex from "rehype-katex";
import remarkDirective from "remark-directive";
import { remarkNote, addClassNames } from './src/plugins/markdown.custom'
// Markdown 配置================
import swup from '@swup/astro'; import swup from '@swup/astro';
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
@ -22,6 +28,11 @@ export default defineConfig({
updateBodyClass: false, updateBodyClass: false,
globalInstance: true globalInstance: true
}), }),
Compress({
CSS: false,
Image: false,
Action: { Passed: async () => true },
}),
sitemap({ sitemap({
changefreq: 'weekly', changefreq: 'weekly',
priority: 0.7, priority: 0.7,
@ -29,10 +40,19 @@ export default defineConfig({
// 处理末尾带 / 的 url // 处理末尾带 / 的 url
serialize: (item) => ({ ...item, url: item.url.endsWith('/') ? item.url.slice(0, -1) : item.url }) serialize: (item) => ({ ...item, url: item.url.endsWith('/') ? item.url.slice(0, -1) : item.url })
}), }),
mdx()], mdx({ extendMarkdownConfig: false })
],
markdown: { markdown: {
rehypePlugins: [addClassNames], remarkPlugins: [
remarkPlugins: [remarkDirective, remarkNote], remarkMath,
remarkDirective,
remarkNote,
],
rehypePlugins: [
rehypeKatex,
rehypeSlug,
addClassNames
],
syntaxHighlight: 'shiki', syntaxHighlight: 'shiki',
shikiConfig: { theme: 'github-light' }, shikiConfig: { theme: 'github-light' },
}, },

View File

@ -16,11 +16,13 @@
"@swup/astro": "^1.5.0", "@swup/astro": "^1.5.0",
"aplayer": "^1.10.1", "aplayer": "^1.10.1",
"astro": "^5.4.1", "astro": "^5.4.1",
"lenis": "^1.2.1",
"overlayscrollbars": "^2.11.1", "overlayscrollbars": "^2.11.1",
"vanilla-lazyload": "^19.1.3", "vanilla-lazyload": "^19.1.3",
"vh-plugin": "^1.2.2" "vh-plugin": "^1.2.2"
}, },
"devDependencies": { "devDependencies": {
"@playform/compress": "^0.1.7",
"@types/dplayer": "^1.25.5", "@types/dplayer": "^1.25.5",
"@types/nprogress": "^0.2.3", "@types/nprogress": "^0.2.3",
"cheerio": "^1.0.0", "cheerio": "^1.0.0",
@ -28,7 +30,11 @@
"less": "^4.2.2", "less": "^4.2.2",
"mdast-util-to-string": "^4.0.0", "mdast-util-to-string": "^4.0.0",
"reading-time": "^1.5.0", "reading-time": "^1.5.0",
"rehype-katex": "^7.0.1",
"rehype-slug": "^6.0.0",
"remark-directive": "^4.0.0", "remark-directive": "^4.0.0",
"remark-math": "^6.0.0",
"remark-sectionize": "^2.1.0",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"unist-util-visit": "^5.0.0" "unist-util-visit": "^5.0.0"
}, },

View File

@ -3,16 +3,10 @@ import { visit } from 'unist-util-visit';
import getReadingTime from 'reading-time'; import getReadingTime from 'reading-time';
import { toString } from 'mdast-util-to-string'; import { toString } from 'mdast-util-to-string';
// 处理函数
const nodeTreeFmt = (node: any, parent: any) => {
if (node.type === 'text') parent.children = node.value.split('\n').map((i: string) => ({ type: 'paragraph', children: [{ type: 'text', value: i }] }));
if (node.children && node.children.length) node.children.forEach((child: any) => nodeTreeFmt(child, node));
}
// 处理标签 // 处理标签
const remarkNote = () => { const remarkNote = () => {
return (tree: any, { data: astroData }: any) => { return (tree: any, { data: astroData }: any) => {
visit(tree, (node, index, parent) => { visit(tree, (node) => {
const { type, name, attributes } = node; const { type, name, attributes } = node;
// 处理组件 // 处理组件
if (type == 'textDirective' || type == 'leafDirective' || type == 'containerDirective') { if (type == 'textDirective' || type == 'leafDirective' || type == 'containerDirective') {
@ -31,10 +25,6 @@ const remarkNote = () => {
if (name.startsWith('vh')) { if (name.startsWith('vh')) {
Object.keys(node.attributes).forEach((i: any) => (hProperties[`data-${i}`] = node.attributes[i])); Object.keys(node.attributes).forEach((i: any) => (hProperties[`data-${i}`] = node.attributes[i]));
} }
// 处理 note 内容换行问题
if (name == 'note') {
nodeTreeFmt(node, parent);
};
// 设置 class // 设置 class
hProperties.class = `vh-node vh-${name}${attributes.type ? ` ${name}-${attributes.type}` : ''}`; hProperties.class = `vh-node vh-${name}${attributes.type ? ` ${name}-${attributes.type}` : ''}`;
// 文章字数统计 // 文章字数统计
@ -48,7 +38,7 @@ const remarkNote = () => {
} }
// Pre中的 Copy 按钮 // 处理 HTML 标签
const addClassNames = () => { const addClassNames = () => {
return (tree: any) => { return (tree: any) => {
visit(tree, (node, index, parent) => { visit(tree, (node, index, parent) => {
@ -56,19 +46,22 @@ const addClassNames = () => {
if (node.tagName === 'a') { if (node.tagName === 'a') {
node.properties.target = '_blank', node.properties.rel = 'noopener nofollow' node.properties.target = '_blank', node.properties.rel = 'noopener nofollow'
node.children = [{ type: 'element', tagName: 'span', children: node.children || [] }]; node.children = [{ type: 'element', tagName: 'span', children: node.children || [] }];
} // 处理 pre 标签
// 处理代码快 } else if (node.tagName === 'pre') {
if (node.tagName === 'pre') {
const divNode = { type: 'element', tagName: 'section', properties: { class: 'vh-code-box' }, children: [{ type: 'element', tagName: 'span', properties: { class: 'vh-code-copy' } }, node] }; const divNode = { type: 'element', tagName: 'section', properties: { class: 'vh-code-box' }, children: [{ type: 'element', tagName: 'span', properties: { class: 'vh-code-copy' } }, node] };
// 替换父节点的 children 中的 pre 节点为新的 div 节点 // 替换父节点的 children 中的 pre 节点为新的 div 节点
if (parent && index !== null) parent.children.splice(index, 1, divNode); if (parent && index !== null) parent.children.splice(index, 1, divNode);
} // 处理 img 标签
// 处理图片 } else if (node.tagName === 'img') {
if (node.tagName === 'img') {
// 添加 class 和 loading 属性 // 添加 class 和 loading 属性
node.properties.class = 'vh-article-img'; node.properties.class = 'vh-article-img';
node.properties['data-vh-lz-src'] = node.properties.src; node.properties['data-vh-lz-src'] = node.properties.src;
node.properties.src = '/assets/images/lazy-loading.webp'; node.properties.src = '/assets/images/lazy-loading.webp';
// 处理 section 标签
} else if (node.tagName === 'section') {
if (node.properties.class && node.properties.class.includes('vh-vhVideo')) {
node.children = [{ type: 'element', tagName: 'section', properties: { class: 'vh-space-loading' }, children: [{ type: 'element', tagName: 'span' }, { type: 'element', tagName: 'span' }, { type: 'element', tagName: 'span' }] }];
}
} }
}); });

View File

@ -12,7 +12,11 @@ const scrollChangeFn = () => {
circle.style.strokeDashoffset = circumference - (percentage / 100) * circumference; circle.style.strokeDashoffset = circumference - (percentage / 100) * circumference;
}; };
// 返回顶部事件 // 返回顶部事件
const backTopFn = () => window.scrollTo({ top: 0, behavior: "smooth" }); const backTopFn = () => {
(window as any).vhlenis && (window as any).vhlenis.stop();
window.scrollTo({ top: 0, behavior: "smooth" });
(window as any).vhlenis.start();
};
// 页面更新,初始化函数====== // 页面更新,初始化函数======
// 回顶部DOM // 回顶部DOM
let backTop: any = document.querySelector(".vh-back-top"); let backTop: any = document.querySelector(".vh-back-top");

View File

@ -1,25 +1,13 @@
// 灯箱JS初始化====== // Pre Code 代码复制功能======
import "../../public/assets/js/view-image.min.js"; let copyText = null;
declare const ViewImage: any;
// 灯箱JS初始化======
// Pre 滚动条====== // Pre 滚动条======
import "overlayscrollbars/overlayscrollbars.css"; import "overlayscrollbars/overlayscrollbars.css";
import { OverlayScrollbars } from "overlayscrollbars"; import { OverlayScrollbars } from "overlayscrollbars";
// Pre 滚动条======
// Pre Code 代码复制功能======
let copyText = null;
// Pre Code 代码复制功能======
// 初始化
export default () => { export default () => {
// 灯箱JS初始化======
ViewImage && ViewImage.init("main>.vh-container>article.vh-article-main img.vh-article-img");
// 灯箱JS初始化======
// Pre 滚动条====== // Pre 滚动条======
document.querySelectorAll("section.vh-code-box>pre.astro-code").forEach((i: any) => { document.querySelectorAll("section.vh-code-box>pre.astro-code").forEach((i: any) => {
OverlayScrollbars(i, { scrollbars: { autoHide: "leave", autoHideDelay: 500, autoHideSuspend: false } }); OverlayScrollbars(i, { scrollbars: { autoHide: "leave", autoHideDelay: 500, autoHideSuspend: false } });
}); });
// Pre 滚动条======
// Pre Code 代码复制功能====== // Pre Code 代码复制功能======
document.querySelectorAll("section.vh-code-box>span.vh-code-copy").forEach((i: any) => { document.querySelectorAll("section.vh-code-box>span.vh-code-copy").forEach((i: any) => {
i.vhTimer = null; i.vhTimer = null;
@ -35,5 +23,4 @@ export default () => {
}, 1000); }, 1000);
}); });
}); });
// Pre Code 代码复制功能======
} }

View File

@ -8,14 +8,14 @@ declare const twikoo: any;
// 处理评论区数据 // 处理评论区数据
const formateComment = () => { const formateComment = () => {
// 图片灯箱 // 图片灯箱
ViewImage && ViewImage.init(".vh-comment img:not(.tk-avatar-img,.tk-owo-emotion,.OwO-item img), main>.vh-container>article.vh-article-main img.vh-article-img"); ViewImage && ViewImage.init(".vh-container>article.vh-article-main img.vh-article-img, .vh-talking>main>article>.main img, .vh-comment>.twikoo>.tk-comments img:not(.tk-avatar-img,.tk-owo-emotion,.OwO-item img)");
// 处理 URL // 处理 URL
document.querySelectorAll('.vh-comment a[href="#"]').forEach(link => link.removeAttribute('href')); document.querySelectorAll('.vh-comment a[href="#"]').forEach(link => link.removeAttribute('href'));
} }
// 初始化评论插件 // 初始化评论插件
export default async () => { export default async () => {
const commentDOM = '.vh-comment>section' const commentDOM = '.vh-comment>section'
if (!document.querySelector(commentDOM) || !SITE_INFO.Twikoo.envId) return; if (!document.querySelector(commentDOM) || !SITE_INFO.Twikoo.envId) return formateComment();
document.querySelector(commentDOM)!.innerHTML = '<section></section>' document.querySelector(commentDOM)!.innerHTML = '<section></section>'
await LoadScript("https://registry.npmmirror.com/twikoo/1.6.41/files/dist/twikoo.all.min.js"); await LoadScript("https://registry.npmmirror.com/twikoo/1.6.41/files/dist/twikoo.all.min.js");
twikoo.init({ envId: SITE_INFO.Twikoo.envId, el: commentDOM, onCommentLoaded: () => setTimeout(formateComment) }) twikoo.init({ envId: SITE_INFO.Twikoo.envId, el: commentDOM, onCommentLoaded: () => setTimeout(formateComment) })

View File

@ -1,6 +1,8 @@
import { inRouter, outRouter } from "../utils/updateRouter"; import { inRouter, outRouter } from "../utils/updateRouter";
// 初始化文章功能脚本 // 鼠标滚动阻尼效果
import ArticleInit from "../scripts/Article"; import LenisInit from './Lenis';
// 初始化文章代码块
import codeInit from "../scripts/Code";
// 初始化视频播放器 // 初始化视频播放器
import videoInit from "../scripts/Video"; import videoInit from "../scripts/Video";
// 初始化音乐播放器 // 初始化音乐播放器
@ -17,6 +19,8 @@ import initLinkCurrent from "../scripts/Header";
import initWebSiteTime from "../scripts/Footer"; import initWebSiteTime from "../scripts/Footer";
// 友情链接初始化 // 友情链接初始化
import initLinks from "../scripts/Links"; import initLinks from "../scripts/Links";
// 朋友圈 RSS 初始化
import initFriends from "../scripts/Friends";
// 动态说说初始化 // 动态说说初始化
import initTalking from "../scripts/Talking"; import initTalking from "../scripts/Talking";
// 文章评论初始化 // 文章评论初始化
@ -36,6 +40,8 @@ import { LoadScript } from "../utils/index";
const videoList: any[] = []; const videoList: any[] = [];
const MusicList: any[] = []; const MusicList: any[] = [];
const indexInit = async (only: boolean = true) => { const indexInit = async (only: boolean = true) => {
// 鼠标滚动阻尼效果
only && LenisInit();
// 预加载搜索数据 // 预加载搜索数据
only && searchFn(""); only && searchFn("");
// 初始化搜索功能 // 初始化搜索功能
@ -48,14 +54,16 @@ const indexInit = async (only: boolean = true) => {
only && initMobileSidebar(); only && initMobileSidebar();
// 顶部导航 Current 状态 // 顶部导航 Current 状态
initLinkCurrent() initLinkCurrent()
// 初始化文章代码块
codeInit();
// 文章评论初始化 // 文章评论初始化
initComment(); initComment();
// 初始化文章功能脚本
ArticleInit();
// 图片懒加载初始化 // 图片懒加载初始化
vhLzImgInit(); vhLzImgInit();
// 友情链接初始化 // 友情链接初始化
initLinks(); initLinks();
// 朋友圈 RSS 初始化
initFriends();
// 动态说说初始化 // 动态说说初始化
initTalking(); initTalking();
// Google 广告 // Google 广告

15
src/scripts/Lenis.ts Normal file
View File

@ -0,0 +1,15 @@
import Lenis from "lenis";
(window as any).vhlenis = new Lenis();
const lenisInit = (time: any) => {
(window as any).vhlenis.raf(time)
requestAnimationFrame(lenisInit)
}
(window as any).vhlenis.on('scroll', () => {
if (window.scrollY + window.innerHeight >= document.documentElement.scrollHeight) {
(window as any).vhlenis.stop();
(window as any).vhlenis.start();
}
});
export default () => requestAnimationFrame(lenisInit)

View File

@ -1,4 +1,3 @@
import vh from 'vh-plugin'
import { $GET } from '../utils/index' import { $GET } from '../utils/index'
// 更新数据 // 更新数据
@ -48,7 +47,10 @@ const vhSearchInit = () => {
const searchDOM: any = document.querySelector(".vh-header>.main>.nav-btn>span.search-btn"); const searchDOM: any = document.querySelector(".vh-header>.main>.nav-btn>span.search-btn");
const searchMainDOM: any = document.querySelector(".vh-header>.main>.vh-search>main"); const searchMainDOM: any = document.querySelector(".vh-header>.main>.vh-search>main");
const searchListDOM: any = document.querySelector(".vh-header>.main>.vh-search"); const searchListDOM: any = document.querySelector(".vh-header>.main>.vh-search");
const addActive = () => setTimeout(() => searchListDOM.classList.add("active")); const addActive = () => setTimeout(() => {
searchListDOM.classList.add("active");
searchListDOM.querySelector(".search-input>input").focus();
});
const removeActive = () => setTimeout(() => searchListDOM.classList.remove("active")); const removeActive = () => setTimeout(() => searchListDOM.classList.remove("active"));
// 禁止默认事件 // 禁止默认事件
searchMainDOM.addEventListener("click", (e: Event) => e.stopPropagation()); searchMainDOM.addEventListener("click", (e: Event) => e.stopPropagation());

View File

@ -21,7 +21,7 @@ const TalkingInit = async (data: any) => {
// 图片懒加载 // 图片懒加载
vhLzImgInit(); vhLzImgInit();
// 灯箱JS初始化====== // 灯箱JS初始化======
ViewImage && ViewImage.init(".vh-talking>main>article>.main img"); setTimeout(() => (ViewImage && ViewImage.init(".vh-talking>main>article>.main img, .vh-comment>.twikoo>.tk-comments img:not(.tk-avatar-img,.tk-owo-emotion,.OwO-item img)")));
// 灯箱JS初始化====== // 灯箱JS初始化======
} catch { } catch {
vh.Toast('获取数据失败') vh.Toast('获取数据失败')

View File

@ -18,6 +18,7 @@ export default async (videoList: any[]) => {
video: { video: {
url: i.getAttribute("data-url"), url: i.getAttribute("data-url"),
type: "auto", type: "auto",
pic: i.getAttribute("data-poster") || '',
customType: { customType: {
hls: (video: any) => { hls: (video: any) => {
if (Hls.isSupported()) { if (Hls.isSupported()) {

View File

@ -195,11 +195,12 @@ section.vh-container {
// 其下面的 a 标签样式 // 其下面的 a 标签样式
a { a {
box-shadow: inset 0 -.12em #60a5fa; color: #280F25;
box-shadow: inset 0 -.12rem #60a5fa;
transition: box-shadow .2s ease-in-out, color .2s ease-in-out; transition: box-shadow .2s ease-in-out, color .2s ease-in-out;
&:hover { &:hover {
box-shadow: inset 0 -1.5em #60a5fa7f box-shadow: inset 0 -1.5rem #60a5fa66;
} }
} }
@ -221,14 +222,17 @@ section.vh-container {
} }
blockquote { blockquote {
padding: 0.188rem 0.58rem; margin: 1rem 0 1.618rem;
border-left: 5px solid #eee; padding: 0 0.88rem;
border-left-color: #929292; border-left: 0.288rem solid #49b1f5;
background-color: #f3f5f7; background-color: rgba(73, 177, 245, 0.1);
border-radius: 0.618rem;
&>p { &>p {
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 500; font-weight: 500;
line-height: 1.58rem;
color: #6A737D;
} }
} }
@ -492,6 +496,7 @@ section.vh-container {
// ::vhVideo // ::vhVideo
&.vh-vhVideo { &.vh-vhVideo {
margin: 1.188rem 0; margin: 1.188rem 0;
box-sizing: border-box;
width: 100%; width: 100%;
aspect-ratio: 16 / 9; aspect-ratio: 16 / 9;
border: solid 1px #E8E8E8; border: solid 1px #E8E8E8;

View File

@ -58,12 +58,14 @@
font-size: 0.875rem; font-size: 0.875rem;
line-height: 28px; line-height: 28px;
a { a {
box-shadow: inset 0 -.12em #60a5fa; color: #280F25;
box-shadow: inset 0 -.12rem #60a5fa;
transition: box-shadow .2s ease-in-out, color .2s ease-in-out; transition: box-shadow .2s ease-in-out, color .2s ease-in-out;
&:hover { &:hover {
box-shadow: inset 0 -1.5em #60a5fa7f box-shadow: inset 0 -1.5rem #60a5fa66;
} }
} }
} }