
(function() {
'use strict';
const CONFIG = {
topBuffer: 200,
statusBarPosition: 'bottom-right',
debug: false
};
let optimizedAnswers = new Map();
let statusBar = null;
let currentMode = GM_getValue('zhihu_optimizer_mode', 'light');
function init() {
log('初始化知乎内存优化脚本');
createStatusBar();
observeExistingAnswers();
observeNewContent();
}
function createStatusBar() {
statusBar = document.createElement('div');
statusBar.id = 'zhihu-memory-optimizer-status';
const isLightMode = currentMode === 'light';
statusBar.className = isLightMode ? 'zhihu-optimizer-status-light' : 'zhihu-optimizer-status-full';
statusBar.innerHTML = `
<div class="zhihu-optimizer-status-header">
<div class="zhihu-optimizer-status-title">知乎内存优化</div>
<button class="zhihu-optimizer-mode-toggle" id="zhihuOptimizerModeToggle">
${isLightMode ? '切换到完全移除模式' : '切换到轻量优化模式'}
</button>
</div>
<div class="zhihu-optimizer-status-details">
<div>已优化内容: <span id="zhihu-optimized-count">0</span> 个</div>
<div>内存节省: <span id="zhihu-memory-saved">0</span> KB</div>
</div>
<div class="zhihu-optimizer-mode-explanation" id="zhihuOptimizerModeExplanation">
${isLightMode ?
'当前模式:轻量优化 - 内容被替换为占位符,可以快速恢复' :
'当前模式:完全移除 - 内容被完全删除,需要重新加载页面'}
</div>
`;
Object.assign(statusBar.style, {
position: 'fixed',
bottom: '20px',
right: '20px',
color: 'white',
padding: '10px 15px',
borderRadius: '4px',
boxShadow: '0 2px 10px rgba(0, 0, 0, 0.2)',
fontSize: '14px',
zIndex: '10000',
minWidth: '300px',
backgroundColor: isLightMode ? '#0084ff' : '#ff4d4f'
});
const modeToggle = statusBar.querySelector('#zhihuOptimizerModeToggle');
modeToggle.addEventListener('click', toggleMode);
document.body.appendChild(statusBar);
addStyles();
}
function addStyles() {
const style = document.createElement('style');
style.textContent = `
.zhihu-optimizer-status-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.zhihu-optimizer-status-title {
font-weight: bold;
}
.zhihu-optimizer-mode-toggle {
background: rgba(255, 255, 255, 0.2);
border: none;
color: white;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.zhihu-optimizer-status-details {
display: flex;
justify-content: space-between;
font-size: 12px;
opacity: 0.9;
}
.zhihu-optimizer-mode-explanation {
margin-top: 10px;
padding: 10px;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
font-size: 12px;
}
.zhihu-optimized-light {
background-color: #f5f5f5 !important;
border: 1px dashed #d9d9d9 !important;
}
.zhihu-optimized-full {
background-color: #fff2f0 !important;
border: 1px dashed #ffa39e !important;
}
.zhihu-optimizer-placeholder-light {
padding: 20px;
text-align: center;
color: #8590a6;
background-color: #f6f6f6;
border: 1px dashed #d9d9d9;
border-radius: 4px;
}
.zhihu-optimizer-placeholder-full {
padding: 20px;
text-align: center;
color: #ff4d4f;
background-color: #fff2f0;
border: 1px dashed #ffa39e;
border-radius: 4px;
}
.zhihu-optimizer-placeholder-light button,
.zhihu-optimizer-placeholder-full button {
background-color: #0084ff;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
.zhihu-optimizer-placeholder-full button {
background-color: #ff4d4f;
}
`;
document.head.appendChild(style);
}
function toggleMode() {
if (currentMode === 'light') {
currentMode = 'full';
GM_setValue('zhihu_optimizer_mode', 'full');
statusBar.style.backgroundColor = '#ff4d4f';
const modeToggle = statusBar.querySelector('#zhihuOptimizerModeToggle');
modeToggle.textContent = '切换到轻量优化模式';
const modeExplanation = statusBar.querySelector('#zhihuOptimizerModeExplanation');
modeExplanation.textContent = '当前模式:完全移除 - 内容被完全删除,需要重新加载页面';
optimizedAnswers.forEach((data, answerId) => {
const answer = document.querySelector(`[data-optimizer-id="${answerId}"]`);
if (answer && data.type === 'light') {
completelyRemoveAnswer(answer);
}
});
} else {
currentMode = 'light';
GM_setValue('zhihu_optimizer_mode', 'light');
statusBar.style.backgroundColor = '#0084ff';
const modeToggle = statusBar.querySelector('#zhihuOptimizerModeToggle');
modeToggle.textContent = '切换到完全移除模式';
const modeExplanation = statusBar.querySelector('#zhihuOptimizerModeExplanation');
modeExplanation.textContent = '当前模式:轻量优化 - 内容被替换为占位符,可以快速恢复';
log('切换到轻量优化模式,但无法恢复已完全移除的内容');
}
updateStatusBar();
}
function updateStatusBar() {
const countElement = document.getElementById('zhihu-optimized-count');
const memoryElement = document.getElementById('zhihu-memory-saved');
if (countElement && memoryElement) {
let totalMemory = 0;
optimizedAnswers.forEach(data => {
totalMemory += data.size;
});
countElement.textContent = optimizedAnswers.size;
memoryElement.textContent = totalMemory.toFixed(1);
}
}
function observeExistingAnswers() {
const answers = getAnswerElements();
answers.forEach(answer => {
if (!answer.dataset.optimizerId) {
const id = generateId();
answer.dataset.optimizerId = id;
observeAnswer(answer);
}
});
log(`观察了 ${answers.length} 个现有回答`);
}
function observeNewContent() {
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1) {
const answers = node.querySelectorAll && node.querySelectorAll('.List-item, .Question-main .ListShortcut .List-item');
if (answers && answers.length) {
answers.forEach(answer => {
if (!answer.dataset.optimizerId) {
const id = generateId();
answer.dataset.optimizerId = id;
observeAnswer(answer);
}
});
log(`观察了 ${answers.length} 个新回答`);
}
if (node.matches && (node.matches('.List-item') || node.matches('.Question-main .ListShortcut .List-item'))) {
if (!node.dataset.optimizerId) {
const id = generateId();
node.dataset.optimizerId = id;
observeAnswer(node);
log('观察了 1 个新回答');
}
}
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
function observeAnswer(answer) {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (!entry.isIntersecting && entry.boundingClientRect.top < -CONFIG.topBuffer) {
if (currentMode === 'light') {
optimizeAnswer(answer);
} else {
completelyRemoveAnswer(answer);
}
}
if (entry.isIntersecting && currentMode === 'light' && optimizedAnswers.has(answer.dataset.optimizerId)) {
const data = optimizedAnswers.get(answer.dataset.optimizerId);
if (data && data.type === 'light') {
restoreAnswer(answer);
}
}
});
}, {
root: null,
threshold: 0,
rootMargin: `${CONFIG.topBuffer}px 0px 0px 0px`
});
observer.observe(answer);
}
function optimizeAnswer(answer) {
if (optimizedAnswers.has(answer.dataset.optimizerId)) {
return;
}
const originalHTML = answer.innerHTML;
const estimatedSize = estimateMemoryUsage(originalHTML);
optimizedAnswers.set(answer.dataset.optimizerId, {
html: originalHTML,
size: estimatedSize,
type: 'light'
});
const placeholder = document.createElement('div');
placeholder.className = 'zhihu-optimizer-placeholder-light';
placeholder.innerHTML = `
<p>此内容已优化以节省内存</p>
<p style="font-size: 12px; margin-top: 5px;">约节省 ${estimatedSize}KB 内存</p>
<button>恢复内容</button>
`;
const restoreButton = placeholder.querySelector('button');
restoreButton.addEventListener('click', () => {
restoreAnswer(answer);
});
answer.innerHTML = '';
answer.appendChild(placeholder);
answer.classList.add('zhihu-optimized-light');
log(`轻量优化了回答 ${answer.dataset.optimizerId},节省约 ${estimatedSize}KB 内存`);
updateStatusBar();
}
function completelyRemoveAnswer(answer) {
if (optimizedAnswers.has(answer.dataset.optimizerId)) {
optimizedAnswers.delete(answer.dataset.optimizerId);
}
const originalHTML = answer.innerHTML;
const estimatedSize = estimateMemoryUsage(originalHTML);
optimizedAnswers.set(answer.dataset.optimizerId, {
size: estimatedSize,
type: 'full'
});
const placeholder = document.createElement('div');
placeholder.className = 'zhihu-optimizer-placeholder-full';
placeholder.innerHTML = `
<p>此内容已完全移除以节省内存</p>
<p style="font-size: 12px; margin-top: 5px;">约节省 ${estimatedSize}KB 内存</p>
<button>重新加载页面</button>
`;
const reloadButton = placeholder.querySelector('button');
reloadButton.addEventListener('click', () => {
location.reload();
});
answer.innerHTML = '';
answer.appendChild(placeholder);
answer.classList.remove('zhihu-optimized-light');
answer.classList.add('zhihu-optimized-full');
log(`完全移除了回答 ${answer.dataset.optimizerId},节省约 ${estimatedSize}KB 内存`);
updateStatusBar();
}
function restoreAnswer(answer) {
const data = optimizedAnswers.get(answer.dataset.optimizerId);
if (data && data.type === 'light') {
answer.innerHTML = data.html;
answer.classList.remove('zhihu-optimized-light');
optimizedAnswers.delete(answer.dataset.optimizerId);
log(`恢复了回答 ${answer.dataset.optimizerId}`);
updateStatusBar();
observeAnswer(answer);
}
}
function getAnswerElements() {
return document.querySelectorAll('.List-item, .Question-main .ListShortcut .List-item');
}
function estimateMemoryUsage(html) {
const size = html.length * 2 / 1024;
return Math.round(size * 10) / 10;
}
function generateId() {
return 'optimizer_' + Math.random().toString(36).substr(2, 9);
}
function log(message) {
if (CONFIG.debug) {
console.log(`[知乎内存优化] ${message}`);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();```