// ==UserScript== // @name 小说阅读助手 // @namespace http://tampermonkey.net/ // @version 1.0.0 // @description 通用小说阅读助手,支持自动翻页、繁简转换、夜间模式等功能 // @author 小说阅读助手 // @match *://*/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @license MIT // ==/UserScript== (function() { 'use strict'; // 配置和设置 const Settings = { autoScroll: false, autoScrollDelay: 30, // 秒 traditional: false, fontSize: 16, darkMode: false, lastRead: {}, init() { this.load(); this.bindEvents(); }, load() { const saved = GM_getValue('novelSettings', '{}'); try { const data = JSON.parse(saved); Object.assign(this, data); } catch(e) { console.log('加载设置失败'); } }, save() { const data = { autoScroll: this.autoScroll, autoScrollDelay: this.autoScrollDelay, traditional: this.traditional, fontSize: this.fontSize, darkMode: this.darkMode, lastRead: this.lastRead }; GM_setValue('novelSettings', JSON.stringify(data)); }, bindEvents() { // 监听设置变更 Object.keys(this).forEach(key => { let value = this[key]; Object.defineProperty(this, key, { get() { return value; }, set(newValue) { value = newValue; this.save(); return true; }, enumerable: true, configurable: true }); }); } }; // 繁简转换映射表 const charMap = { '著': '着', '裏': '里', '後': '后', '來': '来', '時': '时', '實': '实', '現': '现', '個': '个', '這': '这', '邊': '边', '對': '对', '長': '长', '發': '发', '過': '过', '東': '东', '務': '务', '業': '业', '學': '学', '問': '问', '開': '开', '關': '关', '門': '门', '見': '见', '員': '员', '從': '从', '氣': '气', '機': '机', '車': '车', '進': '进', '論': '论', '據': '据', '經': '经', '與': '与', '為': '为', '應': '应', '頭': '头', '產': '产', '內': '内', '資': '资', '質': '质' }; // 主要功能 const NovelReader = { currentElement: null, scrollTimer: null, pageBottomTimer: null, init() { Settings.init(); this.createUI(); this.detectAndConvert(); this.bindGlobalEvents(); }, createUI() { // 添加样式 GM_addStyle(` /* 浮动按钮样式 - 设计更美观 */ .novel-float-btn { position: fixed; bottom: 30px; right: 30px; width: 60px; height: 60px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 50%; box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4); cursor: pointer; z-index: 999999; display: flex; align-items: center; justify-content: center; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); border: 2px solid rgba(255, 255, 255, 0.2); backdrop-filter: blur(10px); } .novel-float-btn:hover { transform: scale(1.1) rotate(10deg); box-shadow: 0 6px 25px rgba(102, 126, 234, 0.6); } .novel-float-btn:active { transform: scale(0.95); } .novel-float-btn::before { content: "阅"; color: white; font-size: 24px; font-weight: bold; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } /* 设置面板 - 毛玻璃效果 */ .novel-settings-panel { position: fixed; bottom: 100px; right: 30px; width: 320px; background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(20px); border-radius: 20px; box-shadow: 0 8px 40px rgba(0, 0, 0, 0.15); z-index: 999998; display: none; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.3); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } .novel-settings-panel.active { display: block; animation: fadeInUp 0.4s cubic-bezier(0.4, 0, 0.2, 1); } /* 面板头部 */ .novel-settings-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; font-size: 18px; font-weight: 600; letter-spacing: 1px; } /* 设置分块 */ .novel-settings-section { padding: 20px; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .novel-settings-section:last-child { border-bottom: none; } .novel-section-label { font-size: 14px; color: #667eea; margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px; } /* 导航按钮 */ .novel-nav-buttons { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; } .novel-nav-btn { padding: 12px; background: rgba(102, 126, 234, 0.1); border: 1px solid rgba(102, 126, 234, 0.2); border-radius: 12px; cursor: pointer; text-align: center; font-size: 14px; color: #667eea; transition: all 0.3s ease; font-weight: 500; } .novel-nav-btn:hover { background: rgba(102, 126, 234, 0.2); transform: translateY(-2px); } .novel-nav-btn:active { transform: translateY(0); } /* 设置项 */ .novel-setting-item { display: flex; justify-content: space-between; align-items: center; padding: 12px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .novel-setting-item:last-child { border-bottom: none; } .novel-setting-label { font-size: 14px; color: #333; display: flex; align-items: center; gap: 8px; } .novel-toggle { width: 50px; height: 28px; background: #e0e0e0; border-radius: 14px; position: relative; cursor: pointer; transition: background 0.3s ease; } .novel-toggle.active { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } .novel-toggle::after { content: ''; position: absolute; width: 24px; height: 24px; background: white; border-radius: 50%; top: 2px; left: 2px; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .novel-toggle.active::after { transform: translateX(22px); } /* 字体大小调节 */ .novel-font-controls { display: flex; align-items: center; gap: 15px; } .novel-font-btn { width: 36px; height: 36px; border: 1px solid rgba(102, 126, 234, 0.3); background: rgba(102, 126, 234, 0.1); border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; color: #667eea; transition: all 0.3s ease; } .novel-font-btn:hover { background: rgba(102, 126, 234, 0.2); transform: scale(1.1); } .novel-font-size { min-width: 40px; text-align: center; font-size: 16px; font-weight: 600; color: #667eea; } /* 夜间模式 */ .novel-dark-mode { background: rgba(30, 30, 40, 0.9); color: #e0e0e0; } .novel-dark-mode .novel-settings-section { border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .novel-dark-mode .novel-section-label { color: #a78bfa; } .novel-dark-mode .novel-nav-btn { background: rgba(167, 139, 250, 0.1); border-color: rgba(167, 139, 250, 0.2); color: #a78bfa; } .novel-dark-mode .novel-setting-label { color: #e0e0e0; } /* 动画 */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } /* 自动翻页指示器 */ .novel-scroll-indicator { position: fixed; bottom: 100px; right: 50%; transform: translateX(50%); background: rgba(102, 126, 234, 0.9); color: white; padding: 10px 20px; border-radius: 20px; font-size: 14px; display: none; z-index: 999997; backdrop-filter: blur(10px); box-shadow: 0 4px 20px rgba(102, 126, 234, 0.3); } .novel-scroll-indicator.active { display: block; animation: fadeInUp 0.3s ease; } /* 响应式 */ @media (max-width: 480px) { .novel-settings-panel { width: 280px; right: 20px; } .novel-float-btn { bottom: 20px; right: 20px; width: 50px; height: 50px; } } `); // 创建浮动按钮 const floatBtn = document.createElement('div'); floatBtn.className = 'novel-float-btn'; floatBtn.addEventListener('click', () => this.toggleSettings()); document.body.appendChild(floatBtn); // 创建设置面板 const panel = document.createElement('div'); panel.className = 'novel-settings-panel'; if (Settings.darkMode) { panel.classList.add('novel-dark-mode'); } panel.innerHTML = `