您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The “↑” button next to Copy/Edit scrolls only large messages (>=700 characters) to their top, aligned per message; supports both user and assistant.
// ==UserScript== // @name GPT Message Top Scroll // @namespace https://greasyfork.org/users/your-id-or-homepage // @version 1.3 // @description The “↑” button next to Copy/Edit scrolls only large messages (>=700 characters) to their top, aligned per message; supports both user and assistant. // @author Madhuvrata // @match https://chatgpt.com/* // @grant none // @run-at document-end // @license MIT // ==/UserScript== (() => { 'use strict'; // CSS const style = document.createElement('style'); style.textContent = ` .tm-scroll-top-btn { width: 32px!important; height: 32px!important; margin: 0 4px!important; background: rgba(0,0,0,0.05)!important; border: 1px solid rgba(0,0,0,0.1)!important; border-radius: 6px!important; display: inline-flex!important; align-items: center!important; justify-content: center!important; cursor: pointer!important; opacity: .7!important; transition: opacity .2s, background .2s; pointer-events: auto!important; } .tm-scroll-top-btn:hover { opacity: 1!important; background: rgba(0,0,0,0.1)!important; } .tm-force-panel { opacity: 1!important; pointer-events: auto!important; mask-image: none!important; -webkit-mask-image: none!important; } `; document.head.appendChild(style); const svgArrow = ` <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"> <path d="M10 4l-6 6h4v6h4v-6h4l-6-6z"/> </svg>`; // панель кнопок для user и assistant const PANEL_SELECTOR = ` article[data-testid^="conversation-turn-"] .flex.justify-end, article[data-testid^="conversation-turn-"] .flex.justify-start `.trim().replace(/\s+/g,' '); function injectButtons() { document.querySelectorAll(PANEL_SELECTOR).forEach(panel => { panel.classList.add('tm-force-panel'); const inner = panel.querySelector(':scope > div'); if (!inner || inner.querySelector('.tm-scroll-top-btn')) return; inner.classList.add('tm-force-panel'); // найдём связанный article и контейнер markdown const article = panel.closest('article[data-testid^="conversation-turn-"]'); if (!article) return; const md = article.querySelector('.markdown') || article; // длина текста const txtLen = (md.innerText || '').length; // создаём кнопку const btn = document.createElement('button'); btn.className = 'tm-scroll-top-btn'; btn.innerHTML = svgArrow; btn.title = 'Scroll message to top'; btn.addEventListener('click', e => { e.stopPropagation(); // если короткое сообщение — игнорируем if (txtLen < 700) return; article.scrollIntoView({ behavior: 'smooth', block: 'start' }); }); inner.appendChild(btn); }); } injectButtons(); new MutationObserver(injectButtons) .observe(document.body, { childList: true, subtree: true }); })();