Greasy Fork is available in English.
video list
Этот скрипт недоступен для установки пользователем. Он является библиотекой, которая подключается к другим скриптам мета-ключом // @require https://update.greasyfork.org/scripts/498124/1396763/video.js
function generateJsonIndexContent(finalData) { return ` <!DOCTYPE html> <html lang="en" data-theme="light"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>视频列表</title> <style> body { font-family: Arial, sans-serif; display: flex; flex-direction: column; align-items: center; padding: 20px; overflow-x: hidden; } .video-row { display: flex; flex-wrap: wrap; justify-content: space-between; width: 100%; max-width: 1200px; margin-bottom: 20px; } .notification { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(0, 0, 0, 0.7); color: white; padding: 10px; z-index: 1000; } .video { width: 48%; position: relative; max-width: 48%; position: relative; cursor: pointer; display: flex; flex-direction: column; align-items: center; margin-bottom: 20px; } .network-label { position: absolute; bottom: 4px; right: 4px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 2px 4px; font-size: 10px; } .video img { width: 100%; height: auto; } .video video { width: 100%; height: auto; } .video-title { margin: 10px 0; font-weight: bold; text-align: center; } .video-mark { color: gray; text-align: center; } @media (min-width: 768px) { .video { width: 23.5%; max-width: 23.5%; } } .sidebar { position: fixed; right: -300px; top: 0; width: 300px; height: 100%; background-color: #f1f1f1; box-shadow: -2px 0 5px rgba(0,0,0,0.5); transition: right 0.3s; display: flex; flex-direction: column; padding: 20px; } .sidebar.open { right: 0; } .sidebar-button { position: fixed; right: -70px; /* 贴边隐藏按钮,此处可以调整隐藏时的偏移量 */ top: 95%; /* 垂直居中 */ transform: translateY(-50%); /* 将按钮垂直居中 */ background-color: #4CAF50; color: white; border: none; padding: 10px 15px; cursor: pointer; z-index: 1000; transition: right 0.3s ease; /* 添加过渡效果 */ } .sidebar-button:hover, .sidebar-button:focus { right: 20px; /* 悬停或者焦点时,展示完整按钮 */ } .sidebar-content button { background-color: #4CAF50; color: white; border: none; padding: 10px; margin: 10px 0; cursor: pointer; } .modal { display: none; position: fixed; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4); } .modal-content.dark-mode { background-color: var(--background-dark); color: var(--text-dark); border-color: var(--border-dark); } .modal-content { background-color: var(--background-light); margin: 15% auto; padding: 20px; border: 1px solid #888; width: 80%; max-width: 600px; border-radius: 8px; color: var(--text-light); } .modal-close { color: #aaa; float: right; font-size: 28px; font-weight: bold; } .detail-button { background-color: var(--button-background-light); /* 按钮背景颜色 */ color: var(--button-text-light); /* 文字颜色 */ border: none; /* 去掉边框 */ padding: 10px 20px; /* 按钮内边距 */ cursor: pointer; /* 光标样式 */ outline: none; /* 去掉点击时的边框 */ border-radius: 4px; /* 圆角 */ transition: background-color 0.3s ease, color 0.3s ease; /* 过渡效果 */ } [data-theme="dark"] .detail-button { background-color: var(--button-background-dark); /* 按钮背景颜色 */ color: var(--button-text-dark); /* 文字颜色 */ } [data-theme="light"] .detail-button { background-color: var(--button-background-light); /* 按钮背景颜色 */ color: var(--button-text-light); /* 文字颜色 */ } .detail-button:hover { background-color: #45a049; /* 鼠标悬停时的背景颜色 */ } .detail-button:focus { background-color: #388e3c; /* 获得焦点时的背景颜色 */ } :root { --background-light: #ffffff; --background-dark: #000000; --text-light: #000000; --text-dark: #ffffff; --border-light: #cccccc; --border-dark: #333333; --modal-background-light: #fefefe; --modal-background-dark: #1c1c1c; /* 更深的黑色背景 */ --button-background-light: #4CAF50; --button-background-dark: #444444; --button-text-light: white; --button-text-dark: white; --message-background-light: #f1f1f1; --message-background-dark: #333333; /* 更深的黑色背景 */ --message-border-light: #ccc; --message-border-dark: #555; /* 边框颜色 */ } [data-theme="light"] { background-color: var(--background-light); color: var(--text-light); } [data-theme="dark"] { background-color: var(--background-dark); color: var(--text-dark); } [data-theme="light"] .sun { display: none; } [data-theme="dark"] .moon { display: none; } [data-theme="light"] input, [data-theme="light"] button { background-color: #ffffff; border: 1px solid var(--border-light); color: var(--text-light); } [data-theme="dark"] .modal-content { background-color: var(--modal-background-dark); color: var(--text-dark); border-color: var(--border-dark); } .message { text-align: center; padding: 10px; margin-top: 20px; background-color: var(--message-background-light); border: 1px solid var(--message-border-light); transition: background-color 0.3s, border-color 0.3s, color 0.3s; } [data-theme="dark"] .message { background-color: var(--message-background-dark); border-color: var(--message-border-dark); color: var(--text-dark); } [data-theme="dark"] input, [data-theme="dark"] button { background-color: #333333; border: 1px solid var(--border-dark); color: var(--text-dark); } .toggle { display: inline-flex; justify-content: center; align-items: center; width: 32px; height: 32px; border-radius: 4px; background-color: #fff; border: 1px solid #e2e8f0; cursor: pointer; position: fixed; top: 10px; right: 10px; } </style> </head> <body> <button class="toggle"> <svg class="sun" stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg> <svg class="moon" stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg> </button> <button class="sidebar-button" onclick="openModal()">备份信息</button> <div id="video-container"></div> <!-- 通知窗口 --> <div class="notification" id="notification"></div> <!-- 模态框 --> <div id="myModal" class="modal"> <div class="modal-content"> <span class="modal-close" onclick="closeMyModal()">×</span> <button type="button" onclick="exportJson()">导出Json</button> <br><br> <h2>备份信息</h2> <p>备份数量: <span id="videoCount"></span></p> <p>备份时间: <span id="cstTime"></span></p> <p>备份地址: <a id="backupLink" href="#" target="_blank">访问</a></p> <p>联系作者: <a href="mailto:[email protected]" target="_blank">人民的勤务员</a></p> </form> </div> </div> <script> document.addEventListener('DOMContentLoaded', (event) => { function loadHighlightStyle() { const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; if (isDarkMode) { toggleDarkMode2('dark'); } else { toggleDarkMode2('light'); } } const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); mediaQuery.addEventListener('change', loadHighlightStyle); // Initial check loadHighlightStyle(); }); function toggleDarkMode2(mode) { const html = document.documentElement; const isDarkMode = html.getAttribute('data-theme') === 'dark'; const newMode = mode || (isDarkMode ? 'light' : 'dark'); // 验证新模式是否为有效值 if (newMode !== 'dark' && newMode !== 'light') return; // 设置新的主题模式 html.setAttribute('data-theme', newMode); // 更新URL中的主题参数,不重新加载页面 const url = new URL(window.location); url.searchParams.set('theme', newMode); window.history.replaceState({}, '', url); } document.querySelector('.toggle').addEventListener('click', () => toggleDarkMode2()); function exportJson() { const dataStr = JSON.stringify(jsonData, null, 4); // 将JSON数据转换为字符串格式,并进行格式化 const blob = new Blob([dataStr], { type: 'application/json' }); // 创建一个Blob对象表示JSON数据 const url = URL.createObjectURL(blob); // 创建一个URL指向Blob对象 const a = document.createElement('a'); // 创建一个<a>元素 a.href = url; // 设置<a>元素的href属性为URL a.download = 'settings.json'; // 设置下载文件的名称 a.click(); // 触发<a>元素的点击事件,从而下载文件 // 释放URL对象 URL.revokeObjectURL(url); } function openModal() { const modal = document.getElementById('myModal'); modal.style.display = 'block'; // 设置视频数量 document.getElementById('videoCount').innerText = videoData.length; // 设置备份时间(将 UTC 时间转为##时间) const timestamp = new Date(jsonData.info.timestamp); const cstTime = timestamp.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }); cocstTime = document.getElementById('cstTime'); cocstTime.textContent = cstTime const backupUrl = jsonData.info.inurl; const backupLink = document.getElementById('backupLink'); backupLink.href = backupUrl; } function closeMyModal() { const modal = document.getElementById('myModal'); modal.style.display = 'none'; } const jsonData = ${JSON.stringify(finalData, null, 4)}; const videoData = jsonData.video; let currentPage = 0; const pageSizeMobile = 12; const pageSizePC = 12; const pageSize = isPC() ? pageSizePC : pageSizeMobile; let isLoadingVideos = false; let allVideosLoaded = false; let firstLoad = true; function isPC() { return window.innerWidth >= 768; } const originalImages = new Map(); const maxVideosOnMobile = 12; // 设置移动设备上同时播放的视频最大数量 let currentVideosOnMobile = 0; function isMobileDevice() { return /Mobi|Android/i.test(navigator.userAgent); } function playVideo(element) { const imgElement = element.querySelector('img'); const videoUrl = imgElement.getAttribute('data-video'); // 保存原始图片元素 if (!originalImages.has(element)) { originalImages.set(element, imgElement.cloneNode(true)); } const videoElement = document.createElement('video'); videoElement.controls = false; videoElement.autoplay = true; videoElement.loop = true; videoElement.style.width = '100%'; videoElement.style.height = imgElement.clientHeight + 'px'; videoElement.innerHTML = "<source src='" + videoUrl + "' type='video/mp4'>"; if (isMobileDevice()) { // 检查是否达到最大视频数量限制 if (currentVideosOnMobile >= maxVideosOnMobile) { // 停止并恢复其他视频为图片 const videos = document.querySelectorAll('video'); videos.forEach(video => { video.pause(); video.src = ''; video.load(); const parentElement = video.parentElement; if (originalImages.has(parentElement)) { video.replaceWith(originalImages.get(parentElement).cloneNode(true)); currentVideosOnMobile--; // 减少当前播放视频计数 } }); } currentVideosOnMobile++; // 增加当前播放视频计数 } // 替换图片元素 imgElement.replaceWith(videoElement); } function createVideoElement(video) { const videoDiv = document.createElement('div'); videoDiv.classList.add('video'); videoDiv.setAttribute('onclick', 'playVideo(this)'); // 创建图片元素 const imgElement = new Image(); imgElement.alt = video.altText; imgElement.dataset.video = video.videoUrl; // 设置本地图片路径 imgElement.src = "img/" + video.fileName + ".jpg"; const netLabel = document.createElement('div'); netLabel.classList.add('network-label'); netLabel.textContent = 'L'; netLabel.style.backgroundColor = '#00FF00'; videoDiv.appendChild(netLabel); // 检查图片是否加载成功 imgElement.addEventListener('error', function() { // 图片加载失败时,切换到网络图片 imgElement.src = video.imgUrl; // 添加网络图片标识 netLabel.style.backgroundColor = '#f44336'; netLabel.textContent = 'N'; videoDiv.appendChild(netLabel); }); videoDiv.appendChild(imgElement); // 创建标题元素 const titleElement = document.createElement('a'); titleElement.classList.add('video-title'); const MAX_TITLE_LENGTH = 20; // 最大标题长度 // 拼接标题文本 let titleText = video.fileName + " - " + video.altText; // 如果标题文本长度超过最大长度,则截取前面的部分 if (titleText.length > MAX_TITLE_LENGTH) { titleText = titleText.substring(0, MAX_TITLE_LENGTH) + '...'; } titleElement.textContent =titleText titleElement.href = video.jumpUrl; titleElement.target = '_blank'; // 打开新标签页 titleElement.style.textDecoration = 'none'; // 移除下划线 videoDiv.appendChild(titleElement); // 创建标记内容元素 if (video.info) { const detailButton = document.createElement('button'); detailButton.textContent = '查看详细'; detailButton.classList.add('detail-button'); detailButton.onclick = function(event) { event.stopPropagation(); // 阻止事件冒泡,防止触发视频播放 const videoElements = document.querySelectorAll('.video'); const index = Array.prototype.indexOf.call(videoElements, videoDiv); const videoInfo = jsonData.video[index].info; openVideoModal(videoInfo); }; // 将查看详细按钮放在视频条目底部 const detailButtonContainer = document.createElement('div'); detailButtonContainer.classList.add('detail-button-container'); detailButtonContainer.appendChild(detailButton); videoDiv.appendChild(detailButtonContainer); } // 创建左上角的文本 const firstLineElement = document.createElement('div'); firstLineElement.classList.add('mark-first-line'); firstLineElement.textContent = video.markContent; videoDiv.appendChild(firstLineElement); // 设置样式 firstLineElement.style.position = 'absolute'; firstLineElement.style.top = '5px'; firstLineElement.style.left = '5px'; firstLineElement.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; firstLineElement.style.color = '#fff'; firstLineElement.style.padding = '5px'; firstLineElement.style.fontSize = '10px'; return videoDiv; } function openVideoModal(info) { const modal = document.createElement('div'); modal.id = 'videoModal'; modal.style.display = 'none'; // 默认隐藏 modal.style.position = 'fixed'; modal.style.zIndex = '1000'; modal.style.left = '0'; modal.style.top = '0'; modal.style.width = '100%'; modal.style.height = '100%'; modal.style.overflow = 'auto'; modal.style.backgroundColor = 'rgba(0, 0, 0, 0.4)'; // 半透明黑色背景 const modalContent = document.createElement('div'); modalContent.classList.add('modal-content-video'); modalContent.style.backgroundColor = '#fefefe'; // 白色背景 modalContent.style.margin = '5% auto'; // 上部5%间距,左右居中 modalContent.style.padding = '20px'; modalContent.style.border = '1px solid #888'; // 灰色边框 modalContent.style.width = '80%'; modalContent.style.position = 'relative'; // 相对定位,用于绝对定位关闭按钮 const closeButton = document.createElement('span'); closeButton.textContent = '×'; // 使用红色 X 号 closeButton.style.position = 'absolute'; closeButton.style.top = '10px'; closeButton.style.right = '10px'; closeButton.style.fontSize = '50px'; closeButton.style.cursor = 'pointer'; closeButton.style.color = 'red'; // 默认红色关闭按钮 closeButton.style.fontWeight = 'bold'; closeButton.onclick = function() { modal.style.display = 'none'; // 点击关闭按钮关闭模态框 }; modalContent.appendChild(closeButton); // 创建标题 const title = document.createElement('h2'); title.textContent = '详细信息'; title.style.textAlign = 'center'; modalContent.appendChild(title); // 解析视频信息对象 const videosInfo = info.videosinfo; // 创建信息列表 const infoList = document.createElement('ul'); infoList.style.listStyleType = 'none'; infoList.style.padding = '0'; infoList.style.display = 'flex'; // 使用 flex 布局 infoList.style.flexWrap = 'wrap'; // 允许内容换行 // 遍历视频信息对象,创建列表项 for (const key in videosInfo) { const listItem = document.createElement('li'); listItem.style.marginBottom = '10px'; listItem.style.flex = '1 1 30%'; // 设置每个列表项的宽度,可根据需要调整 const label = document.createElement('strong'); label.textContent = key.replace(/:/, ''); // 去除末尾的冒号 label.style.display = 'block'; listItem.appendChild(label); // 处理值是数组的情况 if (Array.isArray(videosInfo[key])) { const values = videosInfo[key]; const valueList = document.createElement('ul'); valueList.style.listStyleType = 'none'; valueList.style.padding = '0'; valueList.style.marginTop = '5px'; values.forEach(value => { const valueItem = document.createElement('li'); valueItem.style.marginBottom = '3px'; if (typeof value === 'object' && value.name) { const link = document.createElement('a'); link.textContent = value.name; link.href = value.link; link.target = '_blank'; link.style.color = '#0645AD'; // 蓝色链接色 link.style.textDecoration = 'none'; link.style.fontWeight = 'bold'; valueItem.appendChild(link); } else { valueItem.textContent = value; } valueList.appendChild(valueItem); }); listItem.appendChild(valueList); } else { listItem.textContent += ' ' + videosInfo[key]; } infoList.appendChild(listItem); } // 将信息列表添加到模态框内容 modalContent.appendChild(infoList); // 创建下载链接列表 if (info.secondElementLinksInfo && info.secondElementLinksInfo.length > 0) { const downloadList = document.createElement('ul'); downloadList.style.listStyleType = 'none'; downloadList.style.padding = '0'; downloadList.style.marginTop = '20px'; // 添加磁力链下载标题 const titleListItem = document.createElement('li'); const titleStrong = document.createElement('strong'); titleStrong.textContent = '磁力链下载:'; titleListItem.appendChild(titleStrong); downloadList.appendChild(titleListItem); // 遍历下载链接信息对象,创建列表项 info.secondElementLinksInfo.forEach((linkInfo, index) => { const listItem = document.createElement('li'); listItem.style.marginBottom = '10px'; const linkLabel = document.createElement('span'); linkLabel.textContent = (index + 1) + '. '; // 使用字符串拼接 linkLabel.style.fontWeight = 'bold'; linkLabel.style.marginRight = '5px'; listItem.appendChild(linkLabel); const link = document.createElement('a'); link.textContent = linkInfo.name + ' (' + linkInfo.size + ', ' + linkInfo.date + ')'; link.href = linkInfo.link; link.target = '_blank'; link.style.color = '#0645AD'; // 蓝色链接色 link.style.textDecoration = 'none'; link.style.fontWeight = 'bold'; listItem.appendChild(link); downloadList.appendChild(listItem); }); // 将下载链接列表添加到模态框内容的底部 modalContent.appendChild(downloadList); } // 将模态框内容添加到模态框 modal.appendChild(modalContent); // 将模态框添加到页面主体 document.body.appendChild(modal); // 根据当前主题设置模态框样式(这部分是您之前提供的代码,不需要修改) const currentTheme = document.documentElement.getAttribute('data-theme'); if (currentTheme === 'dark') { modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; // 深色背景 modalContent.style.backgroundColor = '#1c1c1c'; // 深色内容背景 modalContent.style.border = '1px solid #555'; // 深色边框 closeButton.style.color = '#ff6347'; // 深色关闭按钮 } // 显示模态框 modal.style.display = 'block'; } // 关闭模态框 function closevideoModal() { const modal = document.getElementById('videoModal'); modal.style.display = 'none'; } function showNoMoreVideosMessage() { const messageDiv = document.createElement('div'); messageDiv.textContent = '没有更多视频了'; messageDiv.className = 'message'; document.body.appendChild(messageDiv); // 设置定时器清除消息(可选) setTimeout(() => { document.body.removeChild(messageDiv); }, 3000); // 3秒后自动隐藏消息 } function loadVideos() { isLoadingVideos = true; const container = document.getElementById('video-container'); const pageSize = isPC() ? pageSizePC : pageSizeMobile; const start = currentPage * pageSize; const end = start + pageSize; const videosToLoad = videoData.slice(start, end); const newVideoRow = document.createElement('div'); newVideoRow.classList.add('video-row'); videosToLoad.forEach(video => { const videoDiv = createVideoElement(video); newVideoRow.appendChild(videoDiv); }); container.appendChild(newVideoRow); currentPage++; isLoadingVideos = false; if (firstLoad) { firstLoad=false; return; }; updateNotification(); // 更新通知窗口内容 } function updateNotification() { const totalVideos = videoData.length; const loadedVideos = currentPage * (isPC() ? pageSizePC : pageSizeMobile); const notificationElement = document.getElementById('notification'); notificationElement.innerText = "已加载 " + loadedVideos + " 个视频,共 " + totalVideos + " 个视频。"; notificationElement.style.display = 'block'; setTimeout(() => { notificationElement.style.display = 'none'; }, 1000); // 3秒后隐藏通知窗口 } function handleScroll() { // 如果正在加载视频或者已经加载所有视频,则返回 console.log('Window height:', window.innerHeight); console.log('Scroll Y:', window.scrollY); console.log('Body offset height:', document.body.offsetHeight); if (allVideosLoaded) { return; } // 检查是否滚动到页面底部 if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { if (currentPage * pageSize >= videoData.length) { console.log('已加载所有视频'); allVideosLoaded = true; // 显示提示信息 showNoMoreVideosMessage(); } else { loadVideos(); } } } function toggleSidebar() { const sidebar = document.getElementById('sidebar'); sidebar.classList.toggle('open'); } window.addEventListener('scroll', function() { handleScroll(isPC() ? pageSizePC : pageSizeMobile); }); window.addEventListener('DOMContentLoaded', loadVideos); </script> </body> </html> `; }