import API_CONFIG from './config.js';
// 在文档加载完成后初始化全局函数和事件监听
document.addEventListener('DOMContentLoaded', () => {
// 监听switchTab事件
window.addEventListener('switchTab', (e) => {
const { tabName } = e.detail;
switchTab(tabName);
});
// 监听searchMagnet事件
window.addEventListener('searchMagnet', () => {
searchMagnet();
});
// 监听copyToClipboard事件
window.addEventListener('copyToClipboard', (e) => {
const { text } = e.detail;
copyToClipboard(text);
});
// 监听showSortMenu事件
window.addEventListener('showSortMenu', (e) => {
const { button } = e.detail;
showSortMenu(button);
});
// 监听searchWithTerm事件
window.addEventListener('searchWithTerm', (e) => {
const { term } = e.detail;
searchWithTerm(term);
});
// 初始化全局变量
if (window.initializeGlobals) {
window.initializeGlobals({
translations,
currentLang,
SORT_OPTIONS
});
}
});
// Tab切换功能
// 添加全局变量
let currentTab = 'search'; // 默认标签页
// 添加视频URL状态管理
let currentVideoUrl = ''; // 存储当前视频URL
// 添加全局变量来跟踪视频播放状态
let wasPlaying = false; // 记录切换标签页前的播放状态
function switchTab(tabName) {
// 更新当前标签页
currentTab = tabName;
// 获取所有标签页内容和按钮
const tabs = document.querySelectorAll('.tab-content');
const buttons = document.querySelectorAll('.tab-button');
const videoPlayer = document.getElementById('videoPlayer');
// 隐藏所有标签页内容
tabs.forEach(tab => {
tab.classList.add('hidden');
});
// 移除所有按钮的激活状态
buttons.forEach(button => {
button.classList.remove('active');
});
// 显示选中的标签页内容
document.getElementById(`${tabName}Tab`).classList.remove('hidden');
// 激活对应的按钮
document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
// 处理视频播放状态
if (tabName === 'player') {
// 切换到播放器标签页
if (!currentVideoUrl) {
loadVideo();
} else if (wasPlaying && videoPlayer) {
// 如果之前是播放状态,恢复播放
videoPlayer.play().catch(e => console.error('Resume play failed:', e));
}
} else {
// 切换到其他标签页
if (videoPlayer) {
// 保存当前播放状态
wasPlaying = !videoPlayer.paused;
// 暂停视频
if (!videoPlayer.paused) {
videoPlayer.pause();
}
// 不销毁HLS实例,只是暂停播放,避免重新创建开销
}
}
// 当切换到搜索标签页时,获取热门搜索词
if (tabName === 'search') {
fetchHotSearches();
}
}
// 搜索磁力链接
async function searchMagnet() {
const input = document.getElementById('searchInput');
const resultsDiv = document.getElementById('searchResults');
const searchTerm = input.value.replace(/\s+/g, '').trim();
const notification = document.getElementById('notification');
const container = document.getElementById('coverImageContainer');
const regex = /^[A-Za-z][\w\s-]*\d$/;
if (!searchTerm || !regex.test(searchTerm)) {
notification.innerHTML = `
${translations[currentLang].emptySearchWarning}
`;
notification.style.background = '#dc2626';
notification.classList.add('show');
if (container) {
container.classList.add('hidden');
}
setTimeout(() => {
notification.classList.remove('show');
notification.style.background = '';
}, 3000);
return;
}
if (container) {
container.classList.add('hidden');
container.style.opacity = '0';
}
resultsDiv.innerHTML = '';
const loadingTemplate = document.getElementById('loadingTemplate');
resultsDiv.innerHTML = loadingTemplate.innerHTML;
setLanguage(currentLang);
try {
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.SEARCH}/${searchTerm}`);
const data = await response.json();
if (Array.isArray(data.data) && data.data.length > 0) {
// 解析并过滤无效结果
const formattedResults = data.data.map(result => {
if (Array.isArray(result)) {
return result;
}
try {
return JSON.parse(result.replace(/'/g, '"'));
} catch (e) {
console.error('解析结果出错:', e);
return null;
}
}).filter(result => result !== null);
// 对结果进行去重
const uniqueResults = formattedResults.filter((result, index, self) => {
// 使用磁力链接作为唯一标识
const magnet = result[0];
return index === self.findIndex(r => r[0] === magnet);
});
displaySearchResults(uniqueResults);
setTimeout(() => showCoverImage(searchTerm), 300);
} else {
resultsDiv.innerHTML = `
${translations[currentLang].noResults}
`;
if (container) {
container.classList.add('hidden');
}
}
} catch (error) {
console.error('搜索出错:', error);
resultsDiv.innerHTML = `${translations[currentLang].searchError}
`;
if (container) {
container.classList.add('hidden');
}
}
}
// 显示搜索结果
function displaySearchResults(results) {
const searchResults = document.getElementById('searchResults');
const coverToggle = document.getElementById('coverToggle');
// 如果开关是关闭状态,确保移除已存在的封面图容器
if (!coverToggle.checked) {
const existingCoverContainer = document.getElementById('coverImageContainer');
if (existingCoverContainer) {
existingCoverContainer.remove();
}
}
// 清空搜索结果
searchResults.innerHTML = '';
if (results.length === 0) {
searchResults.innerHTML = '未找到相关结果
';
return;
}
results.forEach(([magnet, title, size, date]) => {
const tags = extractTags(title);
const tagsHtml = tags.map(tag => {
return `${getTagLabel(tag.type)}
`;
}).join('');
const resultItem = document.createElement('div');
resultItem.className = 'magnet-item p-6 rounded-xl';
resultItem.innerHTML = `
${tagsHtml}
${translations[currentLang].size}: ${size} | ${translations[currentLang].date}: ${date}
`;
// 添加点击事件
const copyButton = resultItem.querySelector('.copy-button');
copyButton.addEventListener('click', () => {
copyToClipboard(magnet);
});
searchResults.appendChild(resultItem);
});
// 添加这一行,确保结果按照标签数量排序
sortResults('tags-desc');
}
// 显示封面图
function showCoverImage(searchTerm) {
const coverToggle = document.getElementById('coverToggle');
// 如果开关是关闭状态,直接返回
if (!coverToggle.checked) {
return;
}
// 获取或创建封面图容器
let coverImageContainer = document.getElementById('coverImageContainer');
let image = document.getElementById('coverImage');
// 如果容器不存在,创建容器和图片元素
if (!coverImageContainer) {
coverImageContainer = document.createElement('div');
coverImageContainer.id = 'coverImageContainer';
coverImageContainer.className = 'cover-image-container hidden card-3d';
// 创建图片元素
image = document.createElement('img');
image.id = 'coverImage';
image.className = 'cover-image';
image.alt = '封面图片';
// 将图片添加到容器中
coverImageContainer.appendChild(image);
// 将容器添加到搜索结果之前
document.getElementById('searchResults').insertAdjacentElement('beforebegin', coverImageContainer);
} else {
// 确保容器有3D卡片类
if (!coverImageContainer.classList.contains('card-3d')) {
coverImageContainer.classList.add('card-3d');
}
}
const modal = document.getElementById('imageModal');
const modalImage = document.getElementById('modalImage');
// 如果搜索词为空,隐藏图片
if (!searchTerm) {
coverImageContainer.classList.add('hidden');
return;
}
// 正则表达式匹配番号格式
const avMatch = searchTerm.match(/([a-zA-Z]+)[-]?(\d+)/i);
if (avMatch) {
// 提取番号的字母和数字部分
const prefix = avMatch[1].toLowerCase();
const number = avMatch[2].padStart(3, '0'); // 确保数字部分至少有3位
// 构建标准格式的番号 (例如: ipx-096)
const formattedAV = `${prefix}-${number}`;
// 构建图片URL
const imageUrl = `https://fourhoi.com/${formattedAV}/cover-n.jpg`;
// 设置图片源并显示容器
image.src = imageUrl;
coverImageContainer.style.opacity = '0';
coverImageContainer.classList.remove('hidden');
// 移除之前的 loaded 类
image.classList.remove('loaded');
// 处理图片加载完成
image.onload = () => {
requestAnimationFrame(() => {
coverImageContainer.style.transition = 'opacity 0.3s ease';
coverImageContainer.style.opacity = '1';
image.classList.add('loaded');
// 添加3D效果初始化
initCard3DEffect(coverImageContainer);
});
};
// 处理图片加载错误
image.onerror = () => {
coverImageContainer.classList.add('hidden');
};
// 点击图片显示大图
coverImageContainer.onclick = (e) => {
// 获取点击位置相对于容器的坐标
const rect = coverImageContainer.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 将容器分为3x3的网格,根据点击位置选择不同的图片
const width = rect.width;
const height = rect.height;
// 水平分为左、中、右三部分
const xSection = Math.floor(x / (width / 3));
// 垂直分为上、中、下三部分
const ySection = Math.floor(y / (height / 3));
// 根据9宫格位置选择不同的图片
const position = ySection * 3 + xSection;
// 预加载图片,确保图片存在再显示
const preloadImage = new Image();
// 所有位置都使用相同的图片URL
const newImageUrl = imageUrl;
// 显示加载指示器
const loadingIndicator = document.createElement('div');
loadingIndicator.className = 'modal-loading';
modal.querySelector('.modal-content').appendChild(loadingIndicator);
// 预加载图片
preloadImage.onload = () => {
// 图片加载成功,设置src并显示模态框
modalImage.src = newImageUrl;
modalImage.classList.add('fullwidth-preview');
modal.classList.remove('hidden');
// 移除加载指示器
if (loadingIndicator.parentNode) {
loadingIndicator.parentNode.removeChild(loadingIndicator);
}
setTimeout(() => {
modal.classList.add('active');
}, 10);
};
preloadImage.onerror = () => {
console.log(`预览图 ${newImageUrl} 加载失败`);
// 移除加载指示器
if (loadingIndicator.parentNode) {
loadingIndicator.parentNode.removeChild(loadingIndicator);
}
// 显示错误提示
modalImage.classList.add('error');
modal.classList.remove('hidden');
setTimeout(() => {
modal.classList.add('active');
}, 10);
};
// 开始加载图片
preloadImage.src = newImageUrl;
// 先显示模态框,但图片为空
modalImage.src = '';
modalImage.classList.remove('error');
modalImage.classList.remove('fullwidth-preview');
modal.classList.remove('hidden');
// 显示模态框时初始化事件
initializeModalEvents();
};
} else {
// 如果不是番号格式,隐藏图片容器
coverImageContainer.classList.add('hidden');
}
}
// 初始化3D卡片效果
function initCard3DEffect(card) {
if (!card) return;
// 移除之前可能添加的事件监听器
card.removeEventListener('mousemove', handleMouseMove);
card.removeEventListener('mouseleave', handleMouseLeave);
card.removeEventListener('mouseenter', handleMouseEnter);
// 添加事件监听器
card.addEventListener('mousemove', handleMouseMove);
card.addEventListener('mouseleave', handleMouseLeave);
card.addEventListener('mouseenter', handleMouseEnter);
}
// 处理鼠标移动事件
function handleMouseMove(e) {
const card = this;
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 计算鼠标位置相对于卡片中心的偏移
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const deltaX = (x - centerX) / centerX;
const deltaY = (y - centerY) / centerY;
// 减小旋转角度,从15度减小到8度
const rotateX = deltaY * -8;
const rotateY = deltaX * 8;
// 应用3D变换,减小缩放比例
card.style.transform = `perspective(1500px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.02, 1.02, 1.02)`;
// 减小光影效果的强度
card.style.boxShadow = `
0 5px 15px rgba(0,0,0,0.2),
${deltaX * 5}px ${deltaY * 5}px 15px rgba(0,0,0,0.1)
`;
// 减小图片内部的视差效果
const image = card.querySelector('img');
if (image) {
image.style.transform = `translateX(${deltaX * -5}px) translateY(${deltaY * -5}px)`;
// 添加亮度调整,使图片在不同角度下亮度均匀
const brightness = 1 + (deltaX * 0.05);
image.style.filter = `brightness(${brightness})`;
}
}
// 处理鼠标离开事件
function handleMouseLeave() {
const card = this;
// 重置变换
card.style.transform = 'perspective(1500px) rotateX(0) rotateY(0) scale3d(1, 1, 1)';
card.style.boxShadow = '0 4px 10px rgba(0, 0, 0, 0.2)';
// 重置图片位置和滤镜
const image = card.querySelector('img');
if (image) {
image.style.transform = 'translateX(0) translateY(0)';
image.style.filter = 'brightness(1)';
}
}
// 处理鼠标进入事件
function handleMouseEnter() {
const card = this;
// 添加初始变换效果,减小缩放比例
card.style.transition = 'transform 0.3s ease, box-shadow 0.3s ease';
card.style.transform = 'perspective(1500px) scale3d(1.01, 1.01, 1.01)';
card.style.boxShadow = '0 5px 15px rgba(0,0,0,0.2)';
// 短暂延迟后移除过渡效果,使鼠标移动时的变换更加流畅
setTimeout(() => {
card.style.transition = 'none';
}, 300); // 增加延迟时间,使过渡更平滑
}
// 视频播放功能
let hls = null;
let autoplayEnabled = localStorage.getItem('autoplay') === 'true'; // 从localStorage读取初始值
let autoNextEnabled = localStorage.getItem('autoNext') === 'true'; // 从localStorage读取初始值
let isLoadingNextVideo = false; // 添加锁定标志,防止重复请求
// 初始化自动播放设置
function initializeAutoplaySettings() {
const autoplayToggle = document.getElementById('autoplayToggle');
const autoNextToggle = document.getElementById('autoNextToggle');
// 从localStorage读取设置
autoplayToggle.checked = autoplayEnabled;
autoNextToggle.checked = autoNextEnabled;
// 监听自动播放开关变化
autoplayToggle.addEventListener('change', function() {
autoplayEnabled = this.checked;
localStorage.setItem('autoplay', this.checked);
});
// 监听自动下一个开关变化
autoNextToggle.addEventListener('change', function() {
autoNextEnabled = this.checked;
localStorage.setItem('autoNext', this.checked);
});
}
// 初始化封面图开关设置
function initializeCoverToggle() {
const coverToggle = document.getElementById('coverToggle');
// 从localStorage读取设置
const showCover = localStorage.getItem('showCover') !== 'false';
coverToggle.checked = showCover;
// 监听开关变化
coverToggle.addEventListener('change', function() {
localStorage.setItem('showCover', this.checked);
// 如果在搜索页面,重新触发搜索以更新显示
if (currentTab === 'search') {
const searchInput = document.getElementById('searchInput');
if (searchInput.value.trim()) {
searchMagnet(); // 重新触发搜索
} else {
// 如果没有搜索内容,只需要处理封面图容器
const existingCoverContainer = document.getElementById('coverImageContainer');
if (existingCoverContainer) {
existingCoverContainer.remove();
}
}
}
// 如果在视频播放页面,重新加载视频以更新封面图
else if (currentTab === 'player') {
loadVideo();
}
});
}
// 修改 loadVideo 函数
function loadVideo() {
try {
const videoPlayer = document.getElementById('videoPlayer');
const videoSourceUrl = document.getElementById('videoSourceUrl');
const notification = document.getElementById('notification');
const showCover = document.getElementById('coverToggle')?.checked || false;
// 确保视频播放器可操作
if (videoPlayer) {
videoPlayer.controls = true;
}
// 如果已经有视频URL,则不重新请求
if (currentVideoUrl) {
if (videoSourceUrl) {
videoSourceUrl.textContent = currentVideoUrl;
}
if (videoPlayer && videoPlayer.src !== currentVideoUrl) {
// 移除之前的事件监听器
videoPlayer.onended = null;
// 使用HLS.js播放m3u8视频
if (currentVideoUrl.includes('.m3u8')) {
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(currentVideoUrl);
hls.attachMedia(videoPlayer);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
// 根据自动播放设置决定是否播放
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
});
// 存储HLS实例以便清理
videoPlayer.hlsInstance = hls;
} else if (videoPlayer.canPlayType('application/vnd.apple.mpegurl')) {
// 原生支持HLS的浏览器(如Safari)
videoPlayer.src = currentVideoUrl;
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
} else {
console.error('当前浏览器不支持HLS视频播放');
notification.innerHTML = `
${translations[currentLang].browserNotSupported || '当前浏览器不支持该视频格式'}
`;
notification.style.background = '#dc2626';
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
notification.style.background = '';
}, 3000);
}
} else {
// 非m3u8格式视频使用标准方式播放
videoPlayer.src = currentVideoUrl;
// 根据自动播放设置决定是否播放
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
}
// 添加视频结束事件监听
videoPlayer.onended = handleVideoEnded;
}
// 重置锁定状态
isLoadingNextVideo = false;
return;
}
// 设置加载状态为true
isLoadingNextVideo = true;
// 显示加载中通知
notification.innerHTML = `
${translations[currentLang].loadingVideo}
`;
notification.classList.add('show');
// 如果没有视频URL,则请求新的
fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.VIDEO}`)
.then(response => response.json())
.then(data => {
if (data && data.url) {
currentVideoUrl = data.url; // 保存视频URL
if (videoSourceUrl) {
videoSourceUrl.textContent = data.url;
}
if (videoPlayer) {
// 移除之前的事件监听器
videoPlayer.onended = null;
// 确保控件可用
videoPlayer.controls = true;
// 设置视频封面(如果开启了封面图显示)
if (showCover && data.img_url) {
videoPlayer.poster = data.img_url;
} else {
videoPlayer.poster = ''; // 清除封面图
}
// 清理之前的HLS实例(如果存在)
if (videoPlayer.hlsInstance) {
videoPlayer.hlsInstance.destroy();
videoPlayer.hlsInstance = null;
}
// 使用HLS.js播放m3u8视频
if (data.url.includes('.m3u8')) {
if (Hls.isSupported()) {
const hls = new Hls({
// 添加更多的HLS配置,以增强稳定性
maxBufferLength: 30,
maxMaxBufferLength: 60
});
hls.loadSource(data.url);
hls.attachMedia(videoPlayer);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
// 根据自动播放设置决定是否播放
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
});
// 存储HLS实例以便清理
videoPlayer.hlsInstance = hls;
} else if (videoPlayer.canPlayType('application/vnd.apple.mpegurl')) {
// 原生支持HLS的浏览器(如Safari)
videoPlayer.src = data.url;
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
} else {
console.error('当前浏览器不支持HLS视频播放');
notification.innerHTML = `
${translations[currentLang].browserNotSupported || '当前浏览器不支持该视频格式'}
`;
notification.style.background = '#dc2626';
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
notification.style.background = '';
}, 3000);
}
} else {
// 非m3u8格式视频使用标准方式播放
videoPlayer.src = data.url;
// 根据自动播放设置决定是否播放
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
}
// 添加视频结束事件监听
videoPlayer.onended = handleVideoEnded;
}
// 隐藏加载通知
notification.classList.remove('show');
}
// 重置加载状态
isLoadingNextVideo = false;
})
.catch(error => {
console.error('加载视频失败:', error);
notification.innerHTML = `
${translations[currentLang].videoError}
`;
notification.style.background = '#dc2626';
setTimeout(() => {
notification.classList.remove('show');
notification.style.background = '';
}, 3000);
// 重置加载状态
isLoadingNextVideo = false;
// 确保播放器可用
if (videoPlayer) {
videoPlayer.controls = true;
}
});
} catch (error) {
console.error('loadVideo函数出错:', error);
// 确保播放器可用
const videoPlayer = document.getElementById('videoPlayer');
if (videoPlayer) {
videoPlayer.controls = true;
}
// 重置加载状态
isLoadingNextVideo = false;
}
}
// 处理视频结束事件
function handleVideoEnded() {
console.log("视频结束事件触发", autoNextEnabled, isLoadingNextVideo);
// 确保视频播放器可操作
const videoPlayer = document.getElementById('videoPlayer');
if (videoPlayer) {
// 确保控件可用
videoPlayer.controls = true;
}
if (autoNextEnabled && !isLoadingNextVideo) {
isLoadingNextVideo = true;
setTimeout(() => {
// 延迟一点时间再加载下一个视频,防止事件冲突
clearVideoUrl();
}, 100);
} else {
// 如果不需要自动播放下一个,也要确保重置锁定状态
isLoadingNextVideo = false;
}
}
// 添加清除视频URL的函数(可以在需要重新加载视频时调用)
function clearVideoUrl() {
try {
// 确保视频播放器可操作
const videoPlayer = document.getElementById('videoPlayer');
if (videoPlayer) {
// 确保控件可用
videoPlayer.controls = true;
// 移除视频事件监听器
videoPlayer.onended = null;
// 清理HLS实例
if (videoPlayer.hlsInstance) {
videoPlayer.hlsInstance.destroy();
videoPlayer.hlsInstance = null;
}
}
// 清除URL并加载新视频
currentVideoUrl = '';
// 确保loadVideo函数被调用
setTimeout(() => {
loadVideo();
}, 200);
} catch (error) {
console.error('清除视频URL出错:', error);
// 发生错误时重置锁定状态
isLoadingNextVideo = false;
}
}
// 初始化视频播放器
document.addEventListener('DOMContentLoaded', () => {
// 设置初始主题
const savedTheme = localStorage.getItem('theme') || 'dark';
toggleTheme(savedTheme);
// 设置初始语言
const savedLang = localStorage.getItem('language') || 'zh';
setLanguage(savedLang);
// 初始化所有按钮
initializeButtons();
// 初始化视频相关功能
initializeAutoplaySettings();
initializeCoverToggle();
// 加载合集列表
loadCollections();
// 添加事件监听器
// 语言切换按钮
const langButton = document.getElementById('languageToggle');
if (langButton) {
langButton.onclick = () => showLanguageMenu(langButton);
}
// 主题切换按钮
const themeButton = document.getElementById('themeToggle');
if (themeButton) {
themeButton.onclick = () => showThemeMenu(themeButton);
}
// 搜索输入框添加回车键触发搜索
const searchInput = document.getElementById('searchInput');
if (searchInput) {
searchInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
event.preventDefault();
searchMagnet();
}
});
}
// 回到顶部按钮
const backToTopButton = document.getElementById('backToTop');
if (backToTopButton) {
// 初始隐藏按钮
backToTopButton.classList.add('hidden');
// 监听滚动事件
window.addEventListener('scroll', function() {
if (window.scrollY > 300) {
backToTopButton.classList.remove('hidden');
} else {
backToTopButton.classList.add('hidden');
}
});
// 点击事件
backToTopButton.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
}
// 初始化大图预览功能
const modal = document.getElementById('imageModal');
const closeButton = document.getElementById('closeModal');
// 关闭按钮点击事件
if (closeButton) {
closeButton.onclick = () => {
modal.classList.remove('active');
setTimeout(() => {
modal.classList.add('hidden');
}, 300);
};
}
// 点击模态框背景关闭
if (modal) {
modal.onclick = (e) => {
if (e.target === modal) {
modal.classList.remove('active');
setTimeout(() => {
modal.classList.add('hidden');
}, 300);
}
};
}
// ESC键关闭模态框
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal && !modal.classList.contains('hidden')) {
modal.classList.remove('active');
setTimeout(() => {
modal.classList.add('hidden');
}, 300);
}
});
// 下一个视频按钮
const nextVideoButton = document.getElementById('nextVideo');
if (nextVideoButton) {
nextVideoButton.addEventListener('click', () => {
clearVideoUrl(); // 使用clearVideoUrl函数来处理
});
}
// 如果当前是搜索标签页,获取热门搜索词
if (currentTab === 'search') {
fetchHotSearches();
}
// 添加页面卸载事件处理,清理HLS实例
window.addEventListener('beforeunload', () => {
const videoPlayer = document.getElementById('videoPlayer');
if (videoPlayer && videoPlayer.hlsInstance) {
videoPlayer.hlsInstance.destroy();
videoPlayer.hlsInstance = null;
}
});
});
// 初始化复制按钮功能
function initializeCopyButton() {
// 现在我们使用全局函数,这个函数不再需要实际功能
console.log('Using global copyVideoUrl function');
}
// 语言配置
const translations = {
zh: {
search: 'AV搜索',
collections: '里番合集',
player: '视频播放',
searchPlaceholder: '请输入AV番号...',
searchButton: '搜索',
copyButton: '复制链接',
noResults: '未找到相关结果',
searchError: '搜索出错,请稍后重试',
size: '大小',
date: '日期',
emptySearchWarning: '搜索词为空或有误,请重新输入',
copySuccess: '已复制到剪贴板',
copyError: '复制失败,请手动复制',
loading: '正在搜索中',
pageSize: '每页显示',
items: '条',
total: '共',
currentPage: '当前第',
page: '页',
prevPage: '上一页',
nextPage: '下一页',
goToPage: '跳转到',
sortByDate: '按日期排序',
sortBySize: '按大小排序',
newest: '最新',
oldest: '最早',
largest: '最大',
smallest: '最小',
next: '下一个',
loadingVideo: '正在加载视频...',
videoError: '视频加载失败,请稍后重试',
nsfw: '⚠️ 警告:该内容包含成人内容 (NSFW),请确保您已年满18岁',
autoplay: '自动播放',
sourceUrl: '视频源地址',
copy: '复制',
copied: '已复制',
copyFailed: '复制失败',
browserNotSupported: '当前浏览器不支持该视频格式'
},
en: {
search: 'AV Search',
collections: 'Anime Collection',
player: 'Video Player',
searchPlaceholder: 'Enter AV number...',
searchButton: 'Search',
copyButton: 'Copy Link',
noResults: 'No results found',
searchError: 'Search error, please try again later',
size: 'Size',
date: 'Date',
emptySearchWarning: 'The search term is empty or incorrect, please re-enter',
copySuccess: 'Copied to clipboard',
copyError: 'Copy failed, please copy manually',
loading: 'Searching',
pageSize: 'Show',
items: 'items',
total: 'Total',
currentPage: 'Page',
page: '',
prevPage: 'Previous',
nextPage: 'Next',
goToPage: 'Go to page',
sortByDate: 'Sort by date',
sortBySize: 'Sort by size',
newest: 'Newest',
oldest: 'Oldest',
largest: 'Largest',
smallest: 'Smallest',
next: 'Next',
loadingVideo: 'Loading video...',
videoError: 'Failed to load video, please try again later',
nsfw: '⚠️ Warning: This content contains adult material (NSFW), ensure you are 18+',
autoplay: 'Auto Play',
sourceUrl: 'Video Source URL',
copy: 'Copy',
copied: 'Copied',
copyFailed: 'Copy Failed',
browserNotSupported: 'Current browser does not support this video format'
}
};
// 语言图标配置
const LANGUAGES = {
zh: {
icon: ``,
label: '中文'
},
en: {
icon: ``,
label: 'English'
}
};
// 当前语言
let currentLang = 'zh';
// 主题配置
const THEMES = {
dark: {
icon: ``,
label: { zh: '夜间', en: 'Dark' }
},
light: {
icon: ``,
label: { zh: '日间', en: 'Light' }
},
emerald: {
icon: ``,
label: { zh: '翠绿', en: 'Emerald' }
},
ocean: {
icon: ``,
label: { zh: '海蓝', en: 'Ocean' }
},
amethyst: {
icon: ``,
label: { zh: '紫晶', en: 'Amethyst' }
}
};
// 排序配置
const SORT_OPTIONS = {
'tags-desc': {
icon: ``,
label: { zh: '标签最多', en: 'Most Tags' }
},
'date-desc': {
icon: ``,
label: { zh: '最新日期', en: 'Newest' }
},
'date-asc': {
icon: ``,
label: { zh: '最早日期', en: 'Oldest' }
},
'size-desc': {
icon: ``,
label: { zh: '文件最大', en: 'Largest' }
},
'size-asc': {
icon: ``,
label: { zh: '文件最小', en: 'Smallest' }
}
};
// 切换主题功能
function toggleTheme(themeName) {
// 移除所有主题类
document.body.removeAttribute('data-theme');
// 设置新主题
document.body.setAttribute('data-theme', themeName);
// 保存主题设置
localStorage.setItem('theme', themeName);
// 更新主题按钮图标
const themeButton = document.getElementById('themeToggle');
if (themeButton) {
themeButton.innerHTML = THEMES[themeName].icon;
}
// 重新初始化所有按钮事件
initializeButtons();
}
// 初始化所有按钮事件
function initializeButtons() {
// 初始化标签页按钮
document.querySelectorAll('.tab-button').forEach(button => {
const tabName = button.dataset.tab;
button.onclick = () => switchTab(tabName);
});
// 初始化主题切换按钮
const themeButton = document.getElementById('themeToggle');
if (themeButton) {
themeButton.onclick = () => showThemeMenu(themeButton);
}
// 初始化语言切换按钮
const langButton = document.getElementById('languageToggle');
if (langButton) {
langButton.onclick = () => showLanguageMenu(langButton);
}
// 初始化排序按钮
const sortButton = document.getElementById('sortButton');
if (sortButton) {
sortButton.onclick = () => showSortMenu(sortButton);
}
}
// 显示语言菜单
function showLanguageMenu(button) {
const existingMenu = document.querySelector('.language-menu');
if (existingMenu) {
existingMenu.remove();
return;
}
const menu = document.createElement('div');
menu.className = 'theme-menu language-menu';
// 对号图标 SVG
const checkmarkSvg = ``;
menu.innerHTML = `
`;
// 将菜单添加到 body
document.body.appendChild(menu);
// 计算菜单位置
const buttonRect = button.getBoundingClientRect();
const menuRect = menu.getBoundingClientRect();
// 确保菜单不会超出视口
let top = buttonRect.bottom;
let left = Math.min(
buttonRect.left,
window.innerWidth - menuRect.width - 10
);
// 如果菜单会超出底部,则显示在按钮上方
if (top + menuRect.height > window.innerHeight) {
top = buttonRect.top - menuRect.height;
}
menu.style.position = 'fixed';
menu.style.top = `${top}px`;
menu.style.left = `${left}px`;
menu.style.zIndex = '1000';
// 窗口滚动时更新菜单位置
const updateMenuPosition = () => {
const updatedRect = button.getBoundingClientRect();
let newTop = updatedRect.bottom;
// 如果菜单会超出底部,则显示在按钮上方
if (newTop + menuRect.height > window.innerHeight) {
newTop = updatedRect.top - menuRect.height;
}
menu.style.top = `${newTop}px`;
menu.style.left = `${Math.min(updatedRect.left, window.innerWidth - menuRect.width - 10)}px`;
};
window.addEventListener('scroll', updateMenuPosition);
window.addEventListener('resize', updateMenuPosition);
menu.addEventListener('click', (e) => {
const langItem = e.target.closest('.theme-menu-item');
if (langItem) {
const newLang = langItem.dataset.lang;
setLanguage(newLang);
menu.remove();
window.removeEventListener('scroll', updateMenuPosition);
window.removeEventListener('resize', updateMenuPosition);
}
});
// 点击其他区域关闭菜单
const closeMenu = (e) => {
if (!button.contains(e.target) && !menu.contains(e.target)) {
menu.remove();
document.removeEventListener('click', closeMenu);
window.removeEventListener('scroll', updateMenuPosition);
window.removeEventListener('resize', updateMenuPosition);
}
};
// 使用 re·uestAnimationFrame 延迟添加点击事件,避免立即触发
requestAnimationFrame(() => {
document.addEventListener('click', closeMenu);
});
// ESC 键关闭菜单
const handleEscape = (e) => {
if (e.key === 'Escape') {
menu.remove();
document.removeEventListener('keydown', handleEscape);
document.removeEventListener('click', closeMenu);
window.removeEventListener('scroll', updateMenuPosition);
window.removeEventListener('resize', updateMenuPosition);
}
};
document.addEventListener('keydown', handleEscape);
}
// 语言切换功能
function setLanguage(lang) {
currentLang = lang;
localStorage.setItem('language', lang);
// 不再需要更新语言按钮文本,因为我们使用固定的"文"字符作为图标
// const languageButton = document.getElementById('languageToggle');
// if (languageButton) {
// languageButton.querySelector('.language-text').textContent =
// lang === 'zh' ? '中文' : 'English';
// }
// 更新所有带有 data-zh 和 data-en 属性的元素
document.querySelectorAll('[data-zh][data-en]').forEach(element => {
element.textContent = lang === 'zh' ? element.getAttribute('data-zh') : element.getAttribute('data-en');
});
// 更新搜索框占位符
const searchInput = document.getElementById('searchInput');
if (searchInput) {
searchInput.placeholder = lang === 'zh' ?
searchInput.getAttribute('data-zh-placeholder') :
searchInput.getAttribute('data-en-placeholder');
}
// 更新排序按钮文本
const sortButton = document.getElementById('sortButton');
if (sortButton && sortButton.value) {
const sortOption = SORT_OPTIONS[sortButton.value];
if (sortOption) {
sortButton.innerHTML = `
${sortOption.icon}
${sortOption.label[lang]}
`;
}
}
// 更新主题菜单文本
const themeMenuItems = document.querySelectorAll('.theme-menu-item');
themeMenuItems.forEach(item => {
const themeName = item.dataset.theme;
if (themeName && THEMES[themeName]) {
const label = item.querySelector('.theme-label');
if (label) {
label.textContent = THEMES[themeName].label[lang];
}
}
});
// 更新分页控件文本
updatePaginationText();
// 更新所有按钮文本
document.querySelectorAll('button').forEach(button => {
// 更新搜索按钮
if (button.classList.contains('search-button')) {
const searchText = button.querySelector('.tab-text');
if (searchText) {
searchText.textContent = translations[lang].searchButton;
}
}
// 更新复制按钮
if (button.classList.contains('copy-button')) {
button.textContent = translations[lang].copyButton;
}
});
// 重新渲染搜索结果
const searchResults = document.getElementById('searchResults');
if (searchResults && searchResults.children.length > 0) {
const firstChild = searchResults.firstElementChild;
if (!firstChild.classList.contains('loading-container') &&
firstChild.tagName.toLowerCase() !== 'p') {
try {
const results = Array.from(searchResults.children).map(item => {
const title = item.querySelector('h3').textContent;
const info = item.querySelector('p').textContent;
const [size, date] = info.split('|').map(str => str.split(':')[1].trim());
const magnet = item.querySelector('button').getAttribute('onclick').split("'")[1];
return [magnet, title, size, date];
});
displaySearchResults(results);
} catch (error) {
console.error('解析搜索结果失败:', error);
}
}
}
// 重新加载合集
const collectionsTab = document.getElementById('collectionsTab');
if (collectionsTab && !collectionsTab.classList.contains('hidden')) {
loadCollections();
}
// 更新加载动画文本
const loadingText = document.querySelector('.loading-text');
if (loadingText) {
loadingText.textContent = translations[lang].loading;
}
// 更新所有错误和提示消息
document.querySelectorAll('.notification, .error-message, .info-message').forEach(el => {
const messageKey = el.dataset.messageKey;
if (messageKey && translations[lang][messageKey]) {
el.textContent = translations[lang][messageKey];
}
});
// 更新模态框关闭提示文本
const modal = document.getElementById('imageModal');
if (modal) {
modal.setAttribute('data-close-text',
lang === 'en' ? 'Click anywhere to close' : '点击任意位置关闭'
);
}
}
// 更新分页控件文本
function updatePaginationText() {
const paginationElements = document.querySelectorAll('.pagination-container');
paginationElements.forEach(container => {
const prevBtn = container.querySelector('.prev-page');
const nextBtn = container.querySelector('.next-page');
const pageInfo = container.querySelector('.page-info');
const pageSizeSelect = container.querySelector('.page-size-select');
if (prevBtn) prevBtn.textContent = translations[currentLang].prevPage;
if (nextBtn) nextBtn.textContent = translations[currentLang].nextPage;
if (pageInfo) {
const currentPage = pageInfo.dataset.currentPage;
const totalPages = pageInfo.dataset.totalPages;
const pageSize = pageInfo.dataset.pageSize;
pageInfo.textContent = `${translations[currentLang].currentPage}${currentPage}${translations[currentLang].page} / ${translations[currentLang].total}${totalPages}${translations[currentLang].page}`;
}
if (pageSizeSelect) {
const label = pageSizeSelect.previousElementSibling;
if (label) {
label.textContent = `${translations[currentLang].pageSize}: `;
}
const suffix = pageSizeSelect.nextElementSibling;
if (suffix) {
suffix.textContent = ` ${translations[currentLang].items}`;
}
}
});
}
// 解析文件大小
function parseFileSize(sizeStr) {
try {
// 确保输入是字符串
sizeStr = String(sizeStr).trim();
// 匹配数字和单位
const match = sizeStr.match(/^([\d.]+)\s*([KMGT]?B)$/i);
if (!match) return 0;
const [, value, unit] = match;
const size = parseFloat(value);
// 转换到字节
switch (unit.toUpperCase()) {
case 'KB':
return size * 1024;
case 'MB':
return size * 1024 * 1024;
case 'GB':
return size * 1024 * 1024 * 1024;
case 'TB':
return size * 1024 * 1024 * 1024 * 1024;
case 'B':
default:
return size;
}
} catch (error) {
console.error('解析文件大小错误:', error);
return 0;
}
}
// 排序功能
function sortResults(sortType) {
const resultsDiv = document.getElementById('searchResults');
const results = Array.from(resultsDiv.children);
if (results.length === 0 || results[0].classList.contains('loading-container')) {
return;
}
results.sort((a, b) => {
try {
const aInfo = a.querySelector('p').textContent;
const bInfo = b.querySelector('p').textContent;
// 提取大小和日期
const [aSize, aDate] = aInfo.split('|').map(str => str.split(':')[1].trim());
const [bSize, bDate] = bInfo.split('|').map(str => str.split(':')[1].trim());
// 获取标签数量
const aTagCount = a.querySelectorAll('.tag').length;
const bTagCount = b.querySelectorAll('.tag').length;
switch (sortType) {
case 'tags-desc':
return bTagCount - aTagCount;
case 'date-desc':
return new Date(bDate || 0) - new Date(aDate || 0);
case 'date-asc':
return new Date(aDate || 0) - new Date(bDate || 0);
case 'size-desc':
return parseFileSize(bSize) - parseFileSize(aSize);
case 'size-asc':
return parseFileSize(aSize) - parseFileSize(bSize);
default:
return bTagCount - aTagCount; // 默认按标签数量排序
}
} catch (error) {
console.error('排序比较错误:', error);
return 0;
}
});
// 清空并重新添加排序后的结果
resultsDiv.innerHTML = '';
results.forEach(result => resultsDiv.appendChild(result));
}
// 显示动漫合集
function displayCollections(collections) {
const collectionList = document.getElementById('collectionList');
// 清空现有内容
collectionList.innerHTML = '';
// 检查collections是否为数组
if (Array.isArray(collections)) {
// 处理数组类型的数据
collections.forEach(collection => {
const collectionItem = document.createElement('div');
collectionItem.className = 'magnet-item p-6 rounded-xl';
const linkText = collection.link;
collectionItem.innerHTML = `
`;
// 添加点击事件
const copyButton = collectionItem.querySelector('.copy-button');
copyButton.addEventListener('click', () => {
copyToClipboard(linkText);
});
collectionList.appendChild(collectionItem);
});
} else if (typeof collections === 'object' && collections !== null) {
// 处理对象类型的数据
Object.entries(collections).forEach(([title, link]) => {
const collectionItem = document.createElement('div');
collectionItem.className = 'magnet-item p-6 rounded-xl';
collectionItem.innerHTML = `
`;
// 添加点击事件
const copyButton = collectionItem.querySelector('.copy-button');
copyButton.addEventListener('click', () => {
copyToClipboard(link);
});
collectionList.appendChild(collectionItem);
});
} else {
// 没有数据或数据格式不正确
collectionList.innerHTML = `${translations[currentLang].noResults}
`;
}
}
// 获取标签文字
function getTagLabel(type) {
const tagLabels = {
hd: { zh: '高清', en: 'HD' },
subtitle: { zh: '字幕', en: 'SUB' },
uncensored: { zh: '无码', en: 'Uncensored' },
chinese: { zh: '中文', en: 'Chinese' },
leak: { zh: '破解', en: 'Leaked' }
};
return tagLabels[type][currentLang];
}
// 提取标签
function extractTags(title) {
const tags = [];
const tagMap = {
// 高清标签
'HD': {type: 'hd', priority: 1},
'FHD': {type: 'hd', priority: 1},
'高清': {type: 'hd', priority: 1},
// 字幕标签
'字幕': {type: 'subtitle', priority: 2},
'-C': {type: 'subtitle', priority: 2},
'sub': {type: 'subtitle', priority: 2},
'SUB': {type: 'subtitle', priority: 2},
// 无码标签
'無修正': {type: 'uncensored', priority: 3},
'无码': {type: 'uncensored', priority: 3},
'uncensored': {type: 'uncensored', priority: 3},
// 中文标签
'中文': {type: 'chinese', priority: 4},
'ch': {type: 'chinese', priority: 4},
'CH': {type: 'chinese', priority: 4},
'chinese': {type: 'chinese', priority: 4},
// 破解标签
'破解': {type: 'leak', priority: 5},
'leak': {type: 'leak', priority: 5},
'LEAK': {type: 'leak', priority: 5}
};
// 将标题转换为小写以进行不区分大小写的匹配
const lowerTitle = title.toLowerCase();
// 使用 Set 来存储已添加的标签类型,避免重复
const addedTypes = new Set();
// 遍历所有关键词进行匹配
Object.entries(tagMap).forEach(([keyword, {type, priority}]) => {
// 如果这个类型的标签还没有添加过,并且标题中包含关键词
if (!addedTypes.has(type) && lowerTitle.includes(keyword.toLowerCase())) {
tags.push({type, priority});
addedTypes.add(type);
}
});
// 按优先级排序
return tags.sort((a, b) => a.priority - b.priority);
}
// 获取标签样式
function getTagStyle(tag) {
// 更新标签样式为玻璃态设计
const styleMap = {
'高清': 'bg-blue-500/20 text-blue-300',
'字幕': 'bg-green-500/20 text-green-300',
'无码': 'bg-red-500/20 text-red-300',
'有码': 'bg-yellow-500/20 text-yellow-300',
'中文': 'bg-purple-500/20 text-purple-300',
'无修正': 'bg-pink-500/20 text-pink-300',
'破解版': 'bg-indigo-500/20 text-indigo-300'
};
return styleMap[tag] || 'bg-gray-500/20 text-gray-300';
}
// 加载动漫合集
async function loadCollections() {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.COLLECTIONS}`);
const data = await response.json();
displayCollections(data.data);
} catch (error) {
console.error('加载合集失败:', error);
}
}
// 复制到剪贴板
function copyToClipboard(text) {
const notification = document.getElementById('notification');
// 显示通知的辅助函数
const showNotification = (success) => {
notification.innerHTML = success ? `
${translations[currentLang].copySuccess}
` : `
${translations[currentLang].copyError}
`;
notification.style.background = success ? '#1bb76e' : '#dc2626';
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
notification.style.background = '';
}, 3000);
};
// 尝试使用 Clipboard API
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text)
.then(() => showNotification(true))
.catch(() => {
// 如果 Clipboard API 失败,回退到 execCommand 方法
fallbackCopyToClipboard(text);
});
} else {
// 在非安全上下文中直接使用 execCommand 方法
fallbackCopyToClipboard(text);
}
// execCommand 复制方法
function fallbackCopyToClipboard(text) {
try {
// 创建临时文本区域
const textArea = document.createElement('textarea');
textArea.value = text;
// 设置样式使其不可见
textArea.style.position = 'fixed';
textArea.style.top = '0';
textArea.style.left = '0';
textArea.style.width = '2em';
textArea.style.height = '2em';
textArea.style.padding = '0';
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
textArea.style.background = 'transparent';
textArea.style.opacity = '0';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
// 尝试执行复制命令
const successful = document.execCommand('copy');
document.body.removeChild(textArea);
showNotification(successful);
} catch (err) {
console.error('复制失败:', err);
showNotification(false);
}
}
}
// 修改排序下拉菜单
function showSortMenu(button) {
const existingMenu = document.querySelector('.sort-menu');
if (existingMenu) {
existingMenu.remove();
return;
}
const currentSort = button.value || 'tags-desc'; // 默认使用标签排序
const sortMenu = document.createElement('div');
sortMenu.className = 'sort-menu';
button.parentElement.style.position = 'relative';
sortMenu.innerHTML = Object.entries(SORT_OPTIONS).map(([value, option]) => `
`).join('');
button.parentElement.appendChild(sortMenu);
sortMenu.addEventListener('click', (e) => {
const sortItem = e.target.closest('.theme-menu-item');
if (sortItem) {
const newSort = sortItem.dataset.sort;
button.value = newSort;
sortResults(newSort);
button.innerHTML = `
${SORT_OPTIONS[newSort].icon}
${SORT_OPTIONS[newSort].label[currentLang]}
`;
sortMenu.remove();
}
});
document.addEventListener('click', (e) => {
if (!button.contains(e.target) && !sortMenu.contains(e.target)) {
sortMenu.remove();
}
}, { once: true });
}
// 显示主题菜单
function showThemeMenu(button) {
const existingMenu = document.querySelector('.theme-menu');
if (existingMenu) {
existingMenu.remove();
return;
}
const currentTheme = localStorage.getItem('theme') || 'dark';
const themeMenu = document.createElement('div');
themeMenu.className = 'theme-menu';
themeMenu.innerHTML = Object.entries(THEMES).map(([name, theme]) => `
`).join('');
// 将菜单添加到 body 而不是按钮中
document.body.appendChild(themeMenu);
// 计算菜单位置
const buttonRect = button.getBoundingClientRect();
const menuRect = themeMenu.getBoundingClientRect();
// 确保菜单不会超出视口
let top = buttonRect.bottom;
let left = Math.min(
buttonRect.left,
window.innerWidth - menuRect.width - 10
);
// 如果菜单会超出底部,则显示在按钮上方
if (top + menuRect.height > window.innerHeight) {
top = buttonRect.top - menuRect.height;
}
themeMenu.style.position = 'fixed';
themeMenu.style.top = `${top}px`;
themeMenu.style.left = `${left}px`;
themeMenu.style.zIndex = '1000';
// 窗口滚动时更新菜单位置
const updateMenuPosition = () => {
const updatedRect = button.getBoundingClientRect();
let newTop = updatedRect.bottom;
// 如果菜单会超出底部,则显示在按钮上方
if (newTop + menuRect.height > window.innerHeight) {
newTop = updatedRect.top - menuRect.height;
}
themeMenu.style.top = `${newTop}px`;
themeMenu.style.left = `${Math.min(updatedRect.left, window.innerWidth - menuRect.width - 10)}px`;
};
window.addEventListener('scroll', updateMenuPosition);
window.addEventListener('resize', updateMenuPosition);
// 点击菜单项时切换主题并关闭菜单
themeMenu.addEventListener('click', (e) => {
const themeItem = e.target.closest('.theme-menu-item');
if (themeItem) {
const newTheme = themeItem.dataset.theme;
toggleTheme(newTheme);
themeMenu.remove();
window.removeEventListener('scroll', updateMenuPosition);
window.removeEventListener('resize', updateMenuPosition);
}
});
// 点击其他区域关闭菜单
const closeMenu = (e) => {
if (!button.contains(e.target) && !themeMenu.contains(e.target)) {
themeMenu.remove();
document.removeEventListener('click', closeMenu);
window.removeEventListener('scroll', updateMenuPosition);
window.removeEventListener('resize', updateMenuPosition);
}
};
// 使用 requestAnimationFrame 延迟添加点击事件,避免立即触发
requestAnimationFrame(() => {
document.addEventListener('click', closeMenu);
});
// ESC 键关闭菜单
const handleEscape = (e) => {
if (e.key === 'Escape') {
themeMenu.remove();
document.removeEventListener('keydown', handleEscape);
document.removeEventListener('click', closeMenu);
window.removeEventListener('scroll', updateMenuPosition);
window.removeEventListener('resize', updateMenuPosition);
}
};
document.addEventListener('keydown', handleEscape);
}
// 修改 Service Worker 注册代码
if ('serviceWorker' in navigator && window.location.protocol === 'https:') {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./sw.js') // 使用相对路径
.then(registration => {
console.log('ServiceWorker registration successful');
})
.catch(err => {
console.error('ServiceWorker registration failed: ', err);
});
});
} else {
console.log('ServiceWorker is not supported or requires HTTPS');
}
// 修改模态框点击事件处理
function initializeModalEvents() {
const modal = document.getElementById('imageModal');
const modalImage = document.getElementById('modalImage');
// 设置关闭提示文本
modal.setAttribute('data-close-text',
currentLang === 'en' ? 'Click anywhere to close' : '点击任意位置关闭'
);
// 点击模态框任意位置关闭
modal.addEventListener('click', (e) => {
// 添加关闭动画
modal.classList.remove('active');
modalImage.style.transform = 'scale(0.9)';
modalImage.style.opacity = '0';
// 延迟隐藏模态框,等待动画完成
setTimeout(() => {
modal.classList.add('hidden');
// 重置图片样式
modalImage.style.transform = '';
modalImage.style.opacity = '';
}, 300);
});
}
// 添加获取热门搜索的函数
async function fetchHotSearches() {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.HOT_SEARCHES}`);
const data = await response.json();
if (data.status === 'succeed' && Array.isArray(data.data)) {
const hotSearchesContainer = document.getElementById('hotSearches');
// 清空现有内容
hotSearchesContainer.innerHTML = '';
// 创建并添加热门搜索标签
data.data.forEach(term => {
const button = document.createElement('button');
button.className = 'hot-search-tag';
button.textContent = term;
// 添加点击事件监听
button.addEventListener('click', () => {
searchWithTerm(term);
});
hotSearchesContainer.appendChild(button);
});
}
} catch (error) {
console.error('获取热门搜索失败:', error);
}
}
// 添加点击热门搜索词的处理函数
function searchWithTerm(term) {
const searchInput = document.getElementById('searchInput');
searchInput.value = term;
searchMagnet();
}