Greasy Fork is available in English.
1. 去掉 disabled-copy 类及水印遮挡;2. 自动点击"展开"按钮保持全文展开;3. 点击时间复制帖子内容
当前为
// ==UserScript==
// @name 知识星球·解除复制限制+帖子自动展开+点击时间复制
// @namespace https://axutongxue.com/
// @version 1.1
// @license MIT
// @description 1. 去掉 disabled-copy 类及水印遮挡;2. 自动点击"展开"按钮保持全文展开;3. 点击时间复制帖子内容
// @author kejin——公众号:懒人股选
// @match *://wx.zsxq.com/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
/* ************** 通用工具 ************** */
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();
});
})();