php-manager-website/script.js
2025-12-26 17:14:06 +08:00

184 lines
4.5 KiB
JavaScript

/**
* PHPer 官网交互脚本
*/
document.addEventListener('DOMContentLoaded', () => {
// 初始化所有功能
initScreenshotTabs();
initFAQ();
initScrollAnimations();
initMobileMenu();
initSmoothScroll();
});
/**
* 截图标签切换
*/
function initScreenshotTabs() {
const tabs = document.querySelectorAll('.tab-btn');
const images = document.querySelectorAll('.screenshot-img');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = tab.dataset.tab;
// 切换标签状态
tabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
// 切换图片
images.forEach(img => {
if (img.dataset.tab === target) {
img.classList.add('active');
} else {
img.classList.remove('active');
}
});
});
});
}
/**
* FAQ 折叠面板
*/
function initFAQ() {
const faqItems = document.querySelectorAll('.faq-item');
faqItems.forEach(item => {
const question = item.querySelector('.faq-question');
question.addEventListener('click', () => {
// 关闭其他展开的项目
faqItems.forEach(other => {
if (other !== item && other.classList.contains('active')) {
other.classList.remove('active');
}
});
// 切换当前项目
item.classList.toggle('active');
});
});
}
/**
* 滚动动画
*/
function initScrollAnimations() {
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 0.1
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, observerOptions);
// 观察需要动画的元素
const animatedElements = document.querySelectorAll(
'.feature-card, .faq-item, .table-row:not(.table-header)'
);
animatedElements.forEach((el, index) => {
el.style.transitionDelay = `${index * 0.05}s`;
observer.observe(el);
});
}
/**
* 移动端菜单
*/
function initMobileMenu() {
const menuBtn = document.querySelector('.mobile-menu-btn');
const navLinks = document.querySelector('.nav-links');
if (!menuBtn || !navLinks) return;
menuBtn.addEventListener('click', () => {
menuBtn.classList.toggle('active');
navLinks.classList.toggle('mobile-open');
});
// 点击链接后关闭菜单
navLinks.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
menuBtn.classList.remove('active');
navLinks.classList.remove('mobile-open');
});
});
}
/**
* 平滑滚动
*/
function initSmoothScroll() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const href = this.getAttribute('href');
if (href === '#') return;
e.preventDefault();
const target = document.querySelector(href);
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
}
/**
* 导航栏滚动效果
*/
let lastScroll = 0;
const navbar = document.querySelector('.navbar');
window.addEventListener('scroll', () => {
const currentScroll = window.pageYOffset;
if (currentScroll > 100) {
navbar.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.3)';
} else {
navbar.style.boxShadow = 'none';
}
lastScroll = currentScroll;
});
/**
* 打字机效果(终端提示)
*/
function typeWriter(element, text, speed = 50) {
let i = 0;
element.textContent = '';
function type() {
if (i < text.length) {
element.textContent += text.charAt(i);
i++;
setTimeout(type, speed);
}
}
type();
}
// 页面加载完成后启动打字机效果
window.addEventListener('load', () => {
const promptText = document.querySelector('.prompt-text');
if (promptText) {
setTimeout(() => {
typeWriter(promptText, '所有服务已就绪,开始开发吧!', 80);
}, 1500);
}
});