在 HDSky 论坛页面右上角显示控制面板,自动高亮特殊关注用户的回复内容,支持快速翻页和收藏功能,可折叠面板,下拉加载翻页
当前为
// ==UserScript==
// @name HDSky 体育沙龙面板
// @namespace http://tampermonkey.net/
// @version 3.1
// @description 在 HDSky 论坛页面右上角显示控制面板,自动高亮特殊关注用户的回复内容,支持快速翻页和收藏功能,可折叠面板,下拉加载翻页
// @author 江畔
// @match https://hdsky.me/*
// @match https://www.hdsky.me/*
// @icon https://hdsky.me/favicon.ico
// @grant GM_setValue
// @grant GM_getValue
// @charset UTF-8
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 配置管理
const Config = {
// 获取配置
get(key, defaultValue) {
return GM_getValue(key, defaultValue);
},
// 设置配置
set(key, value) {
GM_setValue(key, value);
},
// 获取下拉加载开关状态
getAutoLoadEnabled() {
return this.get('autoLoadEnabled', false);
},
// 设置下拉加载开关状态
setAutoLoadEnabled(enabled) {
this.set('autoLoadEnabled', enabled);
},
// 获取面板展开状态
getPanelExpanded() {
return this.get('panelExpanded', true); // 默认展开
},
// 设置面板展开状态
setPanelExpanded(expanded) {
this.set('panelExpanded', expanded);
}
};
// 从存储中获取特殊关注名单
function getSpecialFollowList() {
const listStr = Config.get('specialFollowList', '');
if (!listStr) return [];
return listStr.split(',').map(name => name.trim()).filter(name => name);
}
// 保存特殊关注名单到存储
function saveSpecialFollowList(list) {
Config.set('specialFollowList', list.join(','));
}
// 从存储中获取收藏列表
function getBookmarkList() {
const listStr = Config.get('bookmarkList', '[]');
try {
return JSON.parse(listStr);
} catch (e) {
return [];
}
}
// 保存收藏列表到存储
function saveBookmarkList(list) {
Config.set('bookmarkList', JSON.stringify(list));
}
// 创建控制面板
function createControlPanel() {
// 创建容器,包含面板和折叠按钮
const container = document.createElement('div');
container.id = 'hdsky-panel-container';
container.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
display: flex;
align-items: flex-start;
z-index: 10000;
`;
// 创建折叠按钮
const toggleBtn = document.createElement('button');
toggleBtn.id = 'panel-toggle-btn';
toggleBtn.innerHTML = '◀';
toggleBtn.title = '收起面板';
toggleBtn.style.cssText = `
background: #e0e0e0;
color: #666;
border: none;
border-radius: 4px 0 0 4px;
width: 24px;
height: 40px;
cursor: pointer;
font-size: 14px;
transition: background 0.3s;
margin-right: -2px;
z-index: 1;
`;
toggleBtn.onmouseover = () => toggleBtn.style.background = '#d0d0d0';
toggleBtn.onmouseout = () => toggleBtn.style.background = '#e0e0e0';
toggleBtn.onclick = togglePanel;
const panel = document.createElement('div');
panel.id = 'hdsky-special-follow-panel';
panel.style.cssText = `
background: #fff;
border: 1px solid #ddd;
border-radius: 8px;
padding: 15px;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
width: 220px;
font-family: Arial, sans-serif;
transition: all 0.3s ease;
`;
// 面板标题
const title = document.createElement('div');
title.textContent = '体育沙龙面板';
title.style.cssText = `
font-size: 16px;
font-weight: bold;
margin-bottom: 12px;
color: #333;
text-align: center;
border-bottom: 1px solid #ddd;
padding-bottom: 8px;
`;
panel.appendChild(title);
// 关注列表按钮
const followListBtn = document.createElement('button');
followListBtn.id = 'follow-list-btn';
followListBtn.textContent = '关注列表';
followListBtn.style.cssText = `
padding: 10px 15px;
background: #2196F3;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
transition: background 0.3s;
width: 100%;
margin-bottom: 10px;
`;
followListBtn.title = '点击编辑特殊关注名单';
followListBtn.onmouseover = () => followListBtn.style.background = '#0b7dda';
followListBtn.onmouseout = () => followListBtn.style.background = '#2196F3';
followListBtn.onclick = handleFollowListClick;
panel.appendChild(followListBtn);
// 按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 8px;
`;
// 下拉加载翻页按钮
const autoLoadBtn = document.createElement('button');
autoLoadBtn.id = 'auto-load-btn';
autoLoadBtn.style.cssText = `
padding: 10px 15px;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
transition: background 0.3s;
width: 100%;
margin-bottom: 10px;
`;
autoLoadBtn.onclick = toggleAutoLoadFromPanel;
updateAutoLoadButton(autoLoadBtn); // 在设置基础样式后再更新按钮状态
buttonContainer.appendChild(autoLoadBtn);
// 收藏功能按钮容器
const bookmarkContainer = document.createElement('div');
bookmarkContainer.id = 'bookmark-container';
bookmarkContainer.style.cssText = `
display: flex;
flex-direction: row;
gap: 8px;
`;
// 收藏按钮
const bookmarkBtn = document.createElement('button');
bookmarkBtn.textContent = '收藏';
bookmarkBtn.id = 'bookmark-btn';
bookmarkBtn.style.cssText = `
padding: 8px 12px;
background: #2196F3;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 13px;
font-weight: bold;
transition: background 0.3s;
flex: 1;
`;
bookmarkBtn.onmouseover = () => bookmarkBtn.style.background = '#0b7dda';
bookmarkBtn.onmouseout = () => bookmarkBtn.style.background = '#2196F3';
bookmarkBtn.onclick = addBookmark;
bookmarkContainer.appendChild(bookmarkBtn);
// 收藏夹按钮
const bookmarkListBtn = document.createElement('button');
bookmarkListBtn.textContent = '收藏夹';
bookmarkListBtn.id = 'bookmark-list-btn';
bookmarkListBtn.style.cssText = `
padding: 8px 12px;
background: #2196F3;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 13px;
font-weight: bold;
transition: background 0.3s;
flex: 1;
`;
bookmarkListBtn.onmouseover = () => bookmarkListBtn.style.background = '#0b7dda';
bookmarkListBtn.onmouseout = () => bookmarkListBtn.style.background = '#2196F3';
bookmarkListBtn.onclick = showBookmarkList;
bookmarkContainer.appendChild(bookmarkListBtn);
buttonContainer.appendChild(bookmarkContainer);
panel.appendChild(buttonContainer);
// 将按钮和面板添加到容器
container.appendChild(toggleBtn);
container.appendChild(panel);
// 添加到页面
document.body.appendChild(container);
// 应用保存的面板状态
const isPanelExpanded = Config.getPanelExpanded();
if (!isPanelExpanded) {
// 如果保存的是收起状态,则收起面板
panel.style.display = 'none';
toggleBtn.innerHTML = '▶';
toggleBtn.title = '展开面板';
toggleBtn.style.borderRadius = '4px';
}
}
// 切换面板显示/隐藏
function togglePanel() {
const panel = document.getElementById('hdsky-special-follow-panel');
const toggleBtn = document.getElementById('panel-toggle-btn');
if (panel.style.display === 'none') {
// 展开面板
panel.style.display = 'block';
toggleBtn.innerHTML = '◀';
toggleBtn.title = '收起面板';
toggleBtn.style.borderRadius = '4px 0 0 4px';
Config.setPanelExpanded(true); // 保存展开状态
} else {
// 收起面板
panel.style.display = 'none';
toggleBtn.innerHTML = '▶';
toggleBtn.title = '展开面板';
toggleBtn.style.borderRadius = '4px';
Config.setPanelExpanded(false); // 保存收起状态
}
}
// 更新下拉加载按钮的显示
function updateAutoLoadButton(button) {
const isEnabled = Config.getAutoLoadEnabled();
button.style.background = '#2196F3'; // 统一使用蓝色
button.onmouseover = () => button.style.background = '#0b7dda';
button.onmouseout = () => button.style.background = '#2196F3';
if (isEnabled) {
button.textContent = '✅ 下拉加载翻页';
button.title = '点击关闭下拉加载翻页功能';
} else {
button.textContent = '❌ 下拉加载翻页';
button.title = '点击开启下拉加载翻页功能';
}
}
// 从面板切换下拉加载功能
function toggleAutoLoadFromPanel() {
const currentState = Config.getAutoLoadEnabled();
const newState = !currentState;
Config.setAutoLoadEnabled(newState);
// 更新按钮显示
const button = document.getElementById('auto-load-btn');
if (button) {
updateAutoLoadButton(button);
}
// 如果是开启,立即初始化功能
if (newState) {
autoLoadNextPage();
} else {
// 如果是关闭,需要刷新页面以移除事件监听器
if (confirm('需要刷新页面以完全关闭下拉加载功能,是否立即刷新?')) {
location.reload();
}
}
}
// 全局变量:高亮帖子列表
let highlightedPosts = [];
// 添加收藏
function addBookmark() {
const currentUrl = window.location.href;
let currentTitle = document.title || '未命名页面';
// 从标题中提取引号里的内容
const match = currentTitle.match(/"([^"]+)"/);
if (match && match[1]) {
currentTitle = match[1];
} else {
// 如果没有引号,则删掉常见的前后缀
currentTitle = currentTitle.replace(/^HDSky :: 查看主题\s+/i, '');
currentTitle = currentTitle.replace(/^HDSky :: /i, '');
currentTitle = currentTitle.replace(/\s*高清视界.*$/i, '');
currentTitle = currentTitle.replace(/\s*-\s*Powered by.*$/i, '');
}
// 获取现有收藏列表
const bookmarks = getBookmarkList();
// 检查是否已经收藏
const exists = bookmarks.some(b => b.url === currentUrl);
if (exists) {
alert('该页面已经在收藏夹中了!');
return;
}
// 添加新收藏
bookmarks.push({
url: currentUrl,
title: currentTitle,
time: new Date().toLocaleString()
});
// 保存
saveBookmarkList(bookmarks);
alert('收藏成功!\n标题:' + currentTitle);
}
// 显示收藏夹
function showBookmarkList() {
const bookmarks = getBookmarkList();
// 移除旧的收藏夹窗口(如果存在)
const oldDialog = document.getElementById('bookmark-dialog');
if (oldDialog) {
oldDialog.remove();
}
// 创建遮罩层
const overlay = document.createElement('div');
overlay.id = 'bookmark-dialog';
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 10003;
display: flex;
justify-content: center;
align-items: center;
`;
// 创建弹窗
const dialog = document.createElement('div');
dialog.style.cssText = `
background: white;
border-radius: 10px;
padding: 20px;
width: 600px;
max-height: 70vh;
overflow-y: auto;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
`;
// 标题栏
const header = document.createElement('div');
header.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid #2196F3;
background: transparent;
`;
const title = document.createElement('h2');
title.textContent = '我的收藏夹';
title.style.cssText = `
margin: 0;
padding: 0;
color: #2196F3;
font-size: 20px;
background: transparent;
border: none;
outline: none;
`;
header.appendChild(title);
const closeBtn = document.createElement('button');
closeBtn.textContent = '✕';
closeBtn.style.cssText = `
background: #f44336;
color: white;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 18px;
font-weight: bold;
transition: background 0.3s;
`;
closeBtn.onmouseover = () => closeBtn.style.background = '#d32f2f';
closeBtn.onmouseout = () => closeBtn.style.background = '#f44336';
closeBtn.onclick = () => overlay.remove();
header.appendChild(closeBtn);
dialog.appendChild(header);
// 收藏列表
if (bookmarks.length === 0) {
const emptyMsg = document.createElement('div');
emptyMsg.textContent = '收藏夹还是空的,快去收藏喜欢的页面吧!';
emptyMsg.style.cssText = `
text-align: center;
color: #999;
padding: 40px 20px;
font-size: 14px;
background: #f9f9f9;
border-radius: 5px;
margin-top: 10px;
`;
dialog.appendChild(emptyMsg);
} else {
bookmarks.forEach((bookmark, index) => {
const item = createBookmarkItem(bookmark, index);
dialog.appendChild(item);
});
}
overlay.appendChild(dialog);
document.body.appendChild(overlay);
// 点击遮罩层关闭
overlay.onclick = (e) => {
if (e.target === overlay) {
overlay.remove();
}
};
}
// 创建收藏项
function createBookmarkItem(bookmark, index) {
const item = document.createElement('div');
item.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
margin-bottom: 10px;
background: #fafafa;
border: 1px solid #e0e0e0;
border-radius: 5px;
transition: all 0.3s;
`;
item.onmouseover = () => {
item.style.background = '#e3f2fd';
item.style.borderColor = '#2196F3';
item.style.transform = 'translateX(5px)';
item.style.boxShadow = '0 2px 8px rgba(33, 150, 243, 0.2)';
};
item.onmouseout = () => {
item.style.background = '#fafafa';
item.style.borderColor = '#e0e0e0';
item.style.transform = 'translateX(0)';
item.style.boxShadow = 'none';
};
// 左侧内容区
const content = document.createElement('div');
content.style.cssText = `
flex: 1;
cursor: pointer;
overflow: hidden;
`;
content.onclick = () => window.location.href = bookmark.url;
const titleDiv = document.createElement('div');
titleDiv.textContent = bookmark.title;
titleDiv.style.cssText = `
font-size: 14px;
font-weight: bold;
color: #2196F3;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
content.appendChild(titleDiv);
const timeDiv = document.createElement('div');
timeDiv.textContent = '收藏时间: ' + bookmark.time;
timeDiv.style.cssText = `
font-size: 12px;
color: #999;
`;
content.appendChild(timeDiv);
item.appendChild(content);
// 删除按钮
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '✕';
deleteBtn.style.cssText = `
background: #ff5722;
color: white;
border: none;
border-radius: 50%;
width: 25px;
height: 25px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
transition: background 0.3s;
margin-left: 10px;
`;
deleteBtn.onmouseover = () => deleteBtn.style.background = '#e64a19';
deleteBtn.onmouseout = () => deleteBtn.style.background = '#ff5722';
deleteBtn.onclick = (e) => {
e.stopPropagation();
if (confirm('确定要删除这个收藏吗?\n' + bookmark.title)) {
deleteBookmark(index);
showBookmarkList(); // 刷新列表
}
};
item.appendChild(deleteBtn);
return item;
}
// 删除收藏
function deleteBookmark(index) {
const bookmarks = getBookmarkList();
bookmarks.splice(index, 1);
saveBookmarkList(bookmarks);
}
// 处理关注列表点击(编辑)
function handleFollowListClick() {
const currentList = getSpecialFollowList();
const currentStr = currentList.join(',');
const input = prompt('请输入特殊关注名单(用逗号分隔):\n例如: DFBCOLD19,李知恩', currentStr);
if (input !== null) { // 用户点击了确定(包括空字符串)
const newList = input.split(',').map(name => name.trim()).filter(name => name);
saveSpecialFollowList(newList);
alert('特殊关注名单已更新!\n当前关注: ' + (newList.length > 0 ? newList.join(', ') : '无'));
// 重新应用高亮
autoHighlightFollowedPosts();
}
}
// 自动高亮特殊关注用户的帖子(页面加载时调用)
function autoHighlightFollowedPosts() {
const followList = getSpecialFollowList();
// 如果没有关注名单,不执行高亮
if (followList.length === 0) {
return;
}
// 先清除之前的高亮
clearHighlights();
// 找到所有回复帖子(每个帖子在一个带有 margin-top 和 margin-bottom 的 div 中)
const allPosts = document.querySelectorAll('div[style*="margin-top: 8pt"]');
// 重置高亮列表
highlightedPosts = [];
allPosts.forEach(post => {
// 在帖子中查找用户名链接
const userLinks = post.querySelectorAll('a[href*="userdetails.php"]');
let isFollowedUser = false;
userLinks.forEach(link => {
const username = link.textContent.trim();
// 检查是否在关注列表中
if (followList.some(followName => username === followName)) {
isFollowedUser = true;
}
});
if (isFollowedUser) {
// 高亮显示关注用户的信息div
post.style.background = '#fffacd';
post.style.border = '2px solid #ffd700';
post.style.borderRadius = '5px';
post.style.padding = '5px';
// 找到并高亮div内部的table
const innerTables = post.querySelectorAll('table');
innerTables.forEach(table => {
table.style.background = '#fff8dc';
table.style.border = '2px solid #ffb700';
});
// 标记为已高亮
post.dataset.highlighted = 'true';
// 找到并高亮紧跟在div后面的回复内容table(class="main")
let nextElement = post.nextElementSibling;
if (nextElement && nextElement.tagName === 'TABLE' && nextElement.classList.contains('main')) {
nextElement.style.background = '#fff8dc';
nextElement.style.border = '2px solid #ffb700';
nextElement.style.borderRadius = '5px';
// 标记这个table也被高亮了
nextElement.dataset.highlightedContent = 'true';
}
// 添加到高亮列表
highlightedPosts.push(post);
}
});
}
// 清除所有高亮
function clearHighlights() {
// 找到所有被高亮的帖子div
const posts = document.querySelectorAll('div[data-highlighted="true"]');
posts.forEach(post => {
// 清除div的高亮样式
post.style.background = '';
post.style.border = '';
post.style.borderRadius = '';
post.style.padding = '';
post.removeAttribute('data-highlighted');
// 清除div内部table的高亮样式
const tables = post.querySelectorAll('table');
tables.forEach(table => {
table.style.background = '';
table.style.border = '';
});
});
// 清除所有被高亮的回复内容table
const contentTables = document.querySelectorAll('table[data-highlighted-content="true"]');
contentTables.forEach(table => {
table.style.background = '';
table.style.border = '';
table.style.borderRadius = '';
table.removeAttribute('data-highlighted-content');
});
// 重置全局变量
highlightedPosts = [];
}
// 自动加载下一页功能
let isLoadingNextPage = false;
const scrollThreshold = 800; // 距离底部多少像素时触发加载
function autoLoadNextPage() {
if (!Config.getAutoLoadEnabled()) {
return;
}
// 检查URL中是否包含topicid参数
const urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has('topicid')) {
return;
}
let lastScrollTop = 0;
window.addEventListener('scroll', function() {
const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
const clientHeight = document.documentElement.clientHeight || window.innerHeight;
// 只在向下滚动时触发
if (scrollTop > lastScrollTop) {
// 判断是否接近底部
if (scrollHeight <= clientHeight + scrollTop + scrollThreshold && !isLoadingNextPage) {
// 查找下一页链接
const nextLinks = document.querySelectorAll('a');
let nextPageLink = null;
for (let link of nextLinks) {
const text = link.textContent.trim();
if (text.includes('下一页') || text === '下一页 >>') {
nextPageLink = link;
break;
}
}
if (nextPageLink && nextPageLink.href) {
loadNextPage(nextPageLink.href);
}
}
}
lastScrollTop = scrollTop;
}, false);
}
function loadNextPage(url) {
isLoadingNextPage = true;
// 显示加载提示
const loadingDiv = document.createElement('div');
loadingDiv.id = 'auto-loading-indicator';
loadingDiv.style.cssText = `
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(33, 150, 243, 0.9);
color: white;
padding: 12px 24px;
border-radius: 25px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
z-index: 9999;
font-size: 14px;
font-weight: bold;
`;
loadingDiv.textContent = '正在加载下一页...';
document.body.appendChild(loadingDiv);
// 使用 fetch 加载下一页
fetch(url)
.then(response => response.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// 查找主要内容区域 - 找到所有回复帖子
const newPosts = doc.querySelectorAll('div[style*="margin-top: 8pt"]');
// 找到当前页面的最后一个帖子
const currentPosts = document.querySelectorAll('div[style*="margin-top: 8pt"]');
if (currentPosts.length > 0 && newPosts.length > 0) {
const lastPost = currentPosts[currentPosts.length - 1];
// 找到最后一个帖子的下一个 table(回复内容)
let lastTable = lastPost.nextElementSibling;
while (lastTable && lastTable.tagName !== 'TABLE') {
lastTable = lastTable.nextElementSibling;
}
// 确定插入位置:如果有 table 就在 table 后面,否则在 div 后面
let insertAfter = lastTable || lastPost;
// 将新帖子插入到页面中
newPosts.forEach(post => {
// 克隆 div(用户信息)
const clonedPost = post.cloneNode(true);
insertAfter.parentNode.insertBefore(clonedPost, insertAfter.nextSibling);
insertAfter = clonedPost;
// 查找并克隆紧跟的 table(回复内容)
const nextTable = post.nextElementSibling;
if (nextTable && nextTable.tagName === 'TABLE' && nextTable.classList.contains('main')) {
const clonedTable = nextTable.cloneNode(true);
insertAfter.parentNode.insertBefore(clonedTable, insertAfter.nextSibling);
insertAfter = clonedTable;
}
});
// 更新页码导航(找到所有 <p align="center"> 中包含"上一页"和"下一页"的元素)
const newPagers = doc.querySelectorAll('p[align="center"]');
const currentPagers = document.querySelectorAll('p[align="center"]');
// 遍历并更新所有分页器
let pagerUpdateCount = 0;
for (let i = 0; i < currentPagers.length && i < newPagers.length; i++) {
const currentPager = currentPagers[i];
const newPager = newPagers[i];
// 检查是否包含分页链接(包含"上一页"或"下一页")
if (currentPager.innerHTML.includes('上一页') || currentPager.innerHTML.includes('下一页')) {
currentPager.innerHTML = newPager.innerHTML;
pagerUpdateCount++;
}
}
console.log(`已更新 ${pagerUpdateCount} 个分页导航`);
// 重新应用高亮
autoHighlightFollowedPosts();
loadingDiv.textContent = '✓ 加载完成';
loadingDiv.style.background = 'rgba(76, 175, 80, 0.9)';
setTimeout(() => {
loadingDiv.remove();
}, 2000);
// 更新 URL(不刷新页面)
history.pushState(null, '', url);
} else {
loadingDiv.textContent = '没有更多内容了';
loadingDiv.style.background = 'rgba(255, 152, 0, 0.9)';
setTimeout(() => {
loadingDiv.remove();
}, 2000);
}
isLoadingNextPage = false;
})
.catch(error => {
console.error('加载下一页失败:', error);
loadingDiv.textContent = '✗ 加载失败';
loadingDiv.style.background = 'rgba(244, 67, 54, 0.9)';
setTimeout(() => {
loadingDiv.remove();
}, 2000);
isLoadingNextPage = false;
});
}
// 检查截止时间并禁用快速回复
function checkDeadlineAndDisableReply() {
// 查找标题中的截止时间
const topSpan = document.getElementById('top');
if (!topSpan) return;
const titleText = topSpan.textContent;
// 匹配格式:截止时间:2025-11-13 21:00
const deadlineMatch = titleText.match(/截止时间[::]\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})/);
if (!deadlineMatch) return;
const deadlineStr = deadlineMatch[1];
// 解析截止时间(北京时间)
const deadlineDate = new Date(deadlineStr.replace(' ', 'T') + ':00+08:00');
// 获取当前时间
const now = new Date();
// 如果截止时间已过
if (now > deadlineDate) {
// 查找快速回复表单
const composeForm = document.getElementById('compose');
if (!composeForm) return;
// 查找包含快速回复的 table
const replyTable = composeForm.closest('table');
if (!replyTable) return;
// 禁用所有表单元素
const formElements = composeForm.querySelectorAll('textarea, input[type="submit"], button');
formElements.forEach(element => {
element.disabled = true;
element.style.opacity = '0.5';
element.style.cursor = 'not-allowed';
});
// 在表单顶部添加过期提示
const notice = document.createElement('div');
notice.style.cssText = `
background: #ff5252;
color: white;
padding: 10px 15px;
margin: 10px 0;
border-radius: 5px;
text-align: center;
font-weight: bold;
font-size: 14px;
`;
notice.textContent = '⚠️ 投注截止时间已过,快速回复已禁用';
// 在"快速回复"标题后插入提示
const quickReplyTitle = Array.from(replyTable.querySelectorAll('b')).find(b => b.textContent === '快速回复');
if (quickReplyTitle && quickReplyTitle.parentElement) {
quickReplyTitle.parentElement.appendChild(notice);
}
console.log('截止时间已过,已禁用快速回复面板');
}
}
// 提取收藏夹中所有URL的topicid并打印到控制台
function printBookmarkTopicIds() {
const bookmarks = getBookmarkList();
const topicIds = [];
bookmarks.forEach(bookmark => {
try {
const url = new URL(bookmark.url);
const topicid = url.searchParams.get('topicid');
if (topicid) {
topicIds.push(topicid);
}
} catch (e) {
// 如果URL格式不正确,尝试用正则表达式提取
const match = bookmark.url.match(/topicid=(\d+)/);
if (match && match[1]) {
topicIds.push(match[1]);
}
}
});
if (topicIds.length > 0) {
console.log('收藏夹中的topicid列表:');
console.log(topicIds);
console.log('topicid列表(逗号分隔):' + topicIds.join(','));
} else {
console.log('收藏夹中没有找到包含topicid的URL');
}
return topicIds;
}
// 将函数暴露到全局,方便在控制台中手动调用
window.printBookmarkTopicIds = printBookmarkTopicIds;
// 在embedded左侧添加星星标记收藏的帖子
function highlightTopicIdRows() {
// 只在URL包含viewforum时生效
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('action') !== 'viewforum') {
return;
}
// 获取收藏夹中的topicid列表
const bookmarks = getBookmarkList();
const topicIds = [];
bookmarks.forEach(bookmark => {
try {
const url = new URL(bookmark.url);
const topicid = url.searchParams.get('topicid');
if (topicid) {
topicIds.push(topicid);
}
} catch (e) {
// 如果URL格式不正确,尝试用正则表达式提取
const match = bookmark.url.match(/topicid=(\d+)/);
if (match && match[1]) {
topicIds.push(match[1]);
}
}
});
if (topicIds.length === 0) {
return; // 如果没有收藏的topicid,不执行标记
}
// 查找所有包含topicid链接的embedded元素
const embeddedTds = document.querySelectorAll('td.embedded');
embeddedTds.forEach(td => {
// 查找td中所有包含topicid的链接
const links = td.querySelectorAll('a[href*="topicid"]');
links.forEach(link => {
// 从链接中提取topicid
const href = link.getAttribute('href');
const match = href.match(/topicid[=&](\d+)/);
if (match && match[1]) {
const topicid = match[1];
// 如果这个topicid在收藏列表中,添加星星
if (topicIds.includes(topicid)) {
// 检查是否已经添加过星星
if (!td.querySelector('.bookmark-star')) {
// 创建星星元素
const star = document.createElement('span');
star.className = 'bookmark-star';
star.textContent = '⭐';
star.title = '已收藏';
star.style.cssText = `
margin-right: 5px;
font-size: 14px;
cursor: pointer;
`;
// 在embedded的左侧插入星星(在所有内容之前)
td.insertBefore(star, td.firstChild);
}
}
}
});
});
console.log(`已标记 ${document.querySelectorAll('.bookmark-star').length} 个收藏的帖子`);
}
// 初始化
function init() {
// 等待页面加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
createControlPanel();
autoHighlightFollowedPosts();
autoLoadNextPage();
checkDeadlineAndDisableReply();
printBookmarkTopicIds(); // 打印收藏夹中的topicid列表
highlightTopicIdRows(); // 高亮包含topicid的行
});
} else {
createControlPanel();
autoHighlightFollowedPosts();
autoLoadNextPage();
checkDeadlineAndDisableReply();
printBookmarkTopicIds(); // 打印收藏夹中的topicid列表
highlightTopicIdRows(); // 高亮包含topicid的行
}
}
// 启动脚本
init();
})();