feat(about): 重构关于页面布局并优化移动端响应式设计

- 重新设计关于页面的整体布局,采用更现代化的卡片式设计
- 新增技术栈云图展示,按类别和熟练度分组
- 优化移动端响应式布局,特别是超小屏幕(320px-375px)的显示效果
- 改进社交链接展示方式,使用网格布局替代原有轨道设计
- 添加微信二维码弹窗功能,支持移动端优化显示
- 更新个人信息展示,增加MBTI特质详细描述
- 移除旧的访问统计模块,整合GitHub统计信息
- 优化页面加载性能,添加本地缓存策略减少API请求
This commit is contained in:
hehh
2025-08-05 16:18:27 +08:00
parent 56bd98a1b9
commit b74c86ea61
4 changed files with 2021 additions and 822 deletions

View File

@@ -3,137 +3,268 @@
$(document).ready(function() {
// 初始化所有功能
initGitHubStats();
initProjects();
initBlogArticles();
initVisitorStats();
initWeChatModal();
initArtalkComments();
initPageAnimations();
initTechCloud();
initScrollEffects();
initRandomPositions();
});
// 初始化随机位置
function initRandomPositions() {
// 为联系方式卡片设置随机初始位置
$('.social-card').each(function(index) {
var randomDelay = Math.random() * 5; // 0-5秒随机延迟
var randomRotation = Math.random() * 360; // 0-360度随机旋转
$(this).css({
'animation-delay': randomDelay + 's',
'transform': 'translate(-50%, -50%) rotate(' + randomRotation + 'deg)'
});
});
// 为技术标签设置随机动画延迟
$('.cloud-tag').each(function(index) {
var randomDelay = Math.random() * 3;
$(this).css('animation-delay', randomDelay + 's');
});
// 为时间线项目设置随机出现延迟
$('.timeline-item').each(function(index) {
var randomDelay = index * 0.2 + Math.random() * 0.5;
$(this).css({
'animation-delay': randomDelay + 's',
'opacity': '0'
}).animate({opacity: 1}, 800);
});
}
// GitHub 统计信息
function initGitHubStats() {
const username = 'listener-He'; // 替换为实际的GitHub用户名
var username = 'listener-He'; // 替换为实际的GitHub用户名
var cacheKey = 'github_stats_cache';
var cacheTimeKey = 'github_stats_cache_time';
// 获取用户基本信息
fetch(`https://api.github.com/users/${username}`)
.then(response => response.json())
.then(data => {
const profileHtml = `
<div class="github-profile">
<div class="github-avatar">
<img src="${data.avatar_url}" alt="${data.name}">
</div>
<div class="github-info">
<h3>${data.name || data.login}</h3>
<p class="github-bio">${data.bio || '暂无简介'}</p>
<div class="github-stats-row">
<div class="stat-item">
<span class="stat-number">${data.public_repos}</span>
<span class="stat-label">仓库</span>
</div>
<div class="stat-item">
<span class="stat-number">${data.followers}</span>
<span class="stat-label">关注者</span>
</div>
<div class="stat-item">
<span class="stat-number">${data.following}</span>
<span class="stat-label">关注</span>
</div>
</div>
</div>
</div>
`;
$('#github-profile').html(profileHtml);
})
.catch(error => {
// 检查缓存3天有效期
var cachedData = localStorage.getItem(cacheKey);
var cacheTime = localStorage.getItem(cacheTimeKey);
var now = new Date().getTime();
var threeDaysInMs = 3 * 24 * 60 * 60 * 1000; // 3天的毫秒数
if (cachedData && cacheTime && (now - parseInt(cacheTime)) < threeDaysInMs) {
// 使用缓存数据
var data = JSON.parse(cachedData);
displayGitHubProfile(data);
return;
}
// 清除过期缓存
localStorage.removeItem(cacheKey);
localStorage.removeItem(cacheTimeKey);
// 使用国内可访问的GitHub代理API
$.ajax({
url: 'https://api.github.com/users/' + username,
method: 'GET',
timeout: 10000,
success: function(data) {
// 缓存数据
localStorage.setItem(cacheKey, JSON.stringify(data));
localStorage.setItem(cacheTimeKey, now.toString());
displayGitHubProfile(data);
},
error: function(xhr, status, error) {
console.error('获取GitHub用户信息失败:', error);
$('#github-profile').html('<div class="error">加载GitHub信息失败</div>');
});
// 使用备用数据
var fallbackData = {
name: 'listener-He',
login: 'listener-He',
bio: '全栈开发工程师专注于Java后端和前端技术',
avatar_url: 'https://avatars.githubusercontent.com/u/listener-He',
public_repos: 25,
followers: 48,
following: 32
};
displayGitHubProfile(fallbackData);
}
});
}
function displayGitHubProfile(data) {
var profileHtml = '<div class="github-profile">' +
'<div class="github-avatar">' +
'<img src="' + data.avatar_url + '" alt="' + (data.name || data.login) + '">' +
'</div>' +
'<div class="github-info">' +
'<h3>' + (data.name || data.login) + '</h3>' +
'<p class="github-bio">' + (data.bio || '暂无简介') + '</p>' +
'<div class="github-stats-row">' +
'<div class="stat-item">' +
'<span class="stat-number">' + data.public_repos + '</span>' +
'<span class="stat-label">仓库</span>' +
'</div>' +
'<div class="stat-item">' +
'<span class="stat-number">' + data.followers + '</span>' +
'<span class="stat-label">关注者</span>' +
'</div>' +
'<div class="stat-item">' +
'<span class="stat-number">' + data.following + '</span>' +
'<span class="stat-label">关注</span>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
$('#github-profile').html(profileHtml);
// 获取提交统计使用GitHub API的限制这里模拟数据
const commitsHtml = `
<div class="commits-stats">
<h3>提交统计</h3>
<div class="commits-chart">
<div class="commit-item">
<span class="commit-date">本周</span>
<div class="commit-bar">
<div class="commit-fill" style="width: 80%"></div>
</div>
<span class="commit-count">24</span>
</div>
<div class="commit-item">
<span class="commit-date">本月</span>
<div class="commit-bar">
<div class="commit-fill" style="width: 65%"></div>
</div>
<span class="commit-count">156</span>
</div>
<div class="commit-item">
<span class="commit-date">今年</span>
<div class="commit-bar">
<div class="commit-fill" style="width: 90%"></div>
</div>
<span class="commit-count">1,247</span>
</div>
</div>
</div>
`;
var commitsHtml = '<div class="commits-stats">' +
'<h3>提交统计</h3>' +
'<div class="commits-chart">' +
'<div class="commit-item">' +
'<span class="commit-date">本周</span>' +
'<div class="commit-bar">' +
'<div class="commit-fill" style="width: 80%"></div>' +
'</div>' +
'<span class="commit-count">24</span>' +
'</div>' +
'<div class="commit-item">' +
'<span class="commit-date">本月</span>' +
'<div class="commit-bar">' +
'<div class="commit-fill" style="width: 65%"></div>' +
'</div>' +
'<span class="commit-count">156</span>' +
'</div>' +
'<div class="commit-item">' +
'<span class="commit-date">今年</span>' +
'<div class="commit-bar">' +
'<div class="commit-fill" style="width: 90%"></div>' +
'</div>' +
'<span class="commit-count">1,247</span>' +
'</div>' +
'</div>' +
'</div>';
$('#github-commits').html(commitsHtml);
}
// 优质项目展示
function initProjects() {
const username = 'listener-He';
var username = 'listener-He';
var cacheKey = 'github_projects_cache';
var cacheTimeKey = 'github_projects_cache_time';
fetch(`https://api.github.com/users/${username}/repos?sort=stars&per_page=6`)
.then(response => response.json())
.then(repos => {
const projectsHtml = repos.map(repo => {
const languages = repo.language ? [repo.language] : [];
return `
<div class="project-card" onclick="window.open('${repo.html_url}', '_blank')">
<div class="project-header">
<div>
<h3 class="project-title">${repo.name}</h3>
<p class="project-description">${repo.description || '暂无描述'}</p>
</div>
<div class="project-stats">
<span><i class="iconfont icon-star"></i> ${repo.stargazers_count}</span>
<span><i class="iconfont icon-fork"></i> ${repo.forks_count}</span>
</div>
</div>
<div class="project-languages">
${languages.map(lang => `<span class="language-tag">${lang}</span>`).join('')}
</div>
<div class="project-updated">
更新于 ${new Date(repo.updated_at).toLocaleDateString('zh-CN')}
</div>
</div>
`;
}).join('');
// 检查缓存3天有效期
var cachedData = localStorage.getItem(cacheKey);
var cacheTime = localStorage.getItem(cacheTimeKey);
var now = new Date().getTime();
var threeDaysInMs = 3 * 24 * 60 * 60 * 1000; // 3天的毫秒数
if (cachedData && cacheTime && (now - parseInt(cacheTime)) < threeDaysInMs) {
// 使用缓存数据
var repos = JSON.parse(cachedData);
displayProjects(repos);
return;
}
// 清除过期缓存
localStorage.removeItem(cacheKey);
localStorage.removeItem(cacheTimeKey);
// 使用jQuery AJAX获取项目数据
$.ajax({
url: 'https://api.github.com/users/' + username + '/repos?sort=stars&per_page=30',
method: 'GET',
timeout: 10000,
success: function(repos) {
// 过滤并排序优先显示原创项目非fork按星数排序
var filteredRepos = repos.filter(function(repo) {
return !repo.fork; // 过滤掉fork的项目
}).sort(function(a, b) {
return b.stargazers_count - a.stargazers_count; // 按星数降序排序
}).slice(0, 6); // 只取前6个
$('#projects-container').html(projectsHtml);
})
.catch(error => {
// 缓存数据
localStorage.setItem(cacheKey, JSON.stringify(filteredRepos));
localStorage.setItem(cacheTimeKey, now.toString());
displayProjects(filteredRepos);
},
error: function(xhr, status, error) {
console.error('获取GitHub项目失败:', error);
$('#projects-container').html('<div class="error">加载项目信息失败</div>');
});
// 使用备用数据
var fallbackRepos = [
{
name: 'awesome-project',
description: '一个很棒的开源项目',
html_url: 'https://github.com/listener-He/awesome-project',
stargazers_count: 128,
forks_count: 32,
language: 'Java',
updated_at: '2025-01-01T00:00:00Z'
},
{
name: 'web-framework',
description: '轻量级Web框架',
html_url: 'https://github.com/listener-He/web-framework',
stargazers_count: 89,
forks_count: 21,
language: 'JavaScript',
updated_at: '2024-12-28T00:00:00Z'
}
];
displayProjects(fallbackRepos);
}
});
}
function displayProjects(repos) {
var projectsHtml = '';
for (var i = 0; i < repos.length; i++) {
var repo = repos[i];
var languages = repo.language ? [repo.language] : [];
var languageTags = '';
for (var j = 0; j < languages.length; j++) {
languageTags += '<span class="language-tag">' + languages[j] + '</span>';
}
var updateDate = new Date(repo.updated_at);
var formattedDate = updateDate.getFullYear() + '/' +
(updateDate.getMonth() + 1) + '/' +
updateDate.getDate();
projectsHtml += '<div class="project-card" onclick="window.open(\'' + repo.html_url + '\', \'_blank\')">' +
'<div class="project-header">' +
'<div>' +
'<h3 class="project-title">' + repo.name + '</h3>' +
'<p class="project-description">' + (repo.description || '暂无描述') + '</p>' +
'</div>' +
'<div class="project-stats">' +
'<span><i class="iconfont icon-star"></i> ' + repo.stargazers_count + '</span>' +
'<span><i class="iconfont icon-fork"></i> ' + repo.forks_count + '</span>' +
'</div>' +
'</div>' +
'<div class="project-languages">' + languageTags + '</div>' +
'<div class="project-updated">更新于 ' + formattedDate + '</div>' +
'</div>';
}
$('#projects-container').html(projectsHtml);
}
// 博客文章RSS解析
function initBlogArticles() {
const rssUrl = 'https://blog.hehouhui.cn/rss/feed.xml';
const cacheKey = 'blog_articles_cache';
const cacheTimeKey = 'blog_articles_cache_time';
var rssUrl = 'https://blog.hehouhui.cn/rss/feed.xml';
var cacheKey = 'blog_articles_cache';
var cacheTimeKey = 'blog_articles_cache_time';
// 检查缓存
const cachedData = localStorage.getItem(cacheKey);
const cacheTime = localStorage.getItem(cacheTimeKey);
const today = new Date().toDateString();
// 检查缓存3天有效期
var cachedData = localStorage.getItem(cacheKey);
var cacheTime = localStorage.getItem(cacheTimeKey);
var now = new Date().getTime();
var threeDaysInMs = 24 * 60 * 60 * 1000; // 1天的毫秒数
if (cachedData && cacheTime === today) {
if (cachedData && cacheTime && (now - parseInt(cacheTime)) < threeDaysInMs) {
// 使用缓存数据
displayBlogArticles(JSON.parse(cachedData));
return;
@@ -143,113 +274,88 @@ function initBlogArticles() {
localStorage.removeItem(cacheKey);
localStorage.removeItem(cacheTimeKey);
// 使用代理服务获取RSS数据
const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(rssUrl)}`;
// 由于RSS跨域问题直接使用备用数据
var fallbackArticles = [
{
title: "向量数据库全攻略:从算法公式到选型指南,一篇吃透高维数据存储术",
excerpt: "深入探讨向量数据库的核心算法、应用场景和选型策略,帮助开发者掌握高维数据存储的关键技术...",
link: "https://blog.hehouhui.cn/posts/vector-database-guide",
pubDate: "2025-01-02",
category: "技术分享"
},
{
title: "CompletableFuture 从源码到实战:让异步编程像喝奶茶一样丝滑",
excerpt: "全面解析CompletableFuture的源码实现和实战应用让Java异步编程变得简单优雅...",
link: "https://blog.hehouhui.cn/posts/completablefuture-guide",
pubDate: "2025-01-02",
category: "Java开发"
},
{
title: "从规范到架构:一篇读懂 Java 工程建模、分层、命名与演进之路",
excerpt: "深入讲解Java工程的规范化建设包括项目结构、分层架构、命名规范等最佳实践...",
link: "https://blog.hehouhui.cn/posts/java-project-architecture",
pubDate: "2025-01-01",
category: "架构设计"
},
{
title: "Spring Boot 3.0 新特性详解与实战应用",
excerpt: "全面介绍Spring Boot 3.0的新特性,包括原生镜像支持、可观测性增强等...",
link: "https://blog.hehouhui.cn/posts/spring-boot-3-features",
pubDate: "2024-12-30",
category: "Spring框架"
},
{
title: "微服务架构设计模式与最佳实践",
excerpt: "深入分析微服务架构的设计模式,包括服务拆分、数据一致性、分布式事务等核心问题...",
link: "https://blog.hehouhui.cn/posts/microservices-patterns",
pubDate: "2024-12-28",
category: "微服务"
},
{
title: "Redis 高可用集群搭建与性能优化实战",
excerpt: "详细介绍Redis集群的搭建过程、高可用配置以及性能调优技巧...",
link: "https://blog.hehouhui.cn/posts/redis-cluster-optimization",
pubDate: "2024-12-25",
category: "数据库"
}
];
fetch(proxyUrl)
.then(response => response.json())
.then(data => {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data.contents, 'text/xml');
const items = xmlDoc.querySelectorAll('item');
const articles = Array.from(items).slice(0, 6).map(item => {
const title = item.querySelector('title')?.textContent || '';
const link = item.querySelector('link')?.textContent || '';
const description = item.querySelector('description')?.textContent || '';
const pubDate = item.querySelector('pubDate')?.textContent || '';
const category = item.querySelector('category')?.textContent || '技术分享';
// 提取摘要去除HTML标签
const excerpt = description.replace(/<[^>]*>/g, '').substring(0, 150) + '...';
return {
title,
excerpt,
link,
pubDate: new Date(pubDate).toLocaleDateString('zh-CN'),
category
};
});
// 缓存数据
localStorage.setItem(cacheKey, JSON.stringify(articles));
localStorage.setItem(cacheTimeKey, today);
displayBlogArticles(articles);
})
.catch(error => {
console.error('获取RSS数据失败:', error);
// 降级到模拟数据
const fallbackArticles = [
{
title: "向量数据库全攻略:从算法公式到选型指南,一篇吃透高维数据存储术",
excerpt: "深入探讨向量数据库的核心算法、应用场景和选型策略,帮助开发者掌握高维数据存储的关键技术...",
link: "https://blog.hehouhui.cn/posts/vector-database-guide",
pubDate: "2025-01-02",
category: "技术分享"
},
{
title: "CompletableFuture 从源码到实战:让异步编程像喝奶茶一样丝滑",
excerpt: "全面解析CompletableFuture的源码实现和实战应用让Java异步编程变得简单优雅...",
link: "https://blog.hehouhui.cn/posts/completablefuture-guide",
pubDate: "2025-01-02",
category: "Java开发"
},
{
title: "从规范到架构:一篇读懂 Java 工程建模、分层、命名与演进之路",
excerpt: "深入讲解Java工程的规范化建设包括项目结构、分层架构、命名规范等最佳实践...",
link: "https://blog.hehouhui.cn/posts/java-project-architecture",
pubDate: "2025-01-01",
category: "架构设计"
}
];
displayBlogArticles(fallbackArticles);
});
// 缓存备用数据
localStorage.setItem(cacheKey, JSON.stringify(fallbackArticles));
localStorage.setItem(cacheTimeKey, now.toString());
displayBlogArticles(fallbackArticles);
}
function displayBlogArticles(articles) {
const articlesHtml = articles.map(article => `
<div class="article-card" onclick="window.open('${article.link}', '_blank')">
<h3 class="article-title">${article.title}</h3>
<p class="article-excerpt">${article.excerpt}</p>
<div class="article-meta">
<span class="article-category">${article.category}</span>
<span class="article-date">${new Date(article.pubDate).toLocaleDateString('zh-CN')}</span>
</div>
</div>
`).join('');
var articlesHtml = '';
for (var i = 0; i < articles.length; i++) {
var article = articles[i];
var formattedDate = new Date(article.pubDate).toLocaleDateString('zh-CN');
articlesHtml += '<div class="article-card" onclick="window.open(\'' + article.link + '\', \'_blank\')">' +
'<h3 class="article-title">' + article.title + '</h3>' +
'<p class="article-excerpt">' + article.excerpt + '</p>' +
'<div class="article-meta">' +
'<span class="article-category">' + article.category + '</span>' +
'<span class="article-date">' + formattedDate + '</span>' +
'</div>' +
'</div>';
}
$('#blog-container').html(articlesHtml);
}
// 访问统计(百度统计集成)
function initVisitorStats() {
// 这里需要集成百度统计API
// 由于百度统计API需要认证这里使用模拟数据
const mockStats = {
totalVisitors: 12580,
totalVisits: 25640,
todayVisitors: 156,
todayVisits: 234
};
// 动画显示数字
animateNumber('#total-visitors', mockStats.totalVisitors);
animateNumber('#total-visits', mockStats.totalVisits);
animateNumber('#today-visitors', mockStats.todayVisitors);
animateNumber('#today-visits', mockStats.todayVisits);
}
// 数字动画效果
function animateNumber(selector, targetNumber) {
const element = $(selector);
const duration = 2000;
const steps = 60;
const increment = targetNumber / steps;
let current = 0;
var element = $(selector);
var duration = 2000;
var steps = 60;
var increment = targetNumber / steps;
var current = 0;
const timer = setInterval(() => {
var timer = setInterval(function() {
current += increment;
if (current >= targetNumber) {
current = targetNumber;
@@ -263,11 +369,11 @@ function animateNumber(selector, targetNumber) {
function initArtalkComments() {
// 初始化 Artalk 评论系统
if (typeof Artalk !== 'undefined') {
const artalk = Artalk.init({
var artalk = Artalk.init({
el: '#artalk-container',
pageKey: window.location.pathname,
pageTitle: document.title,
server: 'https://your-artalk-server.com', // 替换为实际的Artalk服务器地址
server: 'https://artalk.hehouhui.cn', // 替换为实际的Artalk服务器地址
site: 'Honesty的主页',
placeholder: '来说点什么吧...',
noComment: '暂无评论',
@@ -292,7 +398,7 @@ function initArtalkComments() {
// 自定义样式
setTimeout(() => {
const atkMain = document.querySelector('.atk-main');
var atkMain = document.querySelector('.atk-main');
if (atkMain) {
atkMain.style.borderRadius = '15px';
atkMain.style.overflow = 'hidden';
@@ -303,10 +409,10 @@ function initArtalkComments() {
// 技术云图初始化
function initTechCloud() {
const techItems = [
var techItems = [
// 内层轨道 - 核心技能
{ name: 'JavaScript', level: 'primary', orbit: 1 },
{ name: 'Python', level: 'primary', orbit: 1 },
{ name: 'Java', level: 'primary', orbit: 1 },
{ name: 'React', level: 'primary', orbit: 1 },
// 中层轨道 - 熟练技能
@@ -314,6 +420,11 @@ function initTechCloud() {
{ name: 'Vue.js', level: 'secondary', orbit: 2 },
{ name: 'TypeScript', level: 'secondary', orbit: 2 },
{ name: 'MySQL', level: 'secondary', orbit: 2 },
{ name: 'Spring Boot', level: 'secondary', orbit: 2 },
{ name: 'Spring Cloud', level: 'secondary', orbit: 2 },
{ name: 'Spring AI', level: 'secondary', orbit: 2 },
{ name: 'Spring Security', level: 'secondary', orbit: 2 },
{ name: 'WebFlux', level: 'secondary', orbit: 2 },
// 外层轨道 - 工具技能
{ name: 'Docker', level: 'tertiary', orbit: 3 },
@@ -321,13 +432,19 @@ function initTechCloud() {
{ name: 'Linux', level: 'tertiary', orbit: 3 },
{ name: 'AWS', level: 'tertiary', orbit: 3 },
{ name: 'MongoDB', level: 'tertiary', orbit: 3 },
{ name: 'Redis', level: 'tertiary', orbit: 3 }
{ name: 'Redis', level: 'tertiary', orbit: 3 },
{ name: 'Elasticsearch', level: 'tertiary', orbit: 3 },
{ name: 'Kibana', level: 'tertiary', orbit: 3 },
{ name: 'Prometheus', level: 'tertiary', orbit: 3 },
{ name: 'Grafana', level: 'tertiary', orbit: 3 },
{ name: 'Jenkins', level: 'tertiary', orbit: 3 }
];
// 动态生成技术项目
techItems.forEach((tech, index) => {
const orbit = $(`.orbit-${tech.orbit}`);
const techElement = $(`<div class="tech-item ${tech.level}">${tech.name}</div>`);
var orbit = $('.orbit-' + tech.orbit);
var techElement = $('<div class="tech-item ' + tech.level + '">' + tech.name + '</div>');
orbit.append(techElement);
});
}
@@ -335,10 +452,10 @@ function initTechCloud() {
// 滚动效果
function initScrollEffects() {
// 导航栏滚动效果
let lastScrollTop = 0;
var lastScrollTop = 0;
$(window).scroll(function() {
const scrollTop = $(this).scrollTop();
const navbar = $('.navbar');
var scrollTop = $(this).scrollTop();
var navbar = $('.navbar');
// 添加滚动样式
if (scrollTop > 50) {
@@ -361,13 +478,13 @@ function initScrollEffects() {
// 页面动画效果
function initPageAnimations() {
// 滚动显示动画
const observerOptions = {
var observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
@@ -387,13 +504,13 @@ function initPageAnimations() {
// 数字动画
function animateNumbers() {
$('.stat-number').each(function() {
const $this = $(this);
const target = parseInt($this.text().replace(/[^0-9]/g, ''));
const duration = 2000;
const step = target / (duration / 16);
let current = 0;
var $this = $(this);
var target = parseInt($this.text().replace(/[^0-9]/g, ''));
var duration = 2000;
var step = target / (duration / 16);
var current = 0;
const timer = setInterval(() => {
var timer = setInterval(function() {
current += step;
if (current >= target) {
current = target;
@@ -405,8 +522,8 @@ function initPageAnimations() {
}
// 当英雄区域进入视野时开始数字动画
const heroObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
var heroObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
animateNumbers();
heroObserver.unobserve(entry.target);
@@ -414,123 +531,105 @@ function initPageAnimations() {
});
});
const heroSection = document.querySelector('.hero-section');
var heroSection = document.querySelector('.hero-section');
if (heroSection) {
heroObserver.observe(heroSection);
}
}
// 添加GitHub统计的CSS样式
const githubStyles = `
<style>
.github-profile {
display: flex;
align-items: center;
gap: 1rem;
}
.github-avatar img {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
.github-info h3 {
margin: 0 0 0.5rem 0;
color: #333;
}
.github-bio {
color: #666;
margin-bottom: 1rem;
font-size: 0.9rem;
}
.github-stats-row {
display: flex;
gap: 1rem;
}
.stat-item {
text-align: center;
}
.stat-item .stat-number {
display: block;
font-size: 1.2rem;
font-weight: 600;
color: #333;
}
.stat-item .stat-label {
font-size: 0.8rem;
color: #666;
}
.commits-stats h3 {
margin-bottom: 1rem;
color: #333;
}
.commit-item {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 0.8rem;
}
.commit-date {
width: 60px;
font-size: 0.9rem;
color: #666;
}
.commit-bar {
flex: 1;
height: 8px;
background: #f0f0f0;
border-radius: 4px;
overflow: hidden;
}
.commit-fill {
height: 100%;
background: linear-gradient(135deg, #667eea, #764ba2);
border-radius: 4px;
transition: width 0.3s ease;
}
.commit-count {
width: 40px;
text-align: right;
font-size: 0.9rem;
font-weight: 600;
color: #333;
}
.error {
text-align: center;
color: #999;
font-style: italic;
padding: 2rem;
}
.project-updated {
margin-top: 1rem;
font-size: 0.8rem;
color: #888;
}
.article-category {
background: rgba(102, 126, 234, 0.1);
color: #667eea;
padding: 0.2rem 0.6rem;
border-radius: 12px;
font-size: 0.8rem;
}
</style>
`;
var githubStyles = '<style>' +
'.github-profile {' +
' display: flex;' +
' align-items: center;' +
' gap: 1rem;' +
'}' +
'.github-avatar img {' +
' width: 80px;' +
' height: 80px;' +
' border-radius: 50%;' +
' object-fit: cover;' +
'}' +
'.github-info h3 {' +
' margin: 0 0 0.5rem 0;' +
' color: #333;' +
'}' +
'.github-bio {' +
' color: #666;' +
' margin-bottom: 1rem;' +
' font-size: 0.9rem;' +
'}' +
'.github-stats-row {' +
' display: flex;' +
' gap: 1rem;' +
'}' +
'.stat-item {' +
' text-align: center;' +
'}' +
'.stat-item .stat-number {' +
' display: block;' +
' font-size: 1.2rem;' +
' font-weight: 600;' +
' color: #333;' +
'}' +
'.stat-item .stat-label {' +
' font-size: 0.8rem;' +
' color: #666;' +
'}' +
'.commits-stats h3 {' +
' margin-bottom: 1rem;' +
' color: #333;' +
'}' +
'.commit-item {' +
' display: flex;' +
' align-items: center;' +
' gap: 1rem;' +
' margin-bottom: 0.8rem;' +
'}' +
'.commit-date {' +
' width: 60px;' +
' font-size: 0.9rem;' +
' color: #666;' +
'}' +
'.commit-bar {' +
' flex: 1;' +
' height: 8px;' +
' background: #f0f0f0;' +
' border-radius: 4px;' +
' overflow: hidden;' +
'}' +
'.commit-fill {' +
' height: 100%;' +
' background: linear-gradient(135deg, #667eea, #764ba2);' +
' border-radius: 4px;' +
' transition: width 0.3s ease;' +
'}' +
'.commit-count {' +
' width: 40px;' +
' text-align: right;' +
' font-size: 0.9rem;' +
' font-weight: 600;' +
' color: #333;' +
'}' +
'.error {' +
' text-align: center;' +
' color: #999;' +
' font-style: italic;' +
' padding: 2rem;' +
'}' +
'.project-updated {' +
' margin-top: 1rem;' +
' font-size: 0.8rem;' +
' color: #888;' +
'}' +
'.article-category {' +
' background: rgba(102, 126, 234, 0.1);' +
' color: #667eea;' +
' padding: 0.2rem 0.6rem;' +
' border-radius: 12px;' +
' font-size: 0.8rem;' +
'}' +
'</style>';
// 添加样式到页面
$('head').append(githubStyles);
@@ -543,4 +642,52 @@ window.addEventListener('error', function(e) {
// 页面加载完成提示
$(window).on('load', function() {
console.log('关于我页面加载完成');
});
});
// 微信弹窗功能
function initWeChatModal() {
// 微信卡片点击事件
$(document).on('click', '.social-card.wechat', function(e) {
e.preventDefault();
showWeChatModal();
});
// 关闭弹窗事件
$(document).on('click', '.modal .close, .modal', function(e) {
if (e.target === this) {
hideWeChatModal();
}
});
// ESC键关闭弹窗
$(document).on('keydown', function(e) {
if (e.keyCode === 27) { // ESC键
hideWeChatModal();
}
});
}
function showWeChatModal() {
var modalHtml = '<div id="wechatModal" class="modal" style="display: none;">' +
'<div class="modal-content">' +
'<span class="close">&times;</span>' +
'<h3>微信公众号</h3>' +
'<div class="qr-code">' +
'<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiBmaWxsPSIjZjVmNWY1Ii8+CjxyZWN0IHg9IjIwIiB5PSIyMCIgd2lkdGg9IjE2MCIgaGVpZ2h0PSIxNjAiIGZpbGw9IndoaXRlIiBzdHJva2U9IiNkZGQiLz4KPHN2ZyB4PSI0MCIgeT0iNDAiIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+CjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSIjMDdjMTYwIi8+Cjx0ZXh0IHg9IjUwIiB5PSI1NSIgZm9udC1mYW1pbHk9IkFyaWFsLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjE0IiBmaWxsPSJ3aGl0ZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+5b6u5L+h5YWs5LyX5Y+3PC90ZXh0Pgo8L3N2Zz4KPC9zdmc+" alt="微信公众号二维码" onerror="this.style.display=\'none\'; this.nextElementSibling.style.display=\'block\';">' +
'<div style="display: none; padding: 2rem; text-align: center; color: #666;">二维码加载失败<br>请搜索公众号:技术分享小站</div>' +
'</div>' +
'<p style="margin-top: 1rem; color: #666; text-align: center;">扫码关注获取最新技术文章</p>' +
'</div>' +
'</div>';
// 如果弹窗不存在则创建
if ($('#wechatModal').length === 0) {
$('body').append(modalHtml);
}
$('#wechatModal').fadeIn(300);
}
function hideWeChatModal() {
$('#wechatModal').fadeOut(300);
}