// ==UserScript== // @name DeepSeek一键回顶 // @namespace https://scriptcat.org/zh-CN/users/214553 // @version 1.3.0 // @description 在DeepSeek网页上添加「回到顶部」按钮,一键回到对话的最开始。 // @author English3(Σπg|!εh๑๑๑) // @license MIT // @icon https://deepseek.com/favicon.ico // @match https://chat.deepseek.com/* // @run-at document-idle // @grant none // ==/UserScript== (() => { 'use strict'; const ID = 'ds-back-top-v5'; const goTop = () => { try { let bestEl = null; let maxScroll = 0; // 精准查找聊天滚动容器,不再全页暴力遍历 document.querySelectorAll('div, main').forEach(el => { const style = window.getComputedStyle(el); // 找出实际产生滚动且有高度的容器 if ((style.overflowY === 'auto' || style.overflowY === 'scroll') && el.scrollHeight > maxScroll && el.clientHeight > 100) { maxScroll = el.scrollHeight; bestEl = el; } }); if (bestEl) { bestEl.scrollTop = 0; } else { window.scrollTo(0, 0); document.documentElement.scrollTop = 0; document.body.scrollTop = 0; } } catch (e) { console.warn('回顶异常:', e); } }; // 创建按钮 const btn = document.createElement('button'); btn.id = ID; btn.type = 'button'; btn.title = '回到顶部'; btn.setAttribute('aria-label', '回到顶部'); btn.innerHTML = ` `; btn.onmouseenter = () => { if (btn.dataset.mode === 'pc') btn.style.opacity = '1'; }; btn.onmouseleave = () => { if (btn.dataset.mode === 'pc') btn.style.opacity = '0.8'; }; btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); goTop(); }); // 智能挂载与布局 const isMobile = () => window.innerWidth <= 768; const insertToMobileHeader = () => { const allBtns = Array.from(document.querySelectorAll('button, [role="button"]')); const W = window.innerWidth; const topRightBtns = allBtns.filter(b => { const r = b.getBoundingClientRect(); return r.top < 60 && r.left > W * 0.5 && r.width > 0 && b.id !== ID; }).sort((a, b) => a.getBoundingClientRect().left - b.getBoundingClientRect().left); if (topRightBtns.length > 0) { const shareBtn = topRightBtns[topRightBtns.length - 1]; const parent = shareBtn.parentElement; if (parent && (btn.parentElement !== parent || btn.nextElementSibling !== shareBtn)) { parent.insertBefore(btn, shareBtn); btn.dataset.mode = 'mobile'; // 手机端纯净无边框,只留箭头 Object.assign(btn.style, { position: 'relative', right: 'auto', bottom: 'auto', width: '32px', height: '32px', borderRadius: '0', background: 'none', border: 'none', outline: 'none', boxShadow: 'none', color: 'inherit', zIndex: 'auto', opacity: '1', margin: '0 4px', padding: '0', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: '0', transition: 'none' // 移除过渡,防止视觉残留 }); return true; } } return false; }; const setPcFloatingStyle = () => { btn.dataset.mode = 'pc'; Object.assign(btn.style, { position: 'fixed', right: '24px', bottom: '120px', width: '46px', height: '46px', borderRadius: '50%', background: 'rgba(0, 0, 0, 0.6)', color: '#ffffff', border: '2px solid rgba(255,255,255,0.2)', zIndex: '9999999', boxShadow: '0 4px 12px rgba(0,0,0,0.3)', opacity: '0.8', margin: '0', padding: '0', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'opacity 0.15s ease, transform 0.15s ease', cursor: 'pointer' }); }; const ensureMount = () => { if (!document.body) return; if (isMobile()) { if (btn.dataset.mode === 'mobile' && btn.parentElement && btn.parentElement.tagName !== 'BODY') return; if (!insertToMobileHeader()) { if (!btn.isConnected) document.body.appendChild(btn); setPcFloatingStyle(); } } else { if (!btn.isConnected) document.body.appendChild(btn); if (btn.dataset.mode !== 'pc') { setPcFloatingStyle(); } } }; // 启动 ensureMount(); // 防丢失轮询,避免因React重绘导致按钮被吃 setInterval(ensureMount, 1500); setTimeout(ensureMount, 500); setTimeout(ensureMount, 2000); })();