test new html
This commit is contained in:
+190
-240
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user