358 lines
9.4 KiB
JavaScript
358 lines
9.4 KiB
JavaScript
/**
|
|
* DevTools 官网交互脚本
|
|
* 支持主页、PHPer、EasyShell 页面
|
|
*/
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// 初始化所有功能
|
|
initScreenshotTabs();
|
|
initFAQ();
|
|
initScrollAnimations();
|
|
initMobileMenu();
|
|
initSmoothScroll();
|
|
initNavbarScroll();
|
|
});
|
|
|
|
/**
|
|
* 截图标签切换
|
|
*/
|
|
function initScreenshotTabs() {
|
|
const tabs = document.querySelectorAll('.tab-btn');
|
|
const images = document.querySelectorAll('.screenshot-img');
|
|
|
|
if (!tabs.length || !images.length) return;
|
|
|
|
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');
|
|
|
|
if (!faqItems.length) return;
|
|
|
|
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), .product-card, .banner-content, .platform-card, .shortcut-item, .comparison-row'
|
|
);
|
|
|
|
animatedElements.forEach((el, index) => {
|
|
// 为每组元素设置递增的延迟
|
|
const delay = Math.min(index * 0.05, 0.5);
|
|
el.style.transitionDelay = `${delay}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');
|
|
});
|
|
});
|
|
|
|
// 点击页面其他地方关闭菜单
|
|
document.addEventListener('click', (e) => {
|
|
if (!menuBtn.contains(e.target) && !navLinks.contains(e.target)) {
|
|
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'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 导航栏滚动效果
|
|
*/
|
|
function initNavbarScroll() {
|
|
const navbar = document.querySelector('.navbar');
|
|
if (!navbar) return;
|
|
|
|
let lastScroll = 0;
|
|
|
|
window.addEventListener('scroll', () => {
|
|
const currentScroll = window.pageYOffset;
|
|
|
|
if (currentScroll > 100) {
|
|
navbar.style.boxShadow = '0 4px 30px rgba(0, 0, 0, 0.3)';
|
|
navbar.style.background = 'rgba(8, 12, 20, 0.95)';
|
|
} else {
|
|
navbar.style.boxShadow = 'none';
|
|
navbar.style.background = 'rgba(8, 12, 20, 0.85)';
|
|
}
|
|
|
|
lastScroll = currentScroll;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 产品卡片悬停效果增强
|
|
*/
|
|
document.querySelectorAll('.product-card').forEach(card => {
|
|
card.addEventListener('mouseenter', function() {
|
|
this.style.transform = 'translateY(-8px)';
|
|
});
|
|
|
|
card.addEventListener('mouseleave', function() {
|
|
this.style.transform = 'translateY(0)';
|
|
});
|
|
});
|
|
|
|
/**
|
|
* 浮动卡片交互效果
|
|
*/
|
|
document.querySelectorAll('.float-card').forEach(card => {
|
|
card.addEventListener('mouseenter', function() {
|
|
// 暂停动画
|
|
this.style.animationPlayState = 'paused';
|
|
});
|
|
|
|
card.addEventListener('mouseleave', function() {
|
|
// 恢复动画
|
|
this.style.animationPlayState = 'running';
|
|
});
|
|
});
|
|
|
|
/**
|
|
* 按钮点击波纹效果
|
|
*/
|
|
document.querySelectorAll('.btn').forEach(btn => {
|
|
btn.addEventListener('click', function(e) {
|
|
const ripple = document.createElement('span');
|
|
const rect = this.getBoundingClientRect();
|
|
const size = Math.max(rect.width, rect.height);
|
|
const x = e.clientX - rect.left - size / 2;
|
|
const y = e.clientY - rect.top - size / 2;
|
|
|
|
ripple.style.cssText = `
|
|
position: absolute;
|
|
width: ${size}px;
|
|
height: ${size}px;
|
|
left: ${x}px;
|
|
top: ${y}px;
|
|
background: rgba(255, 255, 255, 0.3);
|
|
border-radius: 50%;
|
|
transform: scale(0);
|
|
animation: ripple 0.6s ease-out;
|
|
pointer-events: none;
|
|
`;
|
|
|
|
this.style.position = 'relative';
|
|
this.style.overflow = 'hidden';
|
|
this.appendChild(ripple);
|
|
|
|
setTimeout(() => ripple.remove(), 600);
|
|
});
|
|
});
|
|
|
|
// 添加波纹动画样式
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
@keyframes ripple {
|
|
to {
|
|
transform: scale(4);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
|
|
/**
|
|
* 图片懒加载
|
|
*/
|
|
function initLazyLoad() {
|
|
const images = document.querySelectorAll('img[data-src]');
|
|
|
|
if ('IntersectionObserver' in window) {
|
|
const imageObserver = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
const img = entry.target;
|
|
img.src = img.dataset.src;
|
|
img.removeAttribute('data-src');
|
|
imageObserver.unobserve(img);
|
|
}
|
|
});
|
|
});
|
|
|
|
images.forEach(img => imageObserver.observe(img));
|
|
} else {
|
|
// 降级处理
|
|
images.forEach(img => {
|
|
img.src = img.dataset.src;
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 页面加载完成后的初始化
|
|
*/
|
|
window.addEventListener('load', () => {
|
|
// 移除加载状态
|
|
document.body.classList.add('loaded');
|
|
|
|
// 初始化懒加载
|
|
initLazyLoad();
|
|
});
|
|
|
|
/**
|
|
* 复制代码功能(如果需要)
|
|
*/
|
|
function copyToClipboard(text) {
|
|
if (navigator.clipboard) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
showToast('已复制到剪贴板');
|
|
});
|
|
} else {
|
|
// 降级处理
|
|
const textarea = document.createElement('textarea');
|
|
textarea.value = text;
|
|
document.body.appendChild(textarea);
|
|
textarea.select();
|
|
document.execCommand('copy');
|
|
document.body.removeChild(textarea);
|
|
showToast('已复制到剪贴板');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 显示提示消息
|
|
*/
|
|
function showToast(message) {
|
|
const toast = document.createElement('div');
|
|
toast.className = 'toast';
|
|
toast.textContent = message;
|
|
toast.style.cssText = `
|
|
position: fixed;
|
|
bottom: 24px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: rgba(16, 185, 129, 0.9);
|
|
color: white;
|
|
padding: 12px 24px;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
z-index: 9999;
|
|
animation: toastIn 0.3s ease, toastOut 0.3s ease 2s forwards;
|
|
`;
|
|
|
|
document.body.appendChild(toast);
|
|
setTimeout(() => toast.remove(), 2500);
|
|
}
|
|
|
|
// Toast 动画样式
|
|
const toastStyle = document.createElement('style');
|
|
toastStyle.textContent = `
|
|
@keyframes toastIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-50%) translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(-50%) translateY(0);
|
|
}
|
|
}
|
|
@keyframes toastOut {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateX(-50%) translateY(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateX(-50%) translateY(-20px);
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(toastStyle);
|