优化搜索后自动关闭搜索框,添加相关页面
This commit is contained in:
parent
474c777bbd
commit
864d134acd
File diff suppressed because it is too large
Load Diff
@ -105,5 +105,36 @@ const { title = SITE_NAME, description = SITE_DESCRIPTION, date, author, tags, i
|
||||
<slot />
|
||||
</main>
|
||||
<Footer icp={ICP} psbIcp={PSB_ICP} psbIcpUrl={PSB_ICP_URL} />
|
||||
|
||||
<!-- 预获取脚本 -->
|
||||
<script>
|
||||
// 在DOM加载完成后执行
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
// 获取所有视口预获取链接
|
||||
const viewportLinks = document.querySelectorAll('[data-astro-prefetch="viewport"]');
|
||||
|
||||
if (viewportLinks.length > 0) {
|
||||
// 创建一个交叉观察器
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const link = entry.target;
|
||||
// 进入视口时,添加data-astro-prefetch="true"属性触发预获取
|
||||
if (link.getAttribute('data-astro-prefetch') === 'viewport') {
|
||||
link.setAttribute('data-astro-prefetch', 'true');
|
||||
}
|
||||
// 一旦预获取,就不再观察这个链接
|
||||
observer.unobserve(link);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 观察所有视口预获取链接
|
||||
viewportLinks.forEach(link => {
|
||||
observer.observe(link);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -81,17 +81,69 @@ const breadcrumbs = section ? section.split("/") : [];
|
||||
|
||||
// 获取相关文章
|
||||
const allArticles = await getCollection("articles");
|
||||
const relatedArticles = allArticles
|
||||
|
||||
// 1. 尝试通过标签匹配相关文章
|
||||
let relatedArticles = allArticles
|
||||
.filter(
|
||||
(a) =>
|
||||
a.id !== article.id &&
|
||||
a.data.tags &&
|
||||
article.data.tags &&
|
||||
a.data.tags.some((tag) => article.data.tags?.includes(tag)),
|
||||
(a) => {
|
||||
const hasCommonTags = a.id !== article.id &&
|
||||
a.data.tags &&
|
||||
article.data.tags &&
|
||||
a.data.tags.length > 0 &&
|
||||
article.data.tags.length > 0 &&
|
||||
a.data.tags.some((tag) => article.data.tags?.includes(tag));
|
||||
|
||||
return hasCommonTags;
|
||||
}
|
||||
)
|
||||
.sort((a, b) => b.data.date.getTime() - a.data.date.getTime())
|
||||
.slice(0, 3);
|
||||
|
||||
// 跟踪相关文章的匹配方式: "tag", "directory", "latest"
|
||||
let relatedArticlesMatchType = relatedArticles.length > 0 ? "tag" : "";
|
||||
|
||||
// 2. 如果标签匹配没有找到足够的相关文章,尝试根据目录结构匹配
|
||||
if (relatedArticles.length < 3) {
|
||||
// 获取当前文章的目录路径
|
||||
const currentPath = article.id.includes('/')
|
||||
? article.id.substring(0, article.id.lastIndexOf('/'))
|
||||
: '';
|
||||
|
||||
// 如果有目录路径,查找同目录的其他文章
|
||||
if (currentPath) {
|
||||
// 收集同目录下的文章,但排除已经通过标签匹配的和当前文章
|
||||
const dirRelatedArticles = allArticles
|
||||
.filter(a =>
|
||||
a.id !== article.id &&
|
||||
a.id.startsWith(currentPath + '/') &&
|
||||
!relatedArticles.some(r => r.id === a.id)
|
||||
)
|
||||
.sort((a, b) => b.data.date.getTime() - a.data.date.getTime())
|
||||
.slice(0, 3 - relatedArticles.length);
|
||||
|
||||
if (dirRelatedArticles.length > 0) {
|
||||
relatedArticles = [...relatedArticles, ...dirRelatedArticles];
|
||||
relatedArticlesMatchType = relatedArticles.length > 0 && !relatedArticlesMatchType ? "directory" : relatedArticlesMatchType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果仍然没有找到足够的相关文章,则选择最新的文章(排除当前文章和已选择的文章)
|
||||
if (relatedArticles.length < 3) {
|
||||
const latestArticles = allArticles
|
||||
.filter(a =>
|
||||
a.id !== article.id &&
|
||||
!relatedArticles.some(r => r.id === a.id)
|
||||
)
|
||||
.sort((a, b) => b.data.date.getTime() - a.data.date.getTime())
|
||||
.slice(0, 3 - relatedArticles.length);
|
||||
|
||||
if (latestArticles.length > 0) {
|
||||
relatedArticles = [...relatedArticles, ...latestArticles];
|
||||
relatedArticlesMatchType = relatedArticles.length > 0 && !relatedArticlesMatchType ? "latest" : relatedArticlesMatchType;
|
||||
}
|
||||
}
|
||||
|
||||
// 准备文章描述
|
||||
const description =
|
||||
article.data.summary ||
|
||||
@ -147,6 +199,7 @@ function getArticleUrl(articleId: string) {
|
||||
<a
|
||||
href={`/articles${view ? `/${view}` : ""}`}
|
||||
class="text-secondary-500 dark:text-secondary-400 hover:text-primary-600 dark:hover:text-primary-400 flex items-center text-sm"
|
||||
data-astro-prefetch="hover"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -196,7 +249,6 @@ function getArticleUrl(articleId: string) {
|
||||
{article.data.date.toLocaleDateString("zh-CN")}
|
||||
</time>
|
||||
|
||||
{/* 显示文章所在目录 */}
|
||||
{
|
||||
section && (
|
||||
<span class="flex items-center">
|
||||
@ -232,6 +284,7 @@ function getArticleUrl(articleId: string) {
|
||||
<a
|
||||
href={`/articles?tag=${tag}`}
|
||||
class="text-xs bg-primary-50 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 py-1 px-2 rounded hover:bg-primary-100 dark:hover:bg-primary-800/30"
|
||||
data-astro-prefetch="hover"
|
||||
>
|
||||
#{tag}
|
||||
</a>
|
||||
@ -322,13 +375,15 @@ function getArticleUrl(articleId: string) {
|
||||
relatedArticles.length > 0 && (
|
||||
<div class="mt-12 pt-8 border-t border-secondary-200 dark:border-dark-border">
|
||||
<h2 class="text-2xl font-bold mb-6 text-primary-900 dark:text-primary-100">
|
||||
相关文章
|
||||
{relatedArticlesMatchType === "tag" ? "相关文章" :
|
||||
relatedArticlesMatchType === "directory" ? "同类文章" : "推荐阅读"}
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{relatedArticles.map((relatedArticle) => (
|
||||
<a
|
||||
href={getArticleUrl(relatedArticle.id)}
|
||||
class="block p-5 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-dark-card hover:shadow-xl hover:-translate-y-1 shadow-lg"
|
||||
data-astro-prefetch="viewport"
|
||||
>
|
||||
<h3 class="font-bold text-lg mb-2 line-clamp-2 text-gray-800 dark:text-gray-200 hover:text-primary-700 dark:hover:text-primary-400">
|
||||
{relatedArticle.data.title}
|
||||
|
@ -222,7 +222,8 @@ function getArticleUrl(articleId: string) {
|
||||
viewMode === 'grid'
|
||||
? 'text-primary-600'
|
||||
: 'text-gray-400 hover:text-gray-500'
|
||||
}`}>
|
||||
}`}
|
||||
data-astro-prefetch="hover">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
|
||||
</svg>
|
||||
@ -232,7 +233,8 @@ function getArticleUrl(articleId: string) {
|
||||
viewMode === 'timeline'
|
||||
? 'text-primary-600'
|
||||
: 'text-gray-400 hover:text-gray-500'
|
||||
}`}>
|
||||
}`}
|
||||
data-astro-prefetch="hover">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z" />
|
||||
</svg>
|
||||
@ -249,7 +251,8 @@ function getArticleUrl(articleId: string) {
|
||||
{/* 上一级目录卡片 - 仅在浏览目录时显示 */}
|
||||
{!tagFilter && pathSegments.length > 0 && (
|
||||
<a href={`/articles/${pathSegments.length > 1 ? pathSegments.slice(0, -1).join('/') : ''}/${view}`}
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg">
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg"
|
||||
data-astro-prefetch="hover">
|
||||
<div class="flex items-center">
|
||||
<div class="w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@ -276,7 +279,8 @@ function getArticleUrl(articleId: string) {
|
||||
|
||||
return (
|
||||
<a href={`/articles/${dirLink}`}
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg">
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg"
|
||||
data-astro-prefetch="viewport">
|
||||
<div class="flex items-center">
|
||||
<div class="w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@ -319,7 +323,8 @@ function getArticleUrl(articleId: string) {
|
||||
// 显示标签过滤后的文章
|
||||
filteredArticles.map(article => (
|
||||
<a href={getArticleUrl(article.id)}
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg">
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg recent-article"
|
||||
data-astro-prefetch="viewport">
|
||||
<div class="flex items-start">
|
||||
<div class="w-10 h-10 flex-shrink-0 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@ -389,7 +394,8 @@ function getArticleUrl(articleId: string) {
|
||||
|
||||
return (
|
||||
<a href={`/articles/${article.id}`}
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg">
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 shadow-lg recent-article"
|
||||
data-astro-prefetch="viewport">
|
||||
<div class="flex items-start">
|
||||
<div class="w-10 h-10 flex-shrink-0 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@ -459,7 +465,8 @@ function getArticleUrl(articleId: string) {
|
||||
isActive
|
||||
? 'bg-primary-600 text-white dark:bg-primary-500 dark:text-gray-100 hover:bg-primary-700 dark:hover:bg-primary-600 shadow-md hover:shadow-lg'
|
||||
: 'bg-primary-50 dark:bg-gray-700/50 text-primary-600 dark:text-gray-300 hover:bg-primary-100 dark:hover:bg-gray-700 hover:text-primary-700 dark:hover:text-primary-400'
|
||||
}`}>
|
||||
}`}
|
||||
data-astro-prefetch="hover">
|
||||
{tag}
|
||||
</a>
|
||||
);
|
||||
@ -483,7 +490,8 @@ function getArticleUrl(articleId: string) {
|
||||
|
||||
{/* 文章卡片 */}
|
||||
<a href={`/articles/${article.id}${viewMode ? `/${viewMode}` : ''}`}
|
||||
class={`group/card ml-10 md:ml-0 ${isEven ? 'md:mr-[50%] md:pr-8' : 'md:ml-[50%] md:pl-8'} block`}>
|
||||
class={`group/card ml-10 md:ml-0 ${isEven ? 'md:mr-[50%] md:pr-8' : 'md:ml-[50%] md:pl-8'} block`}
|
||||
data-astro-prefetch="viewport">
|
||||
<article class="relative flex flex-col gap-4 rounded-xl bg-white dark:bg-gray-800 p-6 shadow-lg hover:shadow-xl hover:-translate-y-1 border border-gray-200 dark:border-gray-700">
|
||||
{/* 日期标签 */}
|
||||
<time datetime={article.data.date.toISOString()}
|
||||
|
Loading…
Reference in New Issue
Block a user