您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Redirects PageUp and PageDown keys to scroll the conversation window while typing in the input field.
- // ==UserScript==
- // @name Fix PageUp and PageDown scrolling for ChatGPT
- // @description Redirects PageUp and PageDown keys to scroll the conversation window while typing in the input field.
- // @author NWP/DEVULSKY
- // @namespace https://greasyfork.org/en/scripts/519486/
- // @version 0.3
- // @license MIT
- // @match https://chat.openai.com/*
- // @match https://chatgpt.com/*
- // @grant none
- //
- // ==/UserScript==
- (function () {
- 'use strict';
- /**
- * Finds the scrollable container of the conversation window.
- * Falls back to a dynamic class-based selector if a specific container ID is not found.
- * @returns {HTMLElement|null} The scrollable container element, or null if not found.
- */
- const getScrollableContainer = () =>
- document.querySelector('#conversation-inner-div') ||
- Array.from(document.querySelectorAll('div')).find(div => /^react-scroll-to-bottom--css-\S+$/.test(div.className));
- /**
- * Checks if an element has `overflow: hidden`.
- * @param {HTMLElement} element - The element to check.
- * @returns {boolean} True if `overflow` is `hidden`, false otherwise.
- */
- const hasOverflowHidden = (element) => {
- if(!element) return false;
- const style = getComputedStyle(element);
- return style && style.overflow === 'hidden';
- };
- /**
- * Smoothly scrolls the container over a period of time.
- * @param {HTMLElement} container - The scrollable container.
- * @param {number} targetPosition - The target scroll position.
- * @param {number} duration - The duration of the scroll animation.
- */
- const smoothScroll = (container, targetPosition, duration) => {
- const startPosition = container.scrollTop;
- const distance = targetPosition - startPosition;
- let startTime = null;
- // Animation function that runs on each frame
- const animateScroll = (currentTime) => {
- if (!startTime) startTime = currentTime;
- const timeElapsed = currentTime - startTime;
- const progress = Math.min(timeElapsed / duration, 1); // Ensure progress is capped at 1
- // Apply the easing function
- container.scrollTop = startPosition + distance * progress;
- if (timeElapsed < duration) {
- requestAnimationFrame(animateScroll); // Continue the animation until duration is reached
- }
- };
- // Start the smooth scrolling animation
- requestAnimationFrame(animateScroll);
- };
- /**
- * Handles the PageUp and PageDown key events.
- * Prevents the default browser behavior and scrolls the conversation window instead.
- * @param {KeyboardEvent} event - The keydown event triggered by the user.
- */
- const handlePageKeys = (event) => {
- if (!['PageUp', 'PageDown'].includes(event.key)) return;
- const scrollableContainer = getScrollableContainer();
- if (!scrollableContainer) return;
- // Add this part
- if (hasOverflowHidden(scrollableContainer)) {
- scrollableContainer.style.overflow = 'visible';
- }
- event.preventDefault();
- const scrollFactor = event.key === 'PageUp' ? -0.75 : 0.75;
- const targetScrollPosition = scrollableContainer.scrollTop + (scrollableContainer.clientHeight * scrollFactor);
- smoothScroll(scrollableContainer, targetScrollPosition, 400);
- };
- document.addEventListener('keydown', handlePageKeys);
- })();