| |
| let isParsing = false; |
| let history = JSON.parse(localStorage.getItem('parseHistory') || '[]'); |
|
|
| |
| function initTheme() { |
| const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); |
| const savedTheme = localStorage.getItem('theme') || (prefersDarkScheme.matches ? 'dark' : 'light'); |
| document.documentElement.setAttribute('data-theme', savedTheme); |
| const themeBtn = document.getElementById('theme-btn'); |
| themeBtn.innerHTML = savedTheme === 'dark' ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>'; |
| } |
|
|
| |
| function initThemeColor() { |
| const themeColors = [ |
| { primary: '#7c4dff', light: 'rgba(124, 77, 255, 0.2)', dark: '#5e35b1' }, |
| { primary: '#42a5f5', light: 'rgba(66, 165, 245, 0.2)', dark: '#1976d2' }, |
| { primary: '#ec407a', light: 'rgba(236, 64, 122, 0.2)', dark: '#d81b60' }, |
| { primary: '#66bb6a', light: 'rgba(102, 187, 106, 0.2)', dark: '#43a047' }, |
| { primary: '#ff9800', light: 'rgba(255, 152, 0, 0.2)', dark: '#f57c00' }, |
| ]; |
| const colorIndex = parseInt(localStorage.getItem('colorIndex') || '0'); |
| const color = themeColors[colorIndex]; |
| document.documentElement.style.setProperty('--primary-color', color.primary); |
| document.documentElement.style.setProperty('--primary-light', color.light); |
| document.documentElement.style.setProperty('--primary-dark', color.dark); |
| document.getElementById('color-btn').onclick = function() { |
| const nextIndex = (colorIndex + 1) % themeColors.length; |
| localStorage.setItem('colorIndex', nextIndex); |
| initThemeColor(); |
| }; |
| } |
|
|
| |
| function loadSakuraEffect() { |
| const script = document.createElement('script'); |
| script.src = 'https://api.suyanw.cn/api/mouse/yinghua.js'; |
| document.body.appendChild(script); |
| } |
|
|
| |
| function initFishAnimation() { |
| console.log('鱼游动画已通过CDN加载'); |
| } |
|
|
| |
| let debugTimer; |
| function showDebugInfo(message) { |
| const debugEl = document.getElementById('debugInfo'); |
| debugEl.textContent = message; |
| clearTimeout(debugTimer); |
| debugTimer = setTimeout(() => debugEl.textContent = '', 5000); |
| } |
|
|
| |
| function updateTime() { |
| const now = new Date(); |
| document.getElementById('currentTime').textContent = |
| `${now.getHours().toString().padStart(2, '0')}:` + |
| `${now.getMinutes().toString().padStart(2, '0')}:` + |
| `${now.getSeconds().toString().padStart(2, '0')}`; |
| } |
|
|
| |
| async function getWeather() { |
| try { |
| const response = await fetch('https://api.kxzjoker.cn/api/Weather'); |
| const data = await response.json(); |
|
|
| if (data.code !== 200) throw new Error('天气获取失败'); |
|
|
| document.getElementById('weatherWidget').innerHTML = ` |
| <i class="fas fa-cloud-sun" style="background: linear-gradient(45deg, #ff9a00, #89CFF0);-webkit-background-clip: text;background-clip: text;color: transparent;"></i> |
| ${data.data.tianqi.temperature}°C |
| `; |
|
|
| showDebugInfo(`👏欢迎来自${data.data.ipdata.info.split('-')[0]}的用户`); |
| } catch (error) { |
| document.getElementById('weatherWidget').innerHTML = ` |
| <i class="fas fa-cloud-sun" style="background: linear-gradient(45deg, #ff9a00, #89CFF0);-webkit-background-clip: text;background-clip: text;color: transparent;"></i> |
| 未知天气 |
| `; |
| showDebugInfo('欢迎访问本服务'); |
| } |
| } |
|
|
| |
| async function fetchRandomQuote() { |
| try { |
| const response = await fetch('https://api.suyanw.cn/api/weimei.php?type=json'); |
| const data = await response.json(); |
| const quoteEl = document.getElementById('random-quote'); |
| if (quoteEl) { |
| quoteEl.textContent = data.text || "每一个视频背后,都有一个想被分享的故事"; |
| } |
| } catch (error) { |
| const quoteEl = document.getElementById('random-quote'); |
| if (quoteEl) { |
| quoteEl.textContent = "每一个视频背后,都有一个想被分享的故事"; |
| } |
| console.error('获取随机文案失败:', error); |
| } |
| } |
|
|
| |
| async function updateBackgroundImage() { |
| try { |
| const response = await fetch('https://api.suyanw.cn/api/comic3.php'); |
| if (!response.ok) throw new Error(`背景图片 API 请求失败: ${response.status}`); |
| const data = await response.json(); |
| const imageUrl = data.url || data.image || data.data?.url; |
| if (imageUrl) { |
| document.body.style.backgroundImage = `url(${imageUrl})`; |
| showDebugInfo('背景图片已更新'); |
| } else { |
| throw new Error('背景图片 URL 为空'); |
| } |
| } catch (error) { |
| console.error('获取背景图片失败:', error); |
| showDebugInfo('背景图片加载失败,将使用默认背景'); |
| document.body.style.backgroundImage = `url('https://img.zlee.de/file/1747480653744_e852b46603ba8a533c63f5631308f760.jpg')`; |
| } |
| } |
|
|
| |
| async function updateOnlineUsers() { |
| try { |
| const response = await fetch('https://api.example.com/online-users'); |
| const data = await response.json(); |
| const onlineUsers = data.count || 0; |
| document.getElementById('online-users').textContent = onlineUsers; |
| } catch (error) { |
| console.error('获取在线人数失败:', error); |
| document.getElementById('online-users').textContent = '未知'; |
| } |
| } |
|
|
| |
| function extractURL(text) { |
| try { |
| const urlRegex = /(https?:\/\/.*)/g; |
| const matches = text.match(urlRegex); |
| return matches ? matches[0].trim() : null; |
| } catch (e) { |
| console.error('URL提取错误:', e); |
| return null; |
| } |
| } |
|
|
| |
| function monitorClipboard() { |
| const videoUrlInput = document.getElementById('urlInput'); |
| const pasteButton = document.getElementById('clipboard-btn'); |
|
|
| pasteButton.addEventListener('click', async function() { |
| try { |
| const permissionStatus = await navigator.permissions.query({ name: 'clipboard-read' }); |
| if (permissionStatus.state === 'denied') { |
| throw new Error('无权限访问剪贴板,请手动粘贴'); |
| } |
|
|
| const text = await navigator.clipboard.readText(); |
| if (text) { |
| videoUrlInput.value = text; |
| const pureUrl = extractURL(text); |
| if (pureUrl) { |
| showDebugInfo(`已提取纯链接: ${pureUrl}`); |
| parseContent(pureUrl); |
| } else { |
| showAlert('未检测到有效的视频链接,请确保链接包含 http 或 https,或者直接从平台复制分享链接!'); |
| } |
| videoUrlInput.focus(); |
| } else { |
| showAlert('剪贴板为空,请复制链接后重试'); |
| } |
| } catch (error) { |
| console.warn('无法访问剪贴板:', error); |
| showAlert('无法访问剪贴板,请手动粘贴链接或检查浏览器权限'); |
| videoUrlInput.focus(); |
| } |
| }); |
|
|
| videoUrlInput.addEventListener('focus', async function() { |
| if (this.value === '') { |
| try { |
| const permissionStatus = await navigator.permissions.query({ name: 'clipboard-read' }); |
| if (permissionStatus.state === 'denied') { |
| showAlert('无权限访问剪贴板,请手动粘贴'); |
| return; |
| } |
|
|
| const text = await navigator.clipboard.readText(); |
| if (text) { |
| this.value = text; |
| const pureUrl = extractURL(text); |
| if (pureUrl) { |
| showDebugInfo(`自动填充提取的纯链接: ${pureUrl}`); |
| } else { |
| showAlert('未检测到有效的视频链接,请确保链接包含 http 或 https,或者直接从平台复制分享链接!'); |
| } |
| } |
| } catch (error) { |
| console.warn('无法自动读取剪贴板:', error); |
| } |
| } |
| }); |
|
|
| videoUrlInput.addEventListener('input', function() { |
| const pureUrl = extractURL(this.value); |
| if (pureUrl) { |
| showDebugInfo(`已检测到有效链接: ${pureUrl}`); |
| } |
| }); |
| } |
|
|
| |
| async function parseContent(urlToParse) { |
| if (isParsing) return; |
| isParsing = true; |
|
|
| const parseBtn = document.querySelector('.parse-btn'); |
| parseBtn.disabled = true; |
| parseBtn.style.opacity = '0.6'; |
|
|
| showDebugInfo('开始解析流程...'); |
|
|
| try { |
| const input = document.getElementById('urlInput'); |
| if (!input) throw new Error('找不到输入框元素'); |
|
|
| const url = urlToParse || extractURL(input.value); |
| showDebugInfo(`提取到URL: ${url || '无'}`); |
|
|
| if (!url) { |
| showAlert('🚨 请输入有效的链接哦~ (´•̥ ̯ •̥`)'); |
| return; |
| } |
|
|
| toggleLoading(true); |
|
|
| showDebugInfo(`正在解析中: ${url}`); |
| const apiUrl = `https://api.kxzjoker.cn/api/jiexi_video_2?url=${encodeURIComponent(url)}`; |
| const response = await fetch(apiUrl); |
| showDebugInfo(`收到响应状态: ${response.status}`); |
|
|
| if (!response.ok) { |
| throw new Error(`API请求失败: ${response.status} ${response.statusText}`); |
| } |
|
|
| const data = await response.json(); |
| showDebugInfo(`API响应数据: ${JSON.stringify(data).slice(0, 100)}...`); |
|
|
| if (!data.success) { |
| throw new Error(`解析失败: ${data.message || '未知错误'}`); |
| } |
|
|
| const { video_title, video_url, download_url, image_url } = data.data; |
| showDebugInfo(`解析成功 - 时间: ${data.time}, 备注: ${data.tips}`); |
|
|
| renderContent(data.data); |
| saveToHistory({ |
| url: url, |
| title: video_title || '', |
| cover: image_url || '' |
| }); |
| showDebugInfo('内容渲染完成'); |
|
|
| const shareContainer = document.getElementById('share-container'); |
| shareContainer.style.display = 'block'; |
| } catch (error) { |
| console.error('解析流程错误:', error); |
| showDebugInfo(`错误: ${error.message}`); |
| showAlert(`❌ 解析失败: ${error.message},请检查链接或稍后重试`); |
| } finally { |
| toggleLoading(false); |
| parseBtn.disabled = false; |
| parseBtn.style.opacity = '1'; |
| isParsing = false; |
| } |
| } |
|
|
| |
| function renderContent(data) { |
| const contentBox = document.getElementById('contentBox'); |
| if (!contentBox) throw new Error('找不到内容容器'); |
|
|
| contentBox.innerHTML = ''; |
|
|
| try { |
| if (data.images) { |
| const galleryHTML = data.images.map((img, index) => ` |
| <div class="gallery-item" onclick="showFullImage('${img}')"> |
| <img src="${img}" |
| alt="图集 ${index + 1}" |
| loading="lazy" |
| style="width: 100%; |
| aspect-ratio: 1/1; |
| object-fit: cover; |
| cursor: pointer;"> |
| <div class="image-index">${index + 1}</div> |
| </div> |
| `).join(''); |
|
|
| contentBox.innerHTML = ` |
| <div class="media-card"> |
| <h2 style="color: var(--primary-color);"> |
| <i class="fas fa-images"></i> |
| ${data.title || '未命名图集'} |
| </h2> |
| <div style="display: grid; |
| gap: 10px; |
| grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));"> |
| ${galleryHTML} |
| </div> |
| <div style="text-align: center; margin-top: 15px;"> |
| <a href="#" class="download-all-btn btn"> |
| <i class="fas fa-file-archive"></i> |
| 打包下载 |
| </a> |
| </div> |
| </div> |
| `; |
|
|
| contentBox.style.display = 'block'; |
| setTimeout(() => contentBox.scrollIntoView({ behavior: 'smooth' }), 300); |
|
|
| const downloadBtn = contentBox.querySelector('.download-all-btn'); |
| downloadBtn.addEventListener('click', async (e) => { |
| e.preventDefault(); |
| try { |
| downloadBtn.innerHTML = `<i class="fas fa-spinner fa-spin"></i> 准备中...`; |
| downloadBtn.disabled = true; |
|
|
| const zip = new JSZip(); |
| const imgFolder = zip.folder('images'); |
|
|
| const downloadPromises = data.images.map(async (imgUrl, index) => { |
| try { |
| const startTime = performance.now(); |
| const response = await fetch(imgUrl); |
| if (!response.ok) throw new Error(`图片${index + 1}下载失败: ${response.status}`); |
| const blob = await response.blob(); |
| const endTime = performance.now(); |
| const duration = (endTime - startTime) / 1000; |
| const speed = (blob.size / 1024) / duration; |
| document.getElementById('progress-info').textContent = `下载速度: ${speed.toFixed(2)} KB/s`; |
| imgFolder.file(`image_${index + 1}.${getFileExtension(imgUrl)}`, blob); |
| } catch (error) { |
| console.warn(`图片${index + 1}下载失败:`, error); |
| return null; |
| } |
| }); |
|
|
| let completed = 0; |
| downloadPromises.forEach(promise => { |
| promise.finally(() => { |
| completed++; |
| const progress = Math.round((completed / data.images.length) * 100); |
| document.getElementById('progress-bar').style.width = `${progress}%`; |
| document.getElementById('progress-info').textContent = `下载进度: ${progress}%`; |
| }); |
| }); |
|
|
| await Promise.all(downloadPromises); |
|
|
| const zipBlob = await zip.generateAsync({ type: 'blob', compression: 'DEFLATE', compressionOptions: { level: 6 } }); |
| const cleanTitle = (data.title || '未命名图集').replace(/[<>:"/\\|?*]/g, ''); |
| saveAs(zipBlob, `${cleanTitle}.zip`); |
| showAlert('🎉 图集下载完成!'); |
| } catch (error) { |
| console.error('打包下载失败:', error); |
| showAlert(`❌ 打包下载失败: ${error.message},请重试`); |
| } finally { |
| downloadBtn.innerHTML = `<i class="fas fa-file-archive"></i> 打包下载`; |
| downloadBtn.disabled = false; |
| } |
| }); |
|
|
| } else if (data.video_url) { |
| const { video_title, video_url, download_url, image_url } = data; |
| contentBox.innerHTML = ` |
| <div class="media-card"> |
| <h2 style="color: var(--primary-color);"> |
| <i class="fas fa-video"></i> |
| ${video_title || '未命名视频'} |
| </h2> |
| ${image_url ? `<img src="${image_url}" alt="视频封面" style="width: 100%; border-radius: 15px; margin-bottom: 15px;">` : ''} |
| <div style="position: relative; padding-top: 56.25%;"> |
| <video controls |
| style="position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%;"> |
| <source src="${video_url}" type="video/mp4"> |
| 您的浏览器不支持视频播放 |
| </video> |
| </div> |
| <div style="text-align: center; margin-top: 15px;"> |
| <a href="${download_url}" class="download-btn btn" download> |
| <i class="fas fa-download"></i> |
| 保存视频 |
| </a> |
| </div> |
| </div> |
| `; |
|
|
| contentBox.style.display = 'block'; |
| setTimeout(() => contentBox.scrollIntoView({ behavior: 'smooth' }), 300); |
|
|
| const downloadBtn = contentBox.querySelector('.download-btn'); |
| downloadBtn.addEventListener('click', async (e) => { |
| e.preventDefault(); |
| try { |
| downloadBtn.innerHTML = `<i class="fas fa-spinner fa-spin"></i> 下载中...`; |
| downloadBtn.disabled = true; |
|
|
| const startTime = performance.now(); |
| const response = await fetch(download_url); |
| if (!response.ok) throw new Error(`视频下载失败: ${response.status} ${response.statusText}`); |
| const blob = await response.blob(); |
| const endTime = performance.now(); |
| const duration = (endTime - startTime) / 1000; |
| const speed = (blob.size / 1024) / duration; |
| document.getElementById('progress-info').textContent = `下载速度: ${speed.toFixed(2)} KB/s`; |
| document.getElementById('progress-bar').style.width = '100%'; |
|
|
| const fileName = `${video_title || '未命名视频'}.mp4`.replace(/[<>:"/\\|?*]/g, ''); |
| saveAs(blob, fileName); |
| showAlert('🎉 视频下载完成!'); |
| } catch (error) { |
| console.error('下载失败:', error); |
| showAlert(`❌ 视频下载失败: ${error.message},请检查链接或稍后重试`); |
| } finally { |
| downloadBtn.innerHTML = `<i class="fas fa-download"></i> 保存视频`; |
| downloadBtn.disabled = false; |
| } |
| }); |
| } |
| } catch (e) { |
| console.error('渲染错误:', e); |
| showAlert('内容渲染失败,请检查数据格式'); |
| } |
| } |
|
|
| |
| function showFullImage(url) { |
| const modal = document.getElementById('image-modal'); |
| const modalImage = document.getElementById('modal-image'); |
| modalImage.src = url; |
| modal.style.display = 'flex'; |
| } |
|
|
| |
| function toggleLoading(show) { |
| document.getElementById('loading').style.display = show ? 'block' : 'none'; |
| } |
|
|
| function showAlert(message) { |
| const alert = document.createElement('div'); |
| alert.className = 'alert'; |
| alert.innerHTML = message; |
| document.body.appendChild(alert); |
| setTimeout(() => alert.remove(), 3000); |
| } |
|
|
| function getFileExtension(url) { |
| try { |
| const ext = url.split('.').pop().split(/[#?]/)[0].toLowerCase(); |
| return ['jpg', 'jpeg', 'png', 'webp', 'gif'].includes(ext) ? ext : 'jpg'; |
| } catch (e) { |
| return 'jpg'; |
| } |
| } |
|
|
| function loadHistory() { |
| const historyList = document.getElementById('history-list'); |
| if (history.length === 0) { |
| historyList.innerHTML = '<li>暂无解析历史</li>'; |
| return; |
| } |
| historyList.innerHTML = ''; |
| history.forEach((item, index) => { |
| const li = document.createElement('li'); |
| li.className = 'history-item'; |
| li.innerHTML = ` |
| <img class="history-thumb" src="${item.cover || 'https://via.placeholder.com/60'}" alt="缩略图"> |
| <div class="history-info"> |
| <div class="history-title">${item.title || '未知标题'}</div> |
| <div class="history-url">${item.url}</div> |
| </div> |
| <div class="history-actions"> |
| <button class="history-btn history-reparse" data-url="${item.url}"><i class="fas fa-redo"></i> 重新解析</button> |
| <button class="history-btn history-delete" data-index="${index}"><i class="fas fa-trash"></i> 删除</button> |
| </div> |
| `; |
| historyList.appendChild(li); |
| }); |
| document.querySelectorAll('.history-reparse').forEach(btn => { |
| btn.addEventListener('click', function() { |
| document.getElementById('urlInput').value = this.getAttribute('data-url'); |
| parseContent(this.getAttribute('data-url')); |
| }); |
| }); |
| document.querySelectorAll('.history-delete').forEach(btn => { |
| btn.addEventListener('click', function() { |
| const index = parseInt(this.getAttribute('data-index')); |
| history.splice(index, 1); |
| localStorage.setItem('parseHistory', JSON.stringify(history)); |
| loadHistory(); |
| }); |
| }); |
| } |
|
|
| function saveToHistory(data) { |
| if (!data || !data.url) return; |
| const exists = history.findIndex(item => item.url === data.url); |
| if (exists > -1) history.splice(exists, 1); |
| history.unshift({ url: data.url, title: data.title || '', cover: data.cover || '', timestamp: new Date().getTime() }); |
| if (history.length > 10) history = history.slice(0, 10); |
| localStorage.setItem('parseHistory', JSON.stringify(history)); |
| loadHistory(); |
| } |
|
|
| |
| function copyLink() { |
| const url = window.location.href; |
| navigator.clipboard.writeText(url).then(() => { |
| showAlert('🎉 链接已复制到剪贴板!'); |
| }).catch(() => { |
| showAlert('❌ 复制失败,请手动复制!'); |
| }); |
| } |
|
|
| function shareToWeChat() { |
| const url = window.location.href; |
| const shareText = `我发现了一个超好用的短视频无水印解析工具,快来试试吧!${url}`; |
| navigator.clipboard.writeText(shareText).then(() => { |
| showAlert('🎉 分享内容已复制,请粘贴到微信!'); |
| }); |
| } |
|
|
| function shareToQQ() { |
| const url = window.location.href; |
| const shareText = `我发现了一个超好用的短视频无水印解析工具,快来试试吧!${url}`; |
| navigator.clipboard.writeText(shareText).then(() => { |
| showAlert('🎉 分享内容已复制,请粘贴到QQ!'); |
| }); |
| } |
|
|
| document.querySelectorAll('.platform-btn').forEach(btn => { |
| const platform = btn.getAttribute('data-platform'); |
| const platformLinks = { |
| '抖音': 'https://www.douyin.com/', |
| '快手': 'https://www.kuaishou.com/', |
| '火山视频': 'https://www.huoshan.com/', |
| '西瓜视频': 'https://www.ixigua.com/', |
| '皮皮虾': 'https://www.pipix.com/', |
| '秒拍': 'https://www.miaopai.com/', |
| '头条视频': 'https://www.toutiao.com/', |
| '腾讯微视': 'https://weishi.qq.com/', |
| '美图秀秀': 'https://www.meitu.com/', |
| '美拍': 'https://www.meipai.com/', |
| '微博': 'https://weibo.com/', |
| '小红书': 'https://www.xiaohongshu.com/', |
| '网易云': 'https://music.163.com/' |
| }; |
| const link = platformLinks[platform] || '#'; |
| btn.addEventListener('click', () => window.open(link, '_blank')); |
| btn.querySelector('img').addEventListener('click', e => { e.stopPropagation(); window.open(link, '_blank'); }); |
| btn.querySelector('span').addEventListener('click', e => { e.stopPropagation(); window.open(link, '_blank'); }); |
| }); |
|
|
| document.addEventListener('DOMContentLoaded', function() { |
| initTheme(); |
| initThemeColor(); |
| loadSakuraEffect(); |
| initFishAnimation(); |
| fetchRandomQuote(); |
| getWeather(); |
| loadHistory(); |
| monitorClipboard(); |
|
|
| |
| updateBackgroundImage(); |
| setInterval(updateBackgroundImage, 10000); |
|
|
| |
| updateOnlineUsers(); |
| setInterval(updateOnlineUsers, 30000); |
|
|
| document.getElementById('theme-btn').addEventListener('click', function() { |
| const currentTheme = document.documentElement.getAttribute('data-theme'); |
| const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; |
| document.documentElement.setAttribute('data-theme', newTheme); |
| localStorage.setItem('theme', newTheme); |
| this.innerHTML = newTheme === 'dark' ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>'; |
| }); |
|
|
| document.getElementById('parse-btn').addEventListener('click', function() { |
| const url = document.getElementById('urlInput').value.trim(); |
| parseContent(extractURL(url)); |
| }); |
|
|
| document.getElementById('urlInput').addEventListener('keypress', (e) => { |
| if (e.key === 'Enter') { |
| const url = document.getElementById('urlInput').value.trim(); |
| parseContent(extractURL(url)); |
| } |
| }); |
|
|
| const feedbackModal = document.getElementById('feedback-modal'); |
| const feedbackBtn = document.getElementById('feedback-btn'); |
| const footerFeedback = document.getElementById('footer-feedback'); |
|
|
| if (feedbackBtn) { |
| feedbackBtn.addEventListener('click', () => { |
| feedbackModal.style.display = 'block'; |
| }); |
| } |
|
|
| if (footerFeedback) { |
| footerFeedback.addEventListener('click', () => { |
| feedbackModal.style.display = 'block'; |
| }); |
| } |
|
|
| document.getElementById('cancel-feedback').addEventListener('click', () => { |
| feedbackModal.style.display = 'none'; |
| }); |
|
|
| document.getElementById('feedback-form').addEventListener('submit', function(e) { |
| e.preventDefault(); |
| const feedback = document.getElementById('feedback-text').value.trim(); |
| if (!feedback) { |
| alert('请输入反馈内容'); |
| return; |
| } |
| console.log('用户反馈:', feedback); |
| alert('感谢您的反馈!我们会尽快处理。'); |
| document.getElementById('feedback-text').value = ''; |
| feedbackModal.style.display = 'none'; |
| }); |
|
|
| document.getElementById('close-modal').addEventListener('click', () => { |
| document.getElementById('image-modal').style.display = 'none'; |
| feedbackModal.style.display = 'none'; |
| }); |
|
|
| if (!window.saveAs) { |
| console.warn('FileSaver.js 未加载!下载功能将不可用'); |
| showDebugInfo('警告:文件保存功能需要 FileSaver.js 支持'); |
| } |
| if (!window.JSZip) { |
| console.warn('JSZip 未加载!打包下载功能不可用'); |
| showDebugInfo('警告:打包下载需要 JSZip 库支持'); |
| } |
|
|
| setInterval(updateTime, 1000); |
| updateTime(); |
| }); |