test new html

This commit is contained in:
ZSCGR
2026-05-03 11:08:49 +08:00
committed by GitHub
parent ccaa50a35e
commit a774b46eb8
+190 -240
View File
@@ -1,270 +1,220 @@
<!DOCTYPE html>
<html lang="en">
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZSCGR Star 导航</title>
<link href="https://fastly.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<style>
/* 其他样式 */
body {
background-image: url('https://pic.chgr.cc/random?dir=cover&type=img');
background-size: 100% 100%;
background-position: center;
background-attachment: fixed;
}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZSCGR GitHub Star 导航</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lykmapipo/[email protected]/css/themify-icons.css">
<style>
/* 基础样式复刻 */
* { padding: 0; margin: 0; box-sizing: border-box; }
li { list-style: none; }
a { text-decoration: none; color: inherit; }
body { font-size: 14px; color: #4d4d4d; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif; background: #f3f6f8; }
.repo-card {
@apply flex-grow flex-shrink-0 w-full sm:w-1/2 md:w-1/3 lg:w-1/3 xl:w-1/4 2xl:w-1/5 p-4;
}
/* 布局容器 */
.container { display: flex; }
.repo-card .px-6.pt-4.pb-2 {
display: flex; /* 将父元素改为 flex 布局 */
flex-wrap: wrap; /* 允许标签换行 */
}
/* 标签容器样式 */
.topics-container {
display: -webkit-box; /* 启用 WebKit 特性 */
-webkit-box-orient: vertical; /* 设置垂直方向 */
-webkit-line-clamp: 3; /* 限制显示三行 */
overflow: hidden; /* 隐藏溢出内容 */
position: relative; /* 使伪元素相对于容器定位 */
max-height: 6em; /* 三行高度,根据实际情况调整 */
line-height: 2em; /* 行高,根据实际情况调整 */
text-overflow: ellipsis; /* 在截断处显示省略号 */
}
/* 左侧侧边栏 */
.left-bar {
position: fixed;
background: #30333c;
color: #6b7386;
height: 100vh;
width: 248px;
display: flex;
flex-direction: column;
transition: all .3s;
z-index: 1000;
}
.big-logo { height: 160px; display: flex; align-items: center; justify-content: center; padding: 20px; }
.big-logo img { width: 100px; height: 100px; border-radius: 50%; background: #fff; padding: 5px; }
.left-bar .title { color: white; font-size: 18px; text-align: center; padding: 10px 0; font-weight: bold; }
.left-bar .nav { flex: 1; overflow-y: auto; }
.nav-item li a {
display: block; padding: 12px 25px; color: #aeb2b7; font-size: 14px; transition: all .3s;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nav-item li:hover a, .nav-item li.active a { color: #fff; background: #393e4a; }
/* 伪元素样式 */
.topics-container::after {
content: "...";
position: absolute; /* 绝对定位 */
bottom: 0; /* 与容器底部对齐 */
right: 0; /* 与容器右侧对齐 */
padding-left: 0.25rem; /* 添加左边距 */
background-color: white; /* 背景色,与容器背景色相同 */
}
/* 主体内容区 */
.main { margin-left: 248px; flex: 1; min-height: 100vh; position: relative; }
.header-tools { background: #fff; padding: 15px 30px; display: flex; align-items: center; box-shadow: 0 2px 4px rgba(0,0,0,0.05); position: sticky; top: 0; z-index: 900; }
#search { width: 300px; padding: 8px 15px; border: 1px solid #e4ecf3; border-radius: 20px; outline: none; background: #f9f9f9; }
.topic {
@apply inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2;
flex: 0 1 auto;
box-sizing: border-box;
line-height: 2; /* 设置您想要的行高 */
}
.content-wrapper { padding: 20px 30px; }
.about-box { background: #fff; padding: 15px 20px; border-radius: 8px; margin-bottom: 25px; color: #666; box-shadow: 0 2px 10px rgba(0,0,0,0.02); }
/* 仓库卡片样式 */
.category-title { font-size: 18px; font-weight: bold; margin: 30px 0 15px 5px; display: flex; align-items: center; }
.category-title i { margin-right: 10px; color: #3a85ff; }
.repo-card {
flex-basis: calc(33.333% - 2rem);
height: 66vh;
overflow: hidden;
}
.repo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; }
.repo-card {
background: #fff; padding: 15px; border-radius: 10px; border: 1px solid #e4ecf3;
transition: all .3s; display: flex; align-items: flex-start; cursor: pointer;
}
.repo-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.05); border-color: #3a85ff; }
.repo-avatar { width: 45px; height: 45px; border-radius: 50%; margin-right: 15px; flex-shrink: 0; border: 1px solid #eee; }
.repo-info { flex: 1; overflow: hidden; }
.repo-name { font-weight: bold; font-size: 15px; color: #3273dc; margin-bottom: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.repo-desc { font-size: 12px; color: #888; line-height: 1.5; height: 36px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.repo-meta { margin-top: 10px; display: flex; gap: 10px; font-size: 11px; color: #999; }
.repo-meta span { display: flex; align-items: center; }
.repo-meta i { margin-right: 3px; }
@media (max-width: 768px) {
.repo-card {
flex-basis: calc(50% - 2rem);
}
}
/* 回到顶部 */
#fixedBar { position: fixed; right: 20px; bottom: 30px; background: #fff; width: 40px; height: 40px; border-radius: 50%; display: none; align-items: center; justify-content: center; box-shadow: 0 2px 10px rgba(0,0,0,0.2); cursor: pointer; z-index: 1001; }
@media (max-width: 480px) {
.repo-card {
flex-basis: 100%;
}
}
/* 移动端菜单按钮 */
#mobile-menu-btn { display: none; font-size: 20px; cursor: pointer; margin-right: 15px; }
.repo-card .text-gray-700 {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
#back-to-top {
position: fixed;
bottom: 20px;
right: 20px;
display: none;
padding: 10px 15px;
background-color: tan;
color: white;
border-radius: 5px;
cursor: pointer;
}
#sidebar {
position: fixed;
top: 0;
left: 0;
height: 100%;
overflow-y: auto;
background-color: tan;
padding: 20px;
width: 167px;
}
#main-content {
margin-left: 167px;
padding-top: 0;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 12px;
background-color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
background-color: tan;
padding: 4px 12px;
}
.header h1 {
margin: 0;
}
.search-container {
margin-left: auto;
}
#search {
width: 300px;
}
.repo-card .repo-stats {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
/* 响应式 */
@media screen and (max-width: 768px) {
.left-bar { left: -248px; }
.left-bar.active { left: 0; }
.main { margin-left: 0; }
#mobile-menu-btn { display: block; }
#search { width: 100%; }
}
</style>
</head>
<body class="bg-gray-100">
<div class="header flex justify-between items-center px-4 py-2 bg-white shadow-md">
<h1 class="text-2xl font-bold">
<a href="/" class="text-blue-500 hover:underline">ZSCGR github Star 导航</a>
</h1>
<input id="search" type="text" placeholder="Search repositories..." class="p-2 border rounded w-1/3 mx-auto">
</div>
<div class="container mx-auto p-4">
<div class="flex">
<div id="sidebar">
<h2 class="text-xl font-bold mb-4">语言分类</h2>
<ul id="sidebarLinks">
<!-- 语言分类链接将在这里动态生成 -->
</ul>
</div>
<div id="main-content">
<div id="categories-container">
<!-- 仓库卡片将在这里动态生成 -->
</div>
</div>
</div>
</div>
<button id="back-to-top"></button>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('search');
const categoriesContainer = document.getElementById('categories-container');
const sidebarLinks = document.getElementById('sidebarLinks');
const backToTopButton = document.getElementById('back-to-top');
<body>
fetch('https://raw.githubusercontent.com/ZSCGR/some-stars/main/data.json')
.then(response => response.json())
<div class="container">
<aside class="left-bar" id="sidebar">
<div class="big-logo">
<img src="https://github.com/identicons/zscgr.png" alt="logo">
</div>
<div class="title">个人导航</div>
<nav class="nav">
<ul class="nav-item" id="sidebarLinks">
</ul>
</nav>
</aside>
<section class="main">
<header class="header-tools">
<div id="mobile-menu-btn" onclick="toggleSidebar()"><i class="ti-menu"></i></div>
<input id="search" type="text" placeholder="搜索仓库、描述或标签...">
</header>
<div class="content-wrapper">
<div class="about-box">
<i class="ti-pencil-alt"></i> 本导航页仅供个人使用,同步自 GitHub Star 数据。
</div>
<div id="categories-container">
<div style="text-align: center; padding: 50px; color: #999;">正在加载 GitHub Stars 数据...</div>
</div>
</div>
<div id="fixedBar" onclick="window.scrollTo({top: 0, behavior: 'smooth'})">
<i class="ti-arrow-up"></i>
</div>
</section>
</div>
<script>
const categoriesContainer = document.getElementById('categories-container');
const sidebarLinks = document.getElementById('sidebarLinks');
const searchInput = document.getElementById('search');
let allData = {};
// 1. 获取数据
fetch('https://raw.githubusercontent.com/ZSCGR/some-stars/main/data.json')
.then(res => res.json())
.then(data => {
generateContent(data);
searchInput.addEventListener('input', function() {
const query = this.value.trim().toLowerCase();
searchAndDisplay(query, data);
});
allData = data;
renderContent(data);
})
.catch(err => {
categoriesContainer.innerHTML = `<div style="color:red; text-align:center;">加载失败,请检查网络或数据源。</div>`;
});
function generateContent(data) {
// 2. 渲染函数
function renderContent(data) {
let categoriesHtml = '';
let sidebarLinksHtml = '';
let sidebarHtml = '';
for (const language in data) {
categoriesHtml += `
<div id="${language}" class="mb-8 category">
<h2 class="text-2xl font-bold mb-4">${language} Repositories</h2>
<div class="flex flex-wrap justify-center">
${generateRepoCards(data[language])}
</div>
</div>
`;
sidebarLinksHtml += `
<li class="mb-2"><a href="#${language}" class="text-blue-500 hover:underline">${language}</a></li>
`;
for (const lang in data) {
if (data[lang].length === 0) continue;
// 侧边栏
sidebarHtml += `<li><a href="#${lang}"><i class="ti-folder"></i> ${lang}</a></li>`;
// 内容区块
categoriesHtml += `
<div id="${lang}">
<div class="category-title"><i class="ti-tag"></i> ${lang}</div>
<div class="repo-grid">
${data[lang].map(repo => createCard(repo)).join('')}
</div>
</div>
`;
}
categoriesContainer.innerHTML = categoriesHtml;
sidebarLinks.innerHTML = sidebarLinksHtml;
}
sidebarLinks.innerHTML = sidebarHtml;
}
function generateRepoCards(repos) {
return repos.map(repo => `
<div class="repo-card max-w-sm rounded-2xl overflow-hidden shadow-lg m-4 bg-white transition-transform transform hover:scale-105">
<div class="h-48 overflow-hidden flex items-center justify-center mt-4 rounded-t-2xl">
<img class="object-contain h-full w-full rounded-t-2xl" src="${repo.owner.avatar_url}" alt="${repo.owner.login}">
// 3. 创建卡片 HTML
function createCard(repo) {
return `
<div class="repo-card" onclick="window.open('${repo.html_url}', '_blank')">
<img class="repo-avatar" src="${repo.owner.avatar_url}" alt="avatar">
<div class="repo-info">
<div class="repo-name">${repo.name}</div>
<div class="repo-desc">${repo.description || '暂无描述'}</div>
<div class="repo-meta">
<span><i class="ti-star"></i> ${repo.stargazers_count}</span>
<span><i class="ti-eye"></i> ${repo.watchers_count}</span>
</div>
</div>
</div>
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">
<a href="${repo.html_url}" class="text-blue-500">${repo.full_name}</a>
</div>
<p class="text-gray-700 text-base">${truncateDescription(repo.description)}</p>
</div>
<div class="px-6 pt-4 pb-2 topics-container">
${repo.topics.map(topic => `<span class="topic inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#${topic}</span>`).join('')}
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-blue-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">Stars: ${repo.stargazers_count}</span>
<span class="inline-block bg-green-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">Watchers: ${repo.watchers_count}</span>
</div>
</div>
`).join('');
}
`;
}
function truncateDescription(description) {
return description && description.length > 200 ? description.slice(0, 200) + '...' : description;
}
function searchAndDisplay(query, data) {
if (query) {
const matchedRepos = [];
for (const language in data) {
matchedRepos.push(...data[language].filter(repo => {
return repo.full_name.toLowerCase().includes(query) ||
(repo.description && repo.description.toLowerCase().includes(query)) ||
repo.topics.some(topic => topic.toLowerCase().includes(query));
}));
}
categoriesContainer.innerHTML = `
<div class="mb-8">
<h2 class="text-2xl font-bold mb-4">Search Results</h2>
<div class="flex flex-wrap justify-center">
${generateRepoCards(matchedRepos)}
</div>
</div>
`;
} else {
generateContent(data);
// 4. 搜索逻辑
searchInput.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
if (!query) {
renderContent(allData);
return;
}
}
window.addEventListener('scroll', function() {
if (window.scrollY > 200) {
backToTopButton.style.display = 'block';
} else {
backToTopButton.style.display = 'none';
let searchResults = [];
for (const lang in allData) {
const filtered = allData[lang].filter(repo =>
repo.name.toLowerCase().includes(query) ||
(repo.description && repo.description.toLowerCase().includes(query))
);
searchResults = searchResults.concat(filtered);
}
});
backToTopButton.addEventListener('click', function() {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
categoriesContainer.innerHTML = `
<div class="category-title"><i class="ti-search"></i> 搜索结果</div>
<div class="repo-grid">
${searchResults.length ? searchResults.map(repo => createCard(repo)).join('') : '<p style="padding:20px; color:#999;">未找到相关仓库</p>'}
</div>
`;
});
</script>
// 5. 辅助功能:移动端侧边栏切换
function toggleSidebar() {
document.getElementById('sidebar').classList.toggle('active');
}
// 6. 辅助功能:回到顶部显示
window.addEventListener('scroll', () => {
const btn = document.getElementById('fixedBar');
btn.style.display = window.scrollY > 300 ? 'flex' : 'none';
});
</script>
</body>
</html>