超级加倍优化更新

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

View File

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

View File

@ -3,16 +3,10 @@ import { visit } from 'unist-util-visit';
import getReadingTime from 'reading-time';
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 = () => {
return (tree: any, { data: astroData }: any) => {
visit(tree, (node, index, parent) => {
visit(tree, (node) => {
const { type, name, attributes } = node;
// 处理组件
if (type == 'textDirective' || type == 'leafDirective' || type == 'containerDirective') {
@ -31,10 +25,6 @@ const remarkNote = () => {
if (name.startsWith('vh')) {
Object.keys(node.attributes).forEach((i: any) => (hProperties[`data-${i}`] = node.attributes[i]));
}
// 处理 note 内容换行问题
if (name == 'note') {
nodeTreeFmt(node, parent);
};
// 设置 class
hProperties.class = `vh-node vh-${name}${attributes.type ? ` ${name}-${attributes.type}` : ''}`;
// 文章字数统计
@ -48,7 +38,7 @@ const remarkNote = () => {
}
// Pre中的 Copy 按钮
// 处理 HTML 标签
const addClassNames = () => {
return (tree: any) => {
visit(tree, (node, index, parent) => {
@ -56,19 +46,22 @@ const addClassNames = () => {
if (node.tagName === 'a') {
node.properties.target = '_blank', node.properties.rel = 'noopener nofollow'
node.children = [{ type: 'element', tagName: 'span', children: node.children || [] }];
}
// 处理代码快
if (node.tagName === 'pre') {
// 处理 pre 标签
} else 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] };
// 替换父节点的 children 中的 pre 节点为新的 div 节点
if (parent && index !== null) parent.children.splice(index, 1, divNode);
}
// 处理图片
if (node.tagName === 'img') {
// 处理 img 标签
} else if (node.tagName === 'img') {
// 添加 class 和 loading 属性
node.properties.class = 'vh-article-img';
node.properties['data-vh-lz-src'] = node.properties.src;
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;
};
// 返回顶部事件
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
let backTop: any = document.querySelector(".vh-back-top");

View File

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

View File

@ -8,14 +8,14 @@ declare const twikoo: any;
// 处理评论区数据
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
document.querySelectorAll('.vh-comment a[href="#"]').forEach(link => link.removeAttribute('href'));
}
// 初始化评论插件
export default async () => {
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>'
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) })

View File

@ -1,6 +1,8 @@
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";
// 初始化音乐播放器
@ -17,6 +19,8 @@ import initLinkCurrent from "../scripts/Header";
import initWebSiteTime from "../scripts/Footer";
// 友情链接初始化
import initLinks from "../scripts/Links";
// 朋友圈 RSS 初始化
import initFriends from "../scripts/Friends";
// 动态说说初始化
import initTalking from "../scripts/Talking";
// 文章评论初始化
@ -36,6 +40,8 @@ import { LoadScript } from "../utils/index";
const videoList: any[] = [];
const MusicList: any[] = [];
const indexInit = async (only: boolean = true) => {
// 鼠标滚动阻尼效果
only && LenisInit();
// 预加载搜索数据
only && searchFn("");
// 初始化搜索功能
@ -48,14 +54,16 @@ const indexInit = async (only: boolean = true) => {
only && initMobileSidebar();
// 顶部导航 Current 状态
initLinkCurrent()
// 初始化文章代码块
codeInit();
// 文章评论初始化
initComment();
// 初始化文章功能脚本
ArticleInit();
// 图片懒加载初始化
vhLzImgInit();
// 友情链接初始化
initLinks();
// 朋友圈 RSS 初始化
initFriends();
// 动态说说初始化
initTalking();
// 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'
// 更新数据
@ -48,7 +47,10 @@ const vhSearchInit = () => {
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 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"));
// 禁止默认事件
searchMainDOM.addEventListener("click", (e: Event) => e.stopPropagation());

View File

@ -21,7 +21,7 @@ const TalkingInit = async (data: any) => {
// 图片懒加载
vhLzImgInit();
// 灯箱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初始化======
} catch {
vh.Toast('获取数据失败')

View File

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

View File

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

View File

@ -58,12 +58,14 @@
font-size: 0.875rem;
line-height: 28px;
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;
&:hover {
box-shadow: inset 0 -1.5em #60a5fa7f
box-shadow: inset 0 -1.5rem #60a5fa66;
}
}
}