anyalerob commited on
Commit
32d4199
·
verified ·
1 Parent(s): 176a9b5

Create script.js

Browse files
Files changed (1) hide show
  1. script.js +662 -0
script.js ADDED
@@ -0,0 +1,662 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // 全局变量
2
+ let isParsing = false;
3
+ let history = JSON.parse(localStorage.getItem('parseHistory') || '[]');
4
+
5
+ // 初始化主题
6
+ function initTheme() {
7
+ const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
8
+ const savedTheme = localStorage.getItem('theme') || (prefersDarkScheme.matches ? 'dark' : 'light');
9
+ document.documentElement.setAttribute('data-theme', savedTheme);
10
+ const themeBtn = document.getElementById('theme-btn');
11
+ themeBtn.innerHTML = savedTheme === 'dark' ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>';
12
+ }
13
+
14
+ // 初始化主题色
15
+ function initThemeColor() {
16
+ const themeColors = [
17
+ { primary: '#7c4dff', light: 'rgba(124, 77, 255, 0.2)', dark: '#5e35b1' },
18
+ { primary: '#42a5f5', light: 'rgba(66, 165, 245, 0.2)', dark: '#1976d2' },
19
+ { primary: '#ec407a', light: 'rgba(236, 64, 122, 0.2)', dark: '#d81b60' },
20
+ { primary: '#66bb6a', light: 'rgba(102, 187, 106, 0.2)', dark: '#43a047' },
21
+ { primary: '#ff9800', light: 'rgba(255, 152, 0, 0.2)', dark: '#f57c00' },
22
+ ];
23
+ const colorIndex = parseInt(localStorage.getItem('colorIndex') || '0');
24
+ const color = themeColors[colorIndex];
25
+ document.documentElement.style.setProperty('--primary-color', color.primary);
26
+ document.documentElement.style.setProperty('--primary-light', color.light);
27
+ document.documentElement.style.setProperty('--primary-dark', color.dark);
28
+ document.getElementById('color-btn').onclick = function() {
29
+ const nextIndex = (colorIndex + 1) % themeColors.length;
30
+ localStorage.setItem('colorIndex', nextIndex);
31
+ initThemeColor();
32
+ };
33
+ }
34
+
35
+ // 加载樱花特效
36
+ function loadSakuraEffect() {
37
+ const script = document.createElement('script');
38
+ script.src = 'https://api.suyanw.cn/api/mouse/yinghua.js';
39
+ document.body.appendChild(script);
40
+ }
41
+
42
+ // 鱼游动画(CDN引入)
43
+ function initFishAnimation() {
44
+ console.log('鱼游动画已通过CDN加载');
45
+ }
46
+
47
+ // 调试信息显示
48
+ let debugTimer;
49
+ function showDebugInfo(message) {
50
+ const debugEl = document.getElementById('debugInfo');
51
+ debugEl.textContent = message;
52
+ clearTimeout(debugTimer);
53
+ debugTimer = setTimeout(() => debugEl.textContent = '', 5000);
54
+ }
55
+
56
+ // 实时时钟
57
+ function updateTime() {
58
+ const now = new Date();
59
+ document.getElementById('currentTime').textContent =
60
+ `${now.getHours().toString().padStart(2, '0')}:` +
61
+ `${now.getMinutes().toString().padStart(2, '0')}:` +
62
+ `${now.getSeconds().toString().padStart(2, '0')}`;
63
+ }
64
+
65
+ // 获取天气
66
+ async function getWeather() {
67
+ try {
68
+ const response = await fetch('https://api.kxzjoker.cn/api/Weather');
69
+ const data = await response.json();
70
+
71
+ if (data.code !== 200) throw new Error('天气获取失败');
72
+
73
+ document.getElementById('weatherWidget').innerHTML = `
74
+ <i class="fas fa-cloud-sun" style="background: linear-gradient(45deg, #ff9a00, #89CFF0);-webkit-background-clip: text;background-clip: text;color: transparent;"></i>
75
+ ${data.data.tianqi.temperature}°C
76
+ `;
77
+
78
+ showDebugInfo(`👏欢迎来自${data.data.ipdata.info.split('-')[0]}的用户`);
79
+ } catch (error) {
80
+ document.getElementById('weatherWidget').innerHTML = `
81
+ <i class="fas fa-cloud-sun" style="background: linear-gradient(45deg, #ff9a00, #89CFF0);-webkit-background-clip: text;background-clip: text;color: transparent;"></i>
82
+ 未知天气
83
+ `;
84
+ showDebugInfo('欢迎访问本服务');
85
+ }
86
+ }
87
+
88
+ // 获取随机文案
89
+ async function fetchRandomQuote() {
90
+ try {
91
+ const response = await fetch('https://api.suyanw.cn/api/weimei.php?type=json');
92
+ const data = await response.json();
93
+ const quoteEl = document.getElementById('random-quote');
94
+ if (quoteEl) {
95
+ quoteEl.textContent = data.text || "每一个视频背后,都有一个想被分享的故事";
96
+ }
97
+ } catch (error) {
98
+ const quoteEl = document.getElementById('random-quote');
99
+ if (quoteEl) {
100
+ quoteEl.textContent = "每一个视频背后,都有一个想被分享的故事";
101
+ }
102
+ console.error('获取随机文案失败:', error);
103
+ }
104
+ }
105
+
106
+ // 获取并更新背景图片
107
+ async function updateBackgroundImage() {
108
+ try {
109
+ const response = await fetch('https://api.suyanw.cn/api/comic3.php');
110
+ if (!response.ok) throw new Error(`背景图片 API 请求失败: ${response.status}`);
111
+ const data = await response.json();
112
+ const imageUrl = data.url || data.image || data.data?.url; // 适配可能的字段
113
+ if (imageUrl) {
114
+ document.body.style.backgroundImage = `url(${imageUrl})`;
115
+ showDebugInfo('背景图片已更新');
116
+ } else {
117
+ throw new Error('背景图片 URL 为空');
118
+ }
119
+ } catch (error) {
120
+ console.error('获取背景图片失败:', error);
121
+ showDebugInfo('背景图片加载失败,将使用默认背景');
122
+ document.body.style.backgroundImage = `url('https://via.placeholder.com/1920x1080?text=Default+Background')`;
123
+ }
124
+ }
125
+
126
+ // 获取在线访客人数(假设 API)
127
+ async function updateOnlineUsers() {
128
+ try {
129
+ const response = await fetch('https://api.example.com/online-users');
130
+ const data = await response.json();
131
+ const onlineUsers = data.count || 0;
132
+ document.getElementById('online-users').textContent = onlineUsers;
133
+ } catch (error) {
134
+ console.error('获取在线人数失败:', error);
135
+ document.getElementById('online-users').textContent = '未知';
136
+ }
137
+ }
138
+
139
+ // URL提取
140
+ function extractURL(text) {
141
+ try {
142
+ const urlRegex = /(https?:\/\/.*)/g;
143
+ const matches = text.match(urlRegex);
144
+ return matches ? matches[0].trim() : null;
145
+ } catch (e) {
146
+ console.error('URL提取错误:', e);
147
+ return null;
148
+ }
149
+ }
150
+
151
+ // 监听剪贴板
152
+ function monitorClipboard() {
153
+ const videoUrlInput = document.getElementById('urlInput');
154
+ const pasteButton = document.getElementById('clipboard-btn');
155
+
156
+ pasteButton.addEventListener('click', async function() {
157
+ try {
158
+ const permissionStatus = await navigator.permissions.query({ name: 'clipboard-read' });
159
+ if (permissionStatus.state === 'denied') {
160
+ throw new Error('无权限访问剪贴板,请手动粘贴');
161
+ }
162
+
163
+ const text = await navigator.clipboard.readText();
164
+ if (text) {
165
+ videoUrlInput.value = text;
166
+ const pureUrl = extractURL(text);
167
+ if (pureUrl) {
168
+ showDebugInfo(`已提取纯链接: ${pureUrl}`);
169
+ parseContent(pureUrl);
170
+ } else {
171
+ showAlert('未检测到有效的视频链接,请确保链接包含 http 或 https,或者直接从平台复制分享链接!');
172
+ }
173
+ videoUrlInput.focus();
174
+ } else {
175
+ showAlert('剪贴板为空,请复制链接后重试');
176
+ }
177
+ } catch (error) {
178
+ console.warn('无法访问剪贴板:', error);
179
+ showAlert('无法访问剪贴板,请手动粘贴链接或检查浏览器权限');
180
+ videoUrlInput.focus();
181
+ }
182
+ });
183
+
184
+ videoUrlInput.addEventListener('focus', async function() {
185
+ if (this.value === '') {
186
+ try {
187
+ const permissionStatus = await navigator.permissions.query({ name: 'clipboard-read' });
188
+ if (permissionStatus.state === 'denied') {
189
+ showAlert('无权限访问剪贴板,请手动粘贴');
190
+ return;
191
+ }
192
+
193
+ const text = await navigator.clipboard.readText();
194
+ if (text) {
195
+ this.value = text;
196
+ const pureUrl = extractURL(text);
197
+ if (pureUrl) {
198
+ showDebugInfo(`自动填充提取的纯链接: ${pureUrl}`);
199
+ } else {
200
+ showAlert('未检测到有效的视频链接,请确保链接包含 http 或 https,或者直接从平台复制分享链接!');
201
+ }
202
+ }
203
+ } catch (error) {
204
+ console.warn('无法自动读取剪贴板:', error);
205
+ }
206
+ }
207
+ });
208
+
209
+ videoUrlInput.addEventListener('input', function() {
210
+ const pureUrl = extractURL(this.value);
211
+ if (pureUrl) {
212
+ showDebugInfo(`已检测到有效链接: ${pureUrl}`);
213
+ }
214
+ });
215
+ }
216
+
217
+ // 解析内容
218
+ async function parseContent(urlToParse) {
219
+ if (isParsing) return;
220
+ isParsing = true;
221
+
222
+ const parseBtn = document.querySelector('.parse-btn');
223
+ parseBtn.disabled = true;
224
+ parseBtn.style.opacity = '0.6';
225
+
226
+ showDebugInfo('开始解析流程...');
227
+
228
+ try {
229
+ const input = document.getElementById('urlInput');
230
+ if (!input) throw new Error('找不到输入框元素');
231
+
232
+ const url = urlToParse || extractURL(input.value);
233
+ showDebugInfo(`提取到URL: ${url || '无'}`);
234
+
235
+ if (!url) {
236
+ showAlert('🚨 请输入有效的链接哦~ (´•̥ ̯ •̥`)');
237
+ return;
238
+ }
239
+
240
+ toggleLoading(true);
241
+
242
+ showDebugInfo(`正在解析中: ${url}`);
243
+ const apiUrl = `https://api.kxzjoker.cn/api/jiexi_video?url=${encodeURIComponent(url)}`;
244
+ const response = await fetch(apiUrl);
245
+ showDebugInfo(`收到响应状态: ${response.status}`);
246
+
247
+ if (!response.ok) {
248
+ throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
249
+ }
250
+
251
+ const data = await response.json();
252
+ showDebugInfo(`API响应数据: ${JSON.stringify(data).slice(0, 100)}...`);
253
+
254
+ if (!data.success) {
255
+ throw new Error(`解析失败: ${data.message || '未知错误'}`);
256
+ }
257
+
258
+ const { video_title, video_url, download_url, image_url } = data.data;
259
+ showDebugInfo(`解析成功 - 时间: ${data.time}, 备注: ${data.tips}`);
260
+
261
+ renderContent(data.data);
262
+ saveToHistory({
263
+ url: url,
264
+ title: video_title || '',
265
+ cover: image_url || ''
266
+ });
267
+ showDebugInfo('内容渲染完成');
268
+
269
+ const shareContainer = document.getElementById('share-container');
270
+ shareContainer.style.display = 'block';
271
+ } catch (error) {
272
+ console.error('解析流程错误:', error);
273
+ showDebugInfo(`错误: ${error.message}`);
274
+ showAlert(`❌ 解析失败: ${error.message},请检查链接或稍后重试`);
275
+ } finally {
276
+ toggleLoading(false);
277
+ parseBtn.disabled = false;
278
+ parseBtn.style.opacity = '1';
279
+ isParsing = false;
280
+ }
281
+ }
282
+
283
+ // 渲染内容
284
+ function renderContent(data) {
285
+ const contentBox = document.getElementById('contentBox');
286
+ if (!contentBox) throw new Error('找不到内容容器');
287
+
288
+ contentBox.innerHTML = '';
289
+
290
+ try {
291
+ if (data.images) {
292
+ const galleryHTML = data.images.map((img, index) => `
293
+ <div class="gallery-item" onclick="showFullImage('${img}')">
294
+ <img src="${img}"
295
+ alt="图集 ${index + 1}"
296
+ loading="lazy"
297
+ style="width: 100%;
298
+ aspect-ratio: 1/1;
299
+ object-fit: cover;
300
+ cursor: pointer;">
301
+ <div class="image-index">${index + 1}</div>
302
+ </div>
303
+ `).join('');
304
+
305
+ contentBox.innerHTML = `
306
+ <div class="media-card">
307
+ <h2 style="color: var(--primary-color);">
308
+ <i class="fas fa-images"></i>
309
+ ${data.title || '未命名图集'}
310
+ </h2>
311
+ <div style="display: grid;
312
+ gap: 10px;
313
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));">
314
+ ${galleryHTML}
315
+ </div>
316
+ <div style="text-align: center; margin-top: 15px;">
317
+ <a href="#" class="download-all-btn btn">
318
+ <i class="fas fa-file-archive"></i>
319
+ 打包下载
320
+ </a>
321
+ </div>
322
+ </div>
323
+ `;
324
+
325
+ contentBox.style.display = 'block';
326
+ setTimeout(() => contentBox.scrollIntoView({ behavior: 'smooth' }), 300);
327
+
328
+ const downloadBtn = contentBox.querySelector('.download-all-btn');
329
+ downloadBtn.addEventListener('click', async (e) => {
330
+ e.preventDefault();
331
+ try {
332
+ downloadBtn.innerHTML = `<i class="fas fa-spinner fa-spin"></i> 准备中...`;
333
+ downloadBtn.disabled = true;
334
+
335
+ const zip = new JSZip();
336
+ const imgFolder = zip.folder('images');
337
+
338
+ const downloadPromises = data.images.map(async (imgUrl, index) => {
339
+ try {
340
+ const startTime = performance.now();
341
+ const response = await fetch(imgUrl);
342
+ if (!response.ok) throw new Error(`图片${index + 1}下载失败: ${response.status}`);
343
+ const blob = await response.blob();
344
+ const endTime = performance.now();
345
+ const duration = (endTime - startTime) / 1000;
346
+ const speed = (blob.size / 1024) / duration;
347
+ document.getElementById('progress-info').textContent = `下载速度: ${speed.toFixed(2)} KB/s`;
348
+ imgFolder.file(`image_${index + 1}.${getFileExtension(imgUrl)}`, blob);
349
+ } catch (error) {
350
+ console.warn(`图片${index + 1}下载失败:`, error);
351
+ return null;
352
+ }
353
+ });
354
+
355
+ let completed = 0;
356
+ downloadPromises.forEach(promise => {
357
+ promise.finally(() => {
358
+ completed++;
359
+ const progress = Math.round((completed / data.images.length) * 100);
360
+ document.getElementById('progress-bar').style.width = `${progress}%`;
361
+ document.getElementById('progress-info').textContent = `下载进度: ${progress}%`;
362
+ });
363
+ });
364
+
365
+ await Promise.all(downloadPromises);
366
+
367
+ const zipBlob = await zip.generateAsync({ type: 'blob', compression: 'DEFLATE', compressionOptions: { level: 6 } });
368
+ const cleanTitle = (data.title || '未命名图集').replace(/[<>:"/\\|?*]/g, '');
369
+ saveAs(zipBlob, `${cleanTitle}.zip`);
370
+ showAlert('🎉 图集下载完成!');
371
+ } catch (error) {
372
+ console.error('打包下载失败:', error);
373
+ showAlert(`❌ 打包下载失败: ${error.message},请重试`);
374
+ } finally {
375
+ downloadBtn.innerHTML = `<i class="fas fa-file-archive"></i> 打包下载`;
376
+ downloadBtn.disabled = false;
377
+ }
378
+ });
379
+
380
+ } else if (data.video_url) {
381
+ const { video_title, video_url, download_url, image_url } = data;
382
+ contentBox.innerHTML = `
383
+ <div class="media-card">
384
+ <h2 style="color: var(--primary-color);">
385
+ <i class="fas fa-video"></i>
386
+ ${video_title || '未命名视频'}
387
+ </h2>
388
+ ${image_url ? `<img src="${image_url}" alt="视频封面" style="width: 100%; border-radius: 15px; margin-bottom: 15px;">` : ''}
389
+ <div style="position: relative; padding-top: 56.25%;">
390
+ <video controls
391
+ style="position: absolute;
392
+ top: 0;
393
+ left: 0;
394
+ width: 100%;
395
+ height: 100%;">
396
+ <source src="${video_url}" type="video/mp4">
397
+ 您的浏览器不支持视频播放
398
+ </video>
399
+ </div>
400
+ <div style="text-align: center; margin-top: 15px;">
401
+ <a href="${download_url}" class="download-btn btn" download>
402
+ <i class="fas fa-download"></i>
403
+ 保存视频
404
+ </a>
405
+ </div>
406
+ </div>
407
+ `;
408
+
409
+ contentBox.style.display = 'block';
410
+ setTimeout(() => contentBox.scrollIntoView({ behavior: 'smooth' }), 300);
411
+
412
+ const downloadBtn = contentBox.querySelector('.download-btn');
413
+ downloadBtn.addEventListener('click', async (e) => {
414
+ e.preventDefault();
415
+ try {
416
+ downloadBtn.innerHTML = `<i class="fas fa-spinner fa-spin"></i> 下载中...`;
417
+ downloadBtn.disabled = true;
418
+
419
+ const startTime = performance.now();
420
+ const response = await fetch(download_url);
421
+ if (!response.ok) throw new Error(`视频下载失败: ${response.status} ${response.statusText}`);
422
+ const blob = await response.blob();
423
+ const endTime = performance.now();
424
+ const duration = (endTime - startTime) / 1000;
425
+ const speed = (blob.size / 1024) / duration;
426
+ document.getElementById('progress-info').textContent = `下载速度: ${speed.toFixed(2)} KB/s`;
427
+ document.getElementById('progress-bar').style.width = '100%';
428
+
429
+ const fileName = `${video_title || '未命名视频'}.mp4`.replace(/[<>:"/\\|?*]/g, '');
430
+ saveAs(blob, fileName);
431
+ showAlert('🎉 视频下载完成!');
432
+ } catch (error) {
433
+ console.error('下载失败:', error);
434
+ showAlert(`❌ 视频下载失败: ${error.message},请检查链接或稍后重试`);
435
+ } finally {
436
+ downloadBtn.innerHTML = `<i class="fas fa-download"></i> 保存视频`;
437
+ downloadBtn.disabled = false;
438
+ }
439
+ });
440
+ }
441
+ } catch (e) {
442
+ console.error('渲染错误:', e);
443
+ showAlert('内容渲染失败,请检查数据格式');
444
+ }
445
+ }
446
+
447
+ // 显示完整图片
448
+ function showFullImage(url) {
449
+ const modal = document.getElementById('image-modal');
450
+ const modalImage = document.getElementById('modal-image');
451
+ modalImage.src = url;
452
+ modal.style.display = 'flex';
453
+ }
454
+
455
+ // 工具函数
456
+ function toggleLoading(show) {
457
+ document.getElementById('loading').style.display = show ? 'block' : 'none';
458
+ }
459
+
460
+ function showAlert(message) {
461
+ const alert = document.createElement('div');
462
+ alert.className = 'alert';
463
+ alert.innerHTML = message;
464
+ document.body.appendChild(alert);
465
+ setTimeout(() => alert.remove(), 3000);
466
+ }
467
+
468
+ function getFileExtension(url) {
469
+ try {
470
+ const ext = url.split('.').pop().split(/[#?]/)[0].toLowerCase();
471
+ return ['jpg', 'jpeg', 'png', 'webp', 'gif'].includes(ext) ? ext : 'jpg';
472
+ } catch (e) {
473
+ return 'jpg';
474
+ }
475
+ }
476
+
477
+ function loadHistory() {
478
+ const historyList = document.getElementById('history-list');
479
+ if (history.length === 0) {
480
+ historyList.innerHTML = '<li>暂无解析历史</li>';
481
+ return;
482
+ }
483
+ historyList.innerHTML = '';
484
+ history.forEach((item, index) => {
485
+ const li = document.createElement('li');
486
+ li.className = 'history-item';
487
+ li.innerHTML = `
488
+ <img class="history-thumb" src="${item.cover || 'https://via.placeholder.com/60'}" alt="缩略图">
489
+ <div class="history-info">
490
+ <div class="history-title">${item.title || '未知标题'}</div>
491
+ <div class="history-url">${item.url}</div>
492
+ </div>
493
+ <div class="history-actions">
494
+ <button class="history-btn history-reparse" data-url="${item.url}"><i class="fas fa-redo"></i> 重新解析</button>
495
+ <button class="history-btn history-delete" data-index="${index}"><i class="fas fa-trash"></i> 删除</button>
496
+ </div>
497
+ `;
498
+ historyList.appendChild(li);
499
+ });
500
+ document.querySelectorAll('.history-reparse').forEach(btn => {
501
+ btn.addEventListener('click', function() {
502
+ document.getElementById('urlInput').value = this.getAttribute('data-url');
503
+ parseContent(this.getAttribute('data-url'));
504
+ });
505
+ });
506
+ document.querySelectorAll('.history-delete').forEach(btn => {
507
+ btn.addEventListener('click', function() {
508
+ const index = parseInt(this.getAttribute('data-index'));
509
+ history.splice(index, 1);
510
+ localStorage.setItem('parseHistory', JSON.stringify(history));
511
+ loadHistory();
512
+ });
513
+ });
514
+ }
515
+
516
+ function saveToHistory(data) {
517
+ if (!data || !data.url) return;
518
+ const exists = history.findIndex(item => item.url === data.url);
519
+ if (exists > -1) history.splice(exists, 1);
520
+ history.unshift({ url: data.url, title: data.title || '', cover: data.cover || '', timestamp: new Date().getTime() });
521
+ if (history.length > 10) history = history.slice(0, 10);
522
+ localStorage.setItem('parseHistory', JSON.stringify(history));
523
+ loadHistory();
524
+ }
525
+
526
+ // 分享功能
527
+ function copyLink() {
528
+ const url = window.location.href;
529
+ navigator.clipboard.writeText(url).then(() => {
530
+ showAlert('🎉 链接已复制到剪贴板!');
531
+ }).catch(() => {
532
+ showAlert('❌ 复制失败,请手动复制!');
533
+ });
534
+ }
535
+
536
+ function shareToWeChat() {
537
+ const url = window.location.href;
538
+ const shareText = `我发现了一个超好用的短视频无水印解析工具,快来试试吧!${url}`;
539
+ navigator.clipboard.writeText(shareText).then(() => {
540
+ showAlert('🎉 分享内容已复制,请粘贴到微信!');
541
+ });
542
+ }
543
+
544
+ function shareToQQ() {
545
+ const url = window.location.href;
546
+ const shareText = `我发现了一个超好用的短视频无水印解析工具,快来试试吧!${url}`;
547
+ navigator.clipboard.writeText(shareText).then(() => {
548
+ showAlert('🎉 分享内容已复制,请粘贴到QQ!');
549
+ });
550
+ }
551
+
552
+ document.querySelectorAll('.platform-btn').forEach(btn => {
553
+ const platform = btn.getAttribute('data-platform');
554
+ const platformLinks = {
555
+ '抖音': 'https://www.douyin.com/',
556
+ '快手': 'https://www.kuaishou.com/',
557
+ '火山视频': 'https://www.huoshan.com/',
558
+ '西瓜视频': 'https://www.ixigua.com/',
559
+ '皮皮虾': 'https://www.pipix.com/',
560
+ '秒拍': 'https://www.miaopai.com/',
561
+ '头条视频': 'https://www.toutiao.com/',
562
+ '腾讯微视': 'https://weishi.qq.com/',
563
+ '美图秀秀': 'https://www.meitu.com/',
564
+ '美拍': 'https://www.meipai.com/',
565
+ '微博': 'https://weibo.com/',
566
+ '小红书': 'https://www.xiaohongshu.com/',
567
+ '网易云': 'https://music.163.com/'
568
+ };
569
+ const link = platformLinks[platform] || '#';
570
+ btn.addEventListener('click', () => window.open(link, '_blank'));
571
+ btn.querySelector('img').addEventListener('click', e => { e.stopPropagation(); window.open(link, '_blank'); });
572
+ btn.querySelector('span').addEventListener('click', e => { e.stopPropagation(); window.open(link, '_blank'); });
573
+ });
574
+
575
+ document.addEventListener('DOMContentLoaded', function() {
576
+ initTheme();
577
+ initThemeColor();
578
+ loadSakuraEffect();
579
+ initFishAnimation();
580
+ fetchRandomQuote();
581
+ getWeather();
582
+ loadHistory();
583
+ monitorClipboard();
584
+
585
+ // 初始化背景图片并每10秒更新
586
+ updateBackgroundImage();
587
+ setInterval(updateBackgroundImage, 10000);
588
+
589
+ // 初始化在线访客人数并每30秒更新
590
+ updateOnlineUsers();
591
+ setInterval(updateOnlineUsers, 30000);
592
+
593
+ document.getElementById('theme-btn').addEventListener('click', function() {
594
+ const currentTheme = document.documentElement.getAttribute('data-theme');
595
+ const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
596
+ document.documentElement.setAttribute('data-theme', newTheme);
597
+ localStorage.setItem('theme', newTheme);
598
+ this.innerHTML = newTheme === 'dark' ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>';
599
+ });
600
+
601
+ document.getElementById('parse-btn').addEventListener('click', function() {
602
+ const url = document.getElementById('urlInput').value.trim();
603
+ parseContent(extractURL(url));
604
+ });
605
+
606
+ document.getElementById('urlInput').addEventListener('keypress', (e) => {
607
+ if (e.key === 'Enter') {
608
+ const url = document.getElementById('urlInput').value.trim();
609
+ parseContent(extractURL(url));
610
+ }
611
+ });
612
+
613
+ const feedbackModal = document.getElementById('feedback-modal');
614
+ const feedbackBtn = document.getElementById('feedback-btn');
615
+ const footerFeedback = document.getElementById('footer-feedback');
616
+
617
+ if (feedbackBtn) {
618
+ feedbackBtn.addEventListener('click', () => {
619
+ feedbackModal.style.display = 'block';
620
+ });
621
+ }
622
+
623
+ if (footerFeedback) {
624
+ footerFeedback.addEventListener('click', () => {
625
+ feedbackModal.style.display = 'block';
626
+ });
627
+ }
628
+
629
+ document.getElementById('cancel-feedback').addEventListener('click', () => {
630
+ feedbackModal.style.display = 'none';
631
+ });
632
+
633
+ document.getElementById('feedback-form').addEventListener('submit', function(e) {
634
+ e.preventDefault();
635
+ const feedback = document.getElementById('feedback-text').value.trim();
636
+ if (!feedback) {
637
+ alert('请输入反馈内容');
638
+ return;
639
+ }
640
+ console.log('用户反馈:', feedback);
641
+ alert('感谢您的反馈!我们会尽快处理。');
642
+ document.getElementById('feedback-text').value = '';
643
+ feedbackModal.style.display = 'none';
644
+ });
645
+
646
+ document.getElementById('close-modal').addEventListener('click', () => {
647
+ document.getElementById('image-modal').style.display = 'none';
648
+ feedbackModal.style.display = 'none';
649
+ });
650
+
651
+ if (!window.saveAs) {
652
+ console.warn('FileSaver.js 未加载!下载功能将不可用');
653
+ showDebugInfo('警告:文件保存功能需要 FileSaver.js 支持');
654
+ }
655
+ if (!window.JSZip) {
656
+ console.warn('JSZip 未加载!打包下载功能不可用');
657
+ showDebugInfo('警告:打包下载需要 JSZip 库支持');
658
+ }
659
+
660
+ setInterval(updateTime, 1000);
661
+ updateTime();
662
+ });