// ==UserScript== // @name 嘉立创社区布局优化 // @namespace http://tampermonkey.net/ // @version 1.5.0 // @description 优化嘉立创社区(jlc-bbs.com)布局:隐藏右侧低价值模块、内容区扩展、合并操作行、删除问题状态、紧凑间距、官方筛选 // @author You // @match https://www.jlc-bbs.com/* // @icon https://www.jlc-bbs.com/ssr/img/logo.970c992.svg // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @run-at document-idle // ==/UserScript== (function () { 'use strict'; // ========== 配置项 ========== const CONFIG = { // 右侧边栏各个模块的可见性(默认全部隐藏) sidebarBlocks: { '社区数据': false, // 今日帖子/互动量/在线人数等统计 '活动日历': false, // 活动日历 '推荐话题': false, // 推荐话题标签 '打赏记录': false, // 打赏记录列表 '涨分锦囊': false, // 积分任务 '广告横幅': false, // 积分抽奖等广告图 '页脚链接': false, // 备案信息等 }, // 是否隐藏整个右侧边栏 hideRightSidebar: true, // 主内容区最大宽度(null 表示不限,随屏幕自适应) contentMaxWidth: null, // 是否显示切换按钮(允许临时恢复右侧边栏) showToggleButton: true, }; // 从存储加载用户配置 const savedConfig = GM_getValue('layoutConfig', null); if (savedConfig) { try { const parsed = JSON.parse(savedConfig); if (parsed.sidebarBlocks) { CONFIG.sidebarBlocks = { ...CONFIG.sidebarBlocks, ...parsed.sidebarBlocks }; } if (parsed.hideRightSidebar !== undefined) { CONFIG.hideRightSidebar = parsed.hideRightSidebar; } if (parsed.contentMaxWidth !== undefined) { CONFIG.contentMaxWidth = parsed.contentMaxWidth; } } catch (e) { /* 忽略解析错误,使用默认配置 */ } } // 保存配置到存储 function saveConfig() { GM_setValue('layoutConfig', JSON.stringify({ sidebarBlocks: CONFIG.sidebarBlocks, hideRightSidebar: CONFIG.hideRightSidebar, contentMaxWidth: CONFIG.contentMaxWidth, })); } // ========== 样式注入 ========== function applyStyles() { // 移除旧的样式 const oldStyle = document.getElementById('jlc-layout-optimize-style'); if (oldStyle) oldStyle.remove(); let css = ''; if (CONFIG.hideRightSidebar) { // 隐藏右侧边栏容器 css += ` /* 隐藏右侧 sticky-wrap(第2个) */ .content.flex.relative > .sticky-wrap:nth-child(3) { display: none !important; } /* 移除主内容区最大宽度限制,让它填充 */ .content.flex.relative > .flex-1 { max-width: none !important; } `; } else { // 按模块逐个控制可见性 const rightSidebar = document.querySelector('.position-sticky.w-\\[310px\\]'); if (rightSidebar) { const blocks = rightSidebar.children; for (let i = 0; i < blocks.length; i++) { const block = blocks[i]; const titleEl = block.querySelector('h3, h4, [class*="title"]'); const title = titleEl ? titleEl.textContent.trim() : ''; const preview = block.textContent.substring(0, 50).trim(); // 匹配模块名称 let matched = false; for (const [name, visible] of Object.entries(CONFIG.sidebarBlocks)) { if (preview.includes(name) && !visible) { block.style.display = 'none'; matched = true; break; } } if (!matched) { block.style.display = ''; } } } } // 如果设置了自定义最大宽度 if (CONFIG.contentMaxWidth) { css += ` .content.flex.relative > .flex-1 { max-width: ${CONFIG.contentMaxWidth}px !important; } `; } // 通用优化:发帖区域也扩大 css += ` /* 发帖框宽度自适应 */ .content.flex.relative > .flex-1 .mt-\\[20px\\] { max-width: 100% !important; } /* ===== 搜索框加宽 + 颜色增强 ===== */ .search-input.el-input { width: 500px !important; } .search-input .el-input__inner { background-color: #fff !important; border: 1.5px solid #c0c4cc !important; border-radius: 20px !important; height: 36px !important; line-height: 36px !important; padding-left: 36px !important; font-size: 14px !important; color: #333 !important; } .search-input .el-input__inner::placeholder { color: #909399 !important; } .search-input .el-input__inner:focus { border-color: #1890ff !important; box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.15) !important; } .search-input .el-input__prefix { left: 12px !important; } /* ===== 紧凑间距:20px → 8px ===== */ /* 主内容区内边距 */ .flex-1.bg-\\[\\#f2f3f5\\] { padding-left: 8px !important; padding-right: 8px !important; } /* 发帖框顶部间距 */ .flex-1.bg-\\[\\#f2f3f5\\] > .mt-\\[20px\\] { margin-top: 8px !important; } /* 卡片内边距 上下 */ .borderb, .borderb.px-0.relative { padding-top: 8px !important; padding-bottom: 8px !important; } /* 卡片内容区信息行间距 */ .borderb .mr-\\[20px\\] { margin-right: 8px !important; } /* 左侧/右侧导航 pt-20 → 8px */ .sticky-wrap.pt-20, .sticky-wrap.pt-\\[20px\\] { padding-top: 8px !important; } /* 发帖编辑区内边距 */ .px-\\[20px\\].pt-\\[20px\\] { padding-left: 8px !important; padding-right: 8px !important; padding-top: 8px !important; } /* ===== 合并操作行后的样式 ===== */ /* info-part-2 容器:允许换行,对齐 */ .info-part-2.flex.items-center { flex-wrap: wrap !important; gap: 0 4px !important; } /* 合并进来的 menu 容器 */ .info-part-2 .menu { display: inline-flex !important; align-items: center !important; } .info-part-2 .menu .flex.items-center { display: inline-flex !important; align-items: center !important; } /* 合并后的按钮缩小间距和字号 */ .info-part-2 .menu .el-tooltip, .info-part-2 .menu .share-btn, .info-part-2 .menu .flag-btn { margin-right: 12px !important; font-size: 12px !important; color: #899099 !important; display: inline-flex !important; align-items: center !important; gap: 3px !important; } .info-part-2 .menu .el-tooltip img, .info-part-2 .menu .share-btn img, .info-part-2 .menu .flag-btn img { width: 14px !important; height: 14px !important; } .info-part-2 .menu .el-tooltip span, .info-part-2 .menu .share-btn span, .info-part-2 .menu .flag-btn span { font-size: 12px !important; } /* 分隔符 */ .jlc-separator { color: #d0d5da; margin: 0 6px; font-size: 12px; } /* ===== 官方筛选按钮选中样式 ===== */ .jlc-official-filter.question-type-active { color: #1890ff !important; font-weight: 600 !important; } /* 合并进来的标签(如"嘉立创EDA") */ .info-part-2 > .text-\\[\\#899099\\] { margin-left: 4px !important; font-size: 12px !important; } /* 切换按钮样式 */ #jlc-sidebar-toggle { position: fixed; right: 16px; bottom: 80px; z-index: 9999; width: 40px; height: 40px; border-radius: 50%; background: #fff; border: 1px solid #e0e0e0; box-shadow: 0 2px 8px rgba(0,0,0,0.15); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; transition: all 0.2s ease; color: #666; line-height: 1; } #jlc-sidebar-toggle:hover { background: #f5f5f5; box-shadow: 0 4px 12px rgba(0,0,0,0.2); color: #333; } #jlc-sidebar-toggle.sidebar-visible { background: #1890ff; color: #fff; border-color: #1890ff; } #jlc-sidebar-toggle.sidebar-visible:hover { background: #40a9ff; } /* 设置面板样式 */ #jlc-settings-panel { position: fixed; right: 16px; bottom: 130px; z-index: 9999; background: #fff; border-radius: 12px; box-shadow: 0 4px 24px rgba(0,0,0,0.18); padding: 20px; width: 280px; font-size: 13px; display: none; } #jlc-settings-panel.visible { display: block; } #jlc-settings-panel h4 { margin: 0 0 12px 0; font-size: 15px; font-weight: 600; color: #333; border-bottom: 1px solid #eee; padding-bottom: 8px; } .jlc-setting-row { display: flex; align-items: center; justify-content: space-between; padding: 6px 0; color: #555; } .jlc-setting-row label { cursor: pointer; user-select: none; } .jlc-setting-row input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; accent-color: #1890ff; } .jlc-setting-divider { height: 1px; background: #eee; margin: 10px 0; } .jlc-setting-btn { display: inline-block; padding: 4px 12px; border-radius: 4px; border: 1px solid #d9d9d9; background: #fff; cursor: pointer; font-size: 12px; color: #555; margin-right: 6px; margin-top: 8px; transition: all 0.15s; } .jlc-setting-btn:hover { border-color: #1890ff; color: #1890ff; } `; // 注入样式 const styleEl = document.createElement('style'); styleEl.id = 'jlc-layout-optimize-style'; styleEl.textContent = css; document.head.appendChild(styleEl); } // ========== UI 控件 ========== // 创建切换按钮 function createToggleButton() { if (!CONFIG.showToggleButton) return; if (document.getElementById('jlc-sidebar-toggle')) return; const btn = document.createElement('button'); btn.id = 'jlc-sidebar-toggle'; btn.title = CONFIG.hideRightSidebar ? '显示右侧边栏' : '隐藏右侧边栏'; btn.innerHTML = CONFIG.hideRightSidebar ? '📱' : '📐'; btn.addEventListener('click', () => { CONFIG.hideRightSidebar = !CONFIG.hideRightSidebar; btn.innerHTML = CONFIG.hideRightSidebar ? '📱' : '📐'; btn.title = CONFIG.hideRightSidebar ? '显示右侧边栏' : '隐藏右侧边栏'; applyStyles(); saveConfig(); }); document.body.appendChild(btn); } // 创建设置面板 function createSettingsPanel() { if (document.getElementById('jlc-settings-panel')) return; const panel = document.createElement('div'); panel.id = 'jlc-settings-panel'; let html = '

🛠️ 布局优化设置

'; // 右侧边栏各模块开关(仅在右侧边栏可见时生效) for (const [name, visible] of Object.entries(CONFIG.sidebarBlocks)) { html += `
`; } html += '
'; html += ''; html += ''; panel.innerHTML = html; // 绑定事件 panel.querySelectorAll('input[type="checkbox"]').forEach(cb => { cb.addEventListener('change', (e) => { const name = e.target.dataset.blockName; CONFIG.sidebarBlocks[name] = e.target.checked; applyStyles(); saveConfig(); }); }); panel.querySelector('#jlc-settings-restore').addEventListener('click', () => { CONFIG.sidebarBlocks = { '社区数据': false, '活动日历': false, '推荐话题': false, '打赏记录': false, '涨分锦囊': false, '广告横幅': false, '页脚链接': false, }; CONFIG.hideRightSidebar = true; saveConfig(); applyStyles(); panel.querySelectorAll('input[type="checkbox"]').forEach(cb => { cb.checked = false; }); const toggleBtn = document.getElementById('jlc-sidebar-toggle'); if (toggleBtn) { toggleBtn.innerHTML = '📱'; toggleBtn.title = '显示右侧边栏'; } }); panel.querySelector('#jlc-settings-close').addEventListener('click', () => { panel.classList.remove('visible'); }); document.body.appendChild(panel); // 长按切换按钮打开设置面板 const toggleBtn = document.getElementById('jlc-sidebar-toggle'); if (toggleBtn) { let longPressTimer = null; toggleBtn.addEventListener('mousedown', (e) => { longPressTimer = setTimeout(() => { panel.classList.toggle('visible'); }, 500); }); toggleBtn.addEventListener('mouseup', () => { clearTimeout(longPressTimer); }); toggleBtn.addEventListener('mouseleave', () => { clearTimeout(longPressTimer); }); } } // ========== 卡片结构优化:合并操作行 + 删除问题状态 ========== // 标记已处理的卡片,避免重复处理 const processedCards = new WeakSet(); function optimizeCards() { // 找到所有帖子卡片 const cards = document.querySelectorAll('.borderb, .borderb.px-0.relative'); for (const card of cards) { if (processedCards.has(card)) continue; processedCards.add(card); // --- 1. 删除问题状态块 (.question-status) --- const qStatus = card.querySelector('.question-status'); if (qStatus) { const qItem = qStatus.closest('.question-item'); if (qItem) { // 把 question-item 里的内容区(标题+正文)提升出来,替代 question-item const contentCol = qItem.querySelector('.flex.flex-col.justify-center'); if (contentCol) { const parent = qItem.parentElement; // 将内容区的子节点插入到 question-item 前面 while (contentCol.firstChild) { parent.insertBefore(contentCol.firstChild, qItem); } } qItem.remove(); } } // --- 2. 合并操作行到信息行 --- // 找到交互按钮行:.flex.justify-between.items-center.mt-[16px] const actionBar = card.querySelector('.flex.justify-between.items-center.mt-\\[16px\\]'); if (!actionBar) continue; // 找到信息行:.info-part-2.flex.items-center const infoPart2 = card.querySelector('.info-part-2.flex.items-center'); if (!infoPart2) continue; // 提取操作行中的元素 const menu = actionBar.querySelector('.menu'); const tagEl = actionBar.querySelector('.text-\\[\\#899099\\]'); if (menu) { // 创建一个分隔符 const separator = document.createElement('span'); separator.textContent = ' | '; separator.className = 'jlc-separator'; infoPart2.appendChild(separator); // 移动 menu 到 info-part-2 // 缩小间距,调整样式 menu.style.display = 'inline-flex'; menu.style.alignItems = 'center'; menu.querySelectorAll('.mr-\\[30px\\]').forEach(el => { el.classList.remove('mr-[30px]'); el.classList.add('mr-[16px]'); // 缩小图标 el.style.fontSize = '12px'; }); infoPart2.appendChild(menu); } if (tagEl) { // 标签也移动到 info-part-2 infoPart2.appendChild(tagEl); } // 移除原来的操作行 actionBar.remove(); } } // ========== 官方筛选功能 ========== // 筛选状态: 'all' | 'official' | 'unofficial' let officialFilter = 'all'; const injectedFilterBars = new WeakSet(); function injectOfficialFilter() { // 找到所有 tab pane(含当前激活和未激活的,SPA 切换时需要处理新出现的) const tabPanes = document.querySelectorAll('.el-tab-pane'); for (const pane of tabPanes) { const questionType = pane.querySelector(':scope > .question-type'); if (!questionType || injectedFilterBars.has(questionType)) continue; injectedFilterBars.add(questionType); // 找到"综合"按钮所在的容器(即 .question-type-item 的直接父级 div) const firstTabItem = questionType.querySelector('.question-type-item'); if (!firstTabItem) continue; const tabContainer = firstTabItem.parentElement; if (!tabContainer) continue; if (tabContainer.querySelector('.jlc-official-filter')) continue; // 用和"综合"/"最新发布"完全相同的 class 创建按钮 const btnOfficial = document.createElement('span'); btnOfficial.className = 'mr-[10px] cursor-pointer question-type-item jlc-official-filter'; btnOfficial.dataset.filter = 'official'; btnOfficial.textContent = '只看官方'; const btnUnofficial = document.createElement('span'); btnUnofficial.className = 'mr-[10px] cursor-pointer question-type-item jlc-official-filter'; btnUnofficial.dataset.filter = 'unofficial'; btnUnofficial.textContent = '不看官方'; tabContainer.appendChild(btnOfficial); tabContainer.appendChild(btnUnofficial); // 点击事件 btnOfficial.addEventListener('click', () => { officialFilter = officialFilter === 'official' ? 'all' : 'official'; updateFilterUI(questionType); applyOfficialFilter(pane); }); btnUnofficial.addEventListener('click', () => { officialFilter = officialFilter === 'unofficial' ? 'all' : 'unofficial'; updateFilterUI(questionType); applyOfficialFilter(pane); }); } // 更新所有已注入按钮的激活状态 updateAllFilterUI(); } function updateFilterUI(questionType) { updateAllFilterUI(); } function updateAllFilterUI() { document.querySelectorAll('.jlc-official-filter').forEach(btn => { const f = btn.dataset.filter; if (f === officialFilter) { btn.classList.add('question-type-active'); } else { btn.classList.remove('question-type-active'); } }); } function applyOfficialFilter(pane) { const cardList = pane.querySelector('.bg-\\[\\#f2f3f5\\]'); if (!cardList) return; cardList.querySelectorAll('.borderb').forEach(card => { const isOfficial = !!card.querySelector('.guan'); if (officialFilter === 'all') card.style.display = ''; else if (officialFilter === 'official') card.style.display = isOfficial ? '' : 'none'; else if (officialFilter === 'unofficial') card.style.display = isOfficial ? 'none' : ''; }); } // 对所有 tab pane 重新应用筛选(无限滚动加载新卡片后调用) function reapplyAllFilters() { if (officialFilter === 'all') return; document.querySelectorAll('.el-tab-pane').forEach(pane => { applyOfficialFilter(pane); }); } // ========== 初始化 ========== function init() { applyStyles(); createToggleButton(); createSettingsPanel(); optimizeCards(); injectOfficialFilter(); // 监听 DOM 变化,处理 SPA 路由切换和无限滚动加载新卡片 const observer = new MutationObserver(() => { applyStyles(); createToggleButton(); createSettingsPanel(); optimizeCards(); injectOfficialFilter(); // 无限滚动加载新卡片后,重新应用官方筛选 reapplyAllFilters(); }); observer.observe(document.body, { childList: true, subtree: true, }); console.log('[嘉立创社区布局优化] 已加载 - 右侧边栏已隐藏,内容区已扩展,操作行已合并'); } // 等待页面加载完成 if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } })();