您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在右侧显示知乎、B站、豆瓣、X(推特)、Pixiv、微博和Reddit的独立导航面板
// ==UserScript== // @name 多平台右侧导航面板增强版 // @namespace http://tampermonkey.net/ // @version 5.3 // @description 在右侧显示知乎、B站、豆瓣、X(推特)、Pixiv、微博和Reddit的独立导航面板 // @author You // @match https://*.zhihu.com/* // @match https://*.bilibili.com/* // @match https://*.douban.com/* // @match https://*.x.com/* // @match https://*.pixiv.net/* // @match https://*.weibo.com/* // @match https://*.reddit.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // 平台数据定义 const platformData = { zhihu: { name: '知乎', users: [], color: '#0084ff' }, bilibili: { name: 'B站', users: [], color: '#fb7299' }, douban: { name: '豆瓣', users: [], color: '#007722' }, x: { name: 'X(推特)', users: [], color: '#000000' }, pixiv: { name: 'Pixiv', users: [], color: '#0096fa' }, weibo: { name: '微博', users: [], color: '#e6162d' }, reddit: { name: 'Reddit', users: [], color: '#ff4500' } }; // 获取当前平台 const currentHost = window.location.hostname; let currentPlatform = 'zhihu'; // 默认 if (currentHost.includes('bilibili')) { currentPlatform = 'bilibili'; } else if (currentHost.includes('douban')) { currentPlatform = 'douban'; } else if (currentHost.includes('x.com')) { currentPlatform = 'x'; } else if (currentHost.includes('pixiv.net')) { currentPlatform = 'pixiv'; } else if (currentHost.includes('weibo.com')) { currentPlatform = 'weibo'; } else if (currentHost.includes('reddit.com')) { currentPlatform = 'reddit'; } // 从存储中获取用户列表或使用初始列表 const platformUsers = GM_getValue(`${currentPlatform}_users`, platformData[currentPlatform].users); // 创建主容器 const container = document.createElement('div'); container.id = 'multi-platform-panel'; document.body.appendChild(container); // 颜色加深函数 function darkenColor(color, percent) { const num = parseInt(color.replace('#', ''), 16); const amt = Math.round(2.55 * percent); const R = (num >> 16) - amt; const G = (num >> 8 & 0x00FF) - amt; const B = (num & 0x0000FF) - amt; return '#' + ( 0x1000000 + (R < 0 ? 0 : R) * 0x10000 + (G < 0 ? 0 : G) * 0x100 + (B < 0 ? 0 : B) ).toString(16).slice(1); } // 颜色变淡函数 function lightenColor(color, percent) { const num = parseInt(color.replace('#', ''), 16); const amt = Math.round(2.55 * percent); const R = (num >> 16) + amt; const G = (num >> 8 & 0x00FF) + amt; const B = (num & 0x0000FF) + amt; return '#' + ( 0x1000000 + (R > 255 ? 255 : R) * 0x10000 + (G > 255 ? 255 : G) * 0x100 + (B > 255 ? 255 : B) ).toString(16).slice(1); } // 计算不同元素的颜色 const primaryColor = platformData[currentPlatform].color; const headerColor = darkenColor(primaryColor, 10); // 导航标题使用深色 const buttonColor = lightenColor(primaryColor, 10); // 超链接按钮使用浅色 const actionButtonColor = primaryColor; // 添加/收藏按钮使用原色 // 添加全局样式 GM_addStyle(` #multi-platform-panel * { box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; } #expand-button { position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 9999; width: 20px; height: 40px; background-color: ${headerColor}; color: white; display: flex; align-items: center; justify-content: center; border-radius: 5px 0 0 5px; cursor: pointer; box-shadow: 0 2px 5px rgba(0,0,0,0.2); transition: all 0.3s ease; } #expand-button:hover { background-color: ${darkenColor(headerColor, 20)}; } #panel-container { position: fixed; right: -300px; top: 50%; transform: translateY(-50%); z-index: 1000; width: 250px; background-color: rgba(255, 255, 255, 0.95); border-radius: 10px 0 0 10px; box-shadow: 0 2px 15px rgba(0, 0, 0, 0.2); transition: right 0.3s ease; max-height: 80vh; overflow: hidden; display: flex; flex-direction: column; } .panel-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 15px; background-color: ${headerColor}; color: white; } .panel-title { font-weight: bold; font-size: 14px; } .close-button { cursor: pointer; font-size: 20px; line-height: 1; transition: transform 0.2s; } .close-button:hover { transform: scale(1.2); } #buttons-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; padding: 15px; overflow-y: auto; max-height: calc(80vh - 150px); scrollbar-width: none; -ms-overflow-style: none; } #buttons-grid::-webkit-scrollbar { display: none; } .button-wrapper { position: relative; overflow: visible; } .user-button { display: block; padding: 6px 8px; background-color: ${buttonColor}; color: white !important; text-align: center; border-radius: 4px; text-decoration: none; font-weight: 500; font-size: 12px; transition: all 0.3s; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100px; } .user-button:hover { background-color: ${darkenColor(buttonColor, 20)}; transform: scale(1.05); } .delete-button { position: absolute; top: -5px; right: -5px; width: 16px; height: 16px; background-color: ${lightenColor(buttonColor, 30)}; color: white; border-radius: 50%; display: flex; justify-content: center; align-items: center; font-size: 12px; cursor: pointer; opacity: 0.7; transition: opacity 0.3s; z-index: 100; box-shadow: 0 1px 3px rgba(0,0,0,0.2); } .delete-button:hover { opacity: 1; background-color: ${lightenColor(buttonColor, 20)}; } .action-button { padding: 8px 12px; color: white; text-align: center; border-radius: 5px; cursor: pointer; font-weight: 500; transition: all 0.3s; font-size: 13px; background-color: ${actionButtonColor}; flex: 1; } .action-button:hover { background-color: ${darkenColor(actionButtonColor, 20)}; transform: scale(1.05); } .button-container { display: flex; flex-direction: row; gap: 10px; padding: 0 15px 15px; } `); // 创建展开按钮 const expandButton = document.createElement('div'); expandButton.id = 'expand-button'; expandButton.textContent = '▶'; container.appendChild(expandButton); // 渲染面板函数 function renderPanel() { // 移除旧的面板容器(如果存在) const oldPanel = document.getElementById('panel-container'); if (oldPanel) oldPanel.remove(); // 创建面板容器 const panelContainer = document.createElement('div'); panelContainer.id = 'panel-container'; container.appendChild(panelContainer); // 添加标题和关闭按钮 const header = document.createElement('div'); header.className = 'panel-header'; panelContainer.appendChild(header); const title = document.createElement('div'); title.className = 'panel-title'; title.textContent = `${platformData[currentPlatform].name}导航`; header.appendChild(title); const closeButton = document.createElement('div'); closeButton.className = 'close-button'; closeButton.textContent = '×'; closeButton.onclick = () => { panelContainer.style.right = '-300px'; expandButton.style.display = 'flex'; }; header.appendChild(closeButton); // 创建用户按钮网格容器 const buttonsGrid = document.createElement('div'); buttonsGrid.id = 'buttons-grid'; panelContainer.appendChild(buttonsGrid); // 创建用户按钮 platformUsers.forEach((user) => { const buttonWrapper = document.createElement('div'); buttonWrapper.className = 'button-wrapper'; buttonsGrid.appendChild(buttonWrapper); const button = document.createElement('a'); button.className = 'user-button'; button.href = user.url; button.target = '_blank'; button.textContent = user.name; buttonWrapper.appendChild(button); const deleteButton = document.createElement('div'); deleteButton.className = 'delete-button'; deleteButton.innerHTML = '×'; deleteButton.onclick = (e) => { e.preventDefault(); e.stopPropagation(); if (confirm(`确定要删除 "${user.name}" 吗?`)) { const index = platformUsers.findIndex(u => u.name === user.name && u.url === user.url); if (index !== -1) { platformUsers.splice(index, 1); GM_setValue(`${currentPlatform}_users`, platformUsers); renderPanel(); } } }; buttonWrapper.appendChild(deleteButton); // 当鼠标移入按钮区域时显示删除按钮 buttonWrapper.onmouseenter = () => { deleteButton.style.display = 'flex'; }; buttonWrapper.onmouseleave = () => { deleteButton.style.display = 'none'; }; // 初始隐藏删除按钮 deleteButton.style.display = 'none'; }); // 创建按钮容器 const buttonContainer = document.createElement('div'); buttonContainer.className = 'button-container'; panelContainer.appendChild(buttonContainer); // 添加"添加"按钮 const addButton = document.createElement('div'); addButton.className = 'action-button'; addButton.textContent = '添加'; addButton.onclick = () => { const name = prompt('请输入用户名:'); if (name === null) return; const url = prompt('请输入用户主页链接:'); if (url === null) return; if (name && url) { platformUsers.push({ name, url }); GM_setValue(`${currentPlatform}_users`, platformUsers); renderPanel(); // 修复:添加后保持面板展开状态 panelContainer.style.right = '0'; expandButton.style.display = 'none'; } }; buttonContainer.appendChild(addButton); // 添加"收藏"按钮 const collectButton = document.createElement('div'); collectButton.className = 'action-button'; collectButton.textContent = '收藏'; collectButton.onclick = () => { const name = prompt('请输入收藏名称:', document.title); if (name === null) return; const url = window.location.href; if (name && url) { platformUsers.push({ name, url }); GM_setValue(`${currentPlatform}_users`, platformUsers); renderPanel(); // 修复:收藏后保持面板展开状态 panelContainer.style.right = '0'; expandButton.style.display = 'none'; } }; buttonContainer.appendChild(collectButton); // 展开按钮点击事件 expandButton.onclick = () => { panelContainer.style.right = '0'; expandButton.style.display = 'none'; }; } // 初始渲染 renderPanel(); })();