🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

jupyter notebook auto scroll

Add auto scroll to bottom feature for jupyter notebook pages.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         jupyter notebook auto scroll
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Add auto scroll to bottom feature for jupyter notebook pages.
// @author       Scruel Tao
// @homepage     https://github.com/scruel/tampermonkey-scripts/blob/main/jupyter-notebook-auto-scroll.js
// @match        http*://*/notebook*/*
// @grant        none
// ==/UserScript==

(function () {
    "use strict";

    var scrollDelay = 100;
    var defalutEnabled = true;

    var scrollEleIndex = 1;
    // To store the last scroll height attr of element.
    // If disable, set to -1.
    var scrollEleIndexMap = new Map();

    var lastScrollMap = new Map();
    var lastScrollTimekey = null;

    document.querySelectorAll(".output_scroll").forEach((e) => {
        e.scrollTop = e.scrollHeight;
    });

    function callScrollToBottom() {
        setTimeout(scrollToBottom, scrollDelay);
    }

    function scrollMonitor(event) {
        // Sometimes, the user needs to check the output. For output elements that have already scrolled
        // to the bottom, user typically will try to scroll up continuously on the output element, however
        // this operation will be failed if the auto-scroll feature is enabled, and they would have to
        // manually disable this feature before performing the upward scrolling. This function is mean to
        // make it more convenient: if the user attempts multiple upward scrolls, it will automatically
        // disable the auto-scroll feature to prevent the "meaningless scolling operations".
        var currentIndex = event.target.getAttribute("scroll_checkbox_index");
        if (!currentIndex) {
            return;
        }
        currentIndex = parseInt(currentIndex);
        const scrollHeight = scrollEleIndexMap.get(currentIndex);
        if (scrollHeight != -1) {
            const now = new Date();
            const timekey = `${now.getHours()}_${now.getMinutes()}`;
            // Only consider events within one minutes
            if (lastScrollTimekey != timekey) {
                lastScrollTimekey = timekey;
                lastScrollMap.clear();
            }
            const key = `${currentIndex}_${timekey}`;
            if (!lastScrollMap.has(key)) {
                lastScrollMap.set(key, 0);
            }

            if (scrollHeight - (event.target.scrollTop + event.target.clientHeight) > 0) {
                lastScrollMap.set(key, lastScrollMap.get(key) + 1);
            }
            if (lastScrollMap.get(key) > 7) {
                // Disable auto scroll via click checkbox
                document.querySelector(`input[scroll_checkbox_index="${currentIndex}"]`).click();
                lastScrollMap.clear();
            }
        }
    }

    function createCheckboxDiv(ele, currentIndex) {
        var div = document.createElement("div");
        var checkbox = document.createElement("input");
        checkbox.type = "checkbox";
        if (defalutEnabled) {
            checkbox.checked = "checked";
            scrollEleIndexMap.set(currentIndex, ele.scrollHeight);
        }
        checkbox.setAttribute("scroll_checkbox_index", currentIndex);
        checkbox.onclick = function () {
            if (checkbox.checked) {
                scrollEleIndexMap.set(currentIndex, ele.scrollHeight);
            } else {
                scrollEleIndexMap.set(currentIndex, -1);
            }
        };
        div.append("Auto Scroll: ");
        div.append(checkbox);
        return div;
    }

    function scrollToBottom() {
        const outputEles = document.querySelectorAll(".output_scroll");
        outputEles.forEach((ele) => {
            var currentIndex = ele.getAttribute("scroll_checkbox_index");
            if (!currentIndex) {
                currentIndex = scrollEleIndex++;
                ele.setAttribute("scroll_checkbox_index", currentIndex);
                const checkboxDiv = createCheckboxDiv(ele, currentIndex);
                ele.parentElement.before(checkboxDiv);
                ele.addEventListener("scrollend", scrollMonitor);
            } else {
                currentIndex = parseInt(currentIndex);
            }
            var autoScroll = scrollEleIndexMap.get(currentIndex) != -1;
            if (autoScroll) {
                ele.scrollTop = ele.scrollHeight;
            }
        });
        callScrollToBottom();
    }

    scrollToBottom();
})();