-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscript.js
More file actions
184 lines (160 loc) · 5.32 KB
/
script.js
File metadata and controls
184 lines (160 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// DOM元素
const navbar = document.querySelector('.navbar');
const hamburger = document.querySelector('.hamburger');
const navMenu = document.querySelector('.nav-menu');
const backToTop = document.getElementById('backToTop');
const yearSpan = document.getElementById('year');
// 设置当前年份
yearSpan.textContent = new Date().getFullYear();
// 导航栏滚动效果
window.addEventListener('scroll', () => {
if (window.scrollY > 100) {
navbar.classList.add('scrolled');
backToTop.classList.add('visible');
} else {
navbar.classList.remove('scrolled');
backToTop.classList.remove('visible');
}
});
// 移动端菜单切换
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('active');
navMenu.classList.toggle('active');
});
// 点击菜单项关闭移动端菜单
document.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', () => {
hamburger.classList.remove('active');
navMenu.classList.remove('active');
});
});
// 返回顶部
backToTop.addEventListener('click', () => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
// 平滑滚动到锚点
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
const offsetTop = target.offsetTop - 70; // 考虑导航栏高度
window.scrollTo({
top: offsetTop,
behavior: 'smooth'
});
}
});
});
// 视频播放控制
const videoWrapper = document.querySelector('.video-wrapper');
const video = document.querySelector('video');
const playButton = document.querySelector('.play-button');
const videoOverlay = document.querySelector('.video-overlay');
if (playButton && video) {
playButton.addEventListener('click', () => {
video.play();
videoOverlay.style.display = 'none';
});
video.addEventListener('pause', () => {
videoOverlay.style.display = 'flex';
});
video.addEventListener('ended', () => {
videoOverlay.style.display = 'flex';
});
}
// 滚动动画观察器
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
// 观察需要动画的元素
document.querySelectorAll('.feature-card, .team-card, .download-card').forEach(el => {
el.style.opacity = '0';
el.style.transform = 'translateY(30px)';
el.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
observer.observe(el);
});
// 数字计数动画
function animateCounter(element, target, duration = 2000) {
let start = 0;
const increment = target / (duration / 16);
function updateCounter() {
start += increment;
if (start < target) {
element.textContent = Math.floor(start).toLocaleString();
requestAnimationFrame(updateCounter);
} else {
element.textContent = target.toLocaleString();
}
}
updateCounter();
}
// 当统计数字进入视口时开始动画
const statsObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const statNumbers = entry.target.querySelectorAll('.stat-number');
statNumbers.forEach(stat => {
const text = stat.textContent;
const number = parseInt(text.replace(/[^\d]/g, ''));
if (number && !stat.classList.contains('animated')) {
stat.classList.add('animated');
animateCounter(stat, number);
}
});
}
});
}, { threshold: 0.5 });
document.querySelectorAll('.hero-stats, .about-stats').forEach(stats => {
statsObserver.observe(stats);
});
// 表单验证和提交(如果有的话)
function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}
// 错误处理
window.addEventListener('error', (e) => {
console.error('页面错误:', e.error);
});
// 页面加载完成后的初始化
document.addEventListener('DOMContentLoaded', () => {
// 预加载关键图片
const criticalImages = [
'img/back.png',
'img/video-poster.jpg'
];
criticalImages.forEach(src => {
const img = new Image();
img.src = src;
});
// 检查浏览器支持
if (!window.IntersectionObserver) {
// 为不支持 IntersectionObserver 的浏览器提供回退
document.querySelectorAll('.feature-card, .team-card, .download-card').forEach(el => {
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
});
}
});
// 性能监控
if ('performance' in window) {
window.addEventListener('load', () => {
setTimeout(() => {
const perfData = performance.getEntriesByType('navigation')[0];
console.log('页面加载时间:', perfData.loadEventEnd - perfData.loadEventStart, 'ms');
}, 0);
});
}