Greasy Fork is available in English.
1. 去掉 disabled-copy 类及水印遮挡;2. 自动点击"展开"按钮保持全文展开;3. 点击时间复制帖子内容;4. 15秒无鼠标活动自动刷新;5. 界面美化和侧边栏控制
当前为
// ==UserScript==
// @name 知识星球吖
// @namespace https://axutongxue.com/
// @version 2.6
// @license MIT
// @description 1. 去掉 disabled-copy 类及水印遮挡;2. 自动点击"展开"按钮保持全文展开;3. 点击时间复制帖子内容;4. 15秒无鼠标活动自动刷新;5. 界面美化和侧边栏控制
// @author kejin——公众号:懒人股选
// @match *://wx.zsxq.com/*
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
/* ************** 样式注入 ************** */
// 添加自定义样式
if (typeof GM_addStyle !== 'undefined') {
GM_addStyle(`
.group-list-container {
transition: transform 0.2s ease-out;
background: #fff;
z-index: 10;
}
#toggle-sidebar {
height: 20px;
font-size: 12px;
margin-left: 10px;
padding: 0px 6px;
border-radius: 4px;
cursor: pointer;
color: rgb(80, 234, 203);
background-color: rgba(52, 146, 112, 0.05);
border: 1px solid rgba(65,183,140,.2);
}
#toggle-sidebar:hover {
background-color: #e0e0e0;
}
`);
} else {
// 如果 GM_addStyle 不可用,使用传统方式
const style = document.createElement('style');
style.textContent = `
.group-list-container {
transition: transform 0.2s ease-out;
background: #fff;
z-index: 10;
}
#toggle-sidebar {
height: 20px;
font-size: 12px;
margin-left: 10px;
padding: 0px 6px;
border-radius: 4px;
cursor: pointer;
color: rgb(80, 234, 203);
background-color: rgba(52, 146, 112, 0.05);
border: 1px solid rgba(65,183,140,.2);
}
#toggle-sidebar:hover {
background-color: #e0e0e0;
}
`;
document.head.appendChild(style);
}
/* ************** 通用工具 ************** */
function waitForKeyElements(selectorOrFunction, callback, waitOnce = true, interval = 300, maxIntervals = -1) {
const select = () => (typeof selectorOrFunction === 'function' ? selectorOrFunction() : document.querySelectorAll(selectorOrFunction));
const tick = () => {
const nodes = select();
if (nodes.length) {
nodes.forEach(n => {
if (n.dataset.alreadyFound) return;
const cancel = callback(n);
if (!cancel) n.dataset.alreadyFound = '1';
});
}
if (--maxIntervals !== 0 && !(waitOnce && nodes.length)) {
setTimeout(tick, interval);
}
};
tick();
}
/* ************** 1. 解除复制限制 ************** */
waitForKeyElements('.disabled-copy', el => el.classList.remove('disabled-copy'), false, 1000);
waitForKeyElements('[watermark]', el => el.setAttribute('style', 'padding:10px;'), false, 1000);
/* ************** 2. 帖子自动展开 ************** */
const processed = new WeakSet();
function smartClick(btn) {
if (!btn || processed.has(btn)) return;
const txt = btn.textContent.trim();
if (!/展[开示]/.test(txt)) return;
btn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
processed.add(btn);
}
function expandAll() {
document.querySelectorAll('p.showAll, button.showAll, span.showAll').forEach(smartClick);
}
// 首次+动态
window.addEventListener('load', () => {
expandAll();
new MutationObserver(() => expandAll()).observe(document.body, { childList: true, subtree: true });
window.addEventListener('hashchange', expandAll);
});
/* ************** 3. 点击时间复制帖子内容 ************** */
const timeClickProcessed = new WeakSet();
function findPostContent(timeElement) {
// 向上查找帖子容器
let container = timeElement.closest('[class*="topic"], [class*="post"], [class*="feed-item"]');
if (!container) {
container = timeElement.closest('div[class*="item"]');
}
if (!container) return null;
// 查找内容区域(尝试多种可能的选择器)
const contentSelectors = [
'.content',
'[class*="content"]',
'.text',
'[class*="text"]',
'.description',
'[class*="description"]'
];
for (const selector of contentSelectors) {
const content = container.querySelector(selector);
if (content && content.textContent.trim()) {
return content.textContent.trim();
}
}
return null;
}
function copyToClipboard(text) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(() => {
showCopyTip('复制成功!');
}).catch(() => {
fallbackCopy(text);
});
} else {
fallbackCopy(text);
}
}
function fallbackCopy(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
showCopyTip('复制成功!');
} catch (err) {
showCopyTip('复制失败,请手动复制');
}
document.body.removeChild(textarea);
}
function showCopyTip(message) {
const tip = document.createElement('div');
tip.textContent = message;
tip.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 12px 24px;
border-radius: 6px;
font-size: 14px;
z-index: 10000;
pointer-events: none;
`;
document.body.appendChild(tip);
setTimeout(() => tip.remove(), 2000);
}
function addTimeClickListener(timeElement) {
if (timeClickProcessed.has(timeElement)) return;
// 添加样式提示可点击
timeElement.style.cursor = 'pointer';
timeElement.title = '点击复制帖子内容';
timeElement.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
const content = findPostContent(timeElement);
if (content) {
copyToClipboard(content);
} else {
showCopyTip('未找到帖子内容');
}
});
timeClickProcessed.add(timeElement);
}
// 监听时间元素(尝试多种可能的选择器)
function attachTimeListeners() {
const timeSelectors = [
'[class*="time"]',
'[class*="date"]',
'time',
'span[title*="202"]', // 匹配包含年份的时间
];
timeSelectors.forEach(selector => {
waitForKeyElements(selector, (el) => {
// 检查是否是时间格式
const text = el.textContent.trim();
if (/\d{4}-\d{2}-\d{2}/.test(text) || /\d{2}:\d{2}/.test(text)) {
addTimeClickListener(el);
}
}, false, 1000);
});
}
// 启动时间点击监听
window.addEventListener('load', () => {
attachTimeListeners();
});
/* ************** 4. 15秒无鼠标活动自动刷新 ************** */
let inactivityTimer = null;
const INACTIVITY_TIMEOUT = 15000; // 15秒
function resetInactivityTimer() {
// 清除现有计时器
if (inactivityTimer) {
clearTimeout(inactivityTimer);
}
// 设置新计时器
inactivityTimer = setTimeout(() => {
console.log('15秒无活动,刷新页面');
location.reload();
}, INACTIVITY_TIMEOUT);
}
// 监听鼠标活动
const mouseEvents = ['mousemove', 'mousedown', 'click', 'scroll', 'keypress', 'touchstart'];
mouseEvents.forEach(event => {
document.addEventListener(event, resetInactivityTimer, true);
});
// 页面加载后启动计时器
window.addEventListener('load', () => {
resetInactivityTimer();
console.log('自动刷新功能已启动:15秒无活动将自动刷新');
});
/* ************** 5. 界面优化功能 ************** */
// 5.1 为精华帖添加红色边框
function addRedBorder() {
const listItems = document.querySelectorAll('.ng-star-inserted');
listItems.forEach((item) => {
const headerContainer = item.querySelector('.header-container');
if (headerContainer) {
const topicFlag = headerContainer.querySelector('.topic-flag');
if (topicFlag) {
const digestElement = topicFlag.querySelector('.digest');
if (digestElement) {
const topicContainer = item.querySelector('.topic-container');
if (topicContainer) {
topicContainer.style.border = '1px solid rgb(80, 234, 203)';
topicContainer.style.backgroundColor = 'rgba(80, 234, 203, 0.1)';
}
}
}
}
});
}
// 5.2 设置侧边栏切换功能
function setupSidebarToggle() {
const sidebar = document.querySelector('.group-list-container');
const logoContainer = document.querySelector('.logo-container');
if (!sidebar || !logoContainer) return;
// 避免重复添加按钮
if (document.getElementById('toggle-sidebar')) return;
const toggleButton = document.createElement('button');
toggleButton.id = 'toggle-sidebar';
toggleButton.textContent = '切换目录';
logoContainer.appendChild(toggleButton);
// 获取视口宽度
const clientWidth = document.documentElement.clientWidth;
const transX = clientWidth - 1526 / 2;
// 默认隐藏侧边栏
sidebar.classList.add('hide');
// 设置hide样式
if (sidebar.classList.contains('hide')) {
sidebar.style.transform = 'translateX(calc(-100% - ' + transX + 'px))';
} else {
sidebar.style.transform = 'translateX(0)';
}
toggleButton.addEventListener('click', () => {
sidebar.classList.toggle('hide');
if (sidebar.classList.contains('hide')) {
sidebar.style.transform = 'translateX(calc(-100% - ' + transX + 'px))';
} else {
sidebar.style.transform = 'translateX(0)';
}
});
}
// 5.3 隐藏不必要的界面元素
function hideElements() {
// 头部
const headerContainer = document.querySelector('.header-container');
if (headerContainer) {
const redirect = headerContainer.querySelector('.redirect');
const userAvatar = headerContainer.querySelector('.user-avatar');
if (redirect) {
redirect.style.display = 'none';
}
if (userAvatar) {
userAvatar.style.display = 'none';
}
}
const leftLogo = document.querySelector('.logo-container .left');
const noteLogo = document.querySelector('.logo-container .note');
if (leftLogo) {
leftLogo.style.display = 'none';
}
if (noteLogo) {
noteLogo.style.display = 'none';
}
// .topic-flow-container
const topicFlowContainer = document.querySelector('.topic-flow-container');
if (topicFlowContainer) {
topicFlowContainer.style.setProperty('width', '100%', 'important');
topicFlowContainer.style.setProperty('padding-left', '100px', 'important');
topicFlowContainer.style.setProperty('padding-right', '100px', 'important');
}
// 主体上部分
const topicContainer = document.querySelector('.topic-container');
if (topicContainer) {
const ngStarInserted = topicContainer.querySelector('.ng-star-inserted');
if (ngStarInserted) {
ngStarInserted.style.display = 'none';
}
}
// 主体中部分
const mainContentContainer = document.querySelector('.main-content-container');
if (mainContentContainer) {
mainContentContainer.style.setProperty('margin-left', '10%', 'important');
mainContentContainer.style.setProperty('margin-right', '10%', 'important');
}
// 右侧边栏
const groupPreviewContainer = document.querySelector('.group-preview-container');
if (groupPreviewContainer) {
groupPreviewContainer.style.display = 'none';
}
}
// 5.4 启动界面优化功能
function initUIEnhancements() {
addRedBorder();
setupSidebarToggle();
hideElements();
// 监听DOM变化,持续应用样式
const observer = new MutationObserver(() => {
addRedBorder();
setupSidebarToggle();
hideElements();
});
observer.observe(document.body, { childList: true, subtree: true });
}
// 页面加载完成后执行界面优化
window.addEventListener('load', () => {
setTimeout(initUIEnhancements, 500);
});
})();