|
|
|
|
|
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(); |
|
|
}); |