jupyter notebook auto scroll

Add auto scroll to bottom feature for jupyter notebook pages.

  1. // ==UserScript==
  2. // @name jupyter notebook auto scroll
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Add auto scroll to bottom feature for jupyter notebook pages.
  6. // @author Scruel Tao
  7. // @homepage https://github.com/scruel/tampermonkey-scripts/blob/main/jupyter-notebook-auto-scroll.js
  8. // @match http*://*/notebook*/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. "use strict";
  14.  
  15. var scrollDelay = 100;
  16. var defalutEnabled = true;
  17.  
  18. var scrollEleIndex = 1;
  19. // To store the last scroll height attr of element.
  20. // If disable, set to -1.
  21. var scrollEleIndexMap = new Map();
  22.  
  23. var lastScrollMap = new Map();
  24. var lastScrollTimekey = null;
  25.  
  26. document.querySelectorAll(".output_scroll").forEach((e) => {
  27. e.scrollTop = e.scrollHeight;
  28. });
  29.  
  30. function callScrollToBottom() {
  31. setTimeout(scrollToBottom, scrollDelay);
  32. }
  33.  
  34. function scrollMonitor(event) {
  35. // Sometimes, the user needs to check the output. For output elements that have already scrolled
  36. // to the bottom, user typically will try to scroll up continuously on the output element, however
  37. // this operation will be failed if the auto-scroll feature is enabled, and they would have to
  38. // manually disable this feature before performing the upward scrolling. This function is mean to
  39. // make it more convenient: if the user attempts multiple upward scrolls, it will automatically
  40. // disable the auto-scroll feature to prevent the "meaningless scolling operations".
  41. var currentIndex = event.target.getAttribute("scroll_checkbox_index");
  42. if (!currentIndex) {
  43. return;
  44. }
  45. currentIndex = parseInt(currentIndex);
  46. const scrollHeight = scrollEleIndexMap.get(currentIndex);
  47. if (scrollHeight != -1) {
  48. const now = new Date();
  49. const timekey = `${now.getHours()}_${now.getMinutes()}`;
  50. // Only consider events within one minutes
  51. if (lastScrollTimekey != timekey) {
  52. lastScrollTimekey = timekey;
  53. lastScrollMap.clear();
  54. }
  55. const key = `${currentIndex}_${timekey}`;
  56. if (!lastScrollMap.has(key)) {
  57. lastScrollMap.set(key, 0);
  58. }
  59.  
  60. if (scrollHeight - (event.target.scrollTop + event.target.clientHeight) > 0) {
  61. lastScrollMap.set(key, lastScrollMap.get(key) + 1);
  62. }
  63. if (lastScrollMap.get(key) > 7) {
  64. // Disable auto scroll via click checkbox
  65. document.querySelector(`input[scroll_checkbox_index="${currentIndex}"]`).click();
  66. lastScrollMap.clear();
  67. }
  68. }
  69. }
  70.  
  71. function createCheckboxDiv(ele, currentIndex) {
  72. var div = document.createElement("div");
  73. var checkbox = document.createElement("input");
  74. checkbox.type = "checkbox";
  75. if (defalutEnabled) {
  76. checkbox.checked = "checked";
  77. scrollEleIndexMap.set(currentIndex, ele.scrollHeight);
  78. }
  79. checkbox.setAttribute("scroll_checkbox_index", currentIndex);
  80. checkbox.onclick = function () {
  81. if (checkbox.checked) {
  82. scrollEleIndexMap.set(currentIndex, ele.scrollHeight);
  83. } else {
  84. scrollEleIndexMap.set(currentIndex, -1);
  85. }
  86. };
  87. div.append("Auto Scroll: ");
  88. div.append(checkbox);
  89. return div;
  90. }
  91.  
  92. function scrollToBottom() {
  93. const outputEles = document.querySelectorAll(".output_scroll");
  94. outputEles.forEach((ele) => {
  95. var currentIndex = ele.getAttribute("scroll_checkbox_index");
  96. if (!currentIndex) {
  97. currentIndex = scrollEleIndex++;
  98. ele.setAttribute("scroll_checkbox_index", currentIndex);
  99. const checkboxDiv = createCheckboxDiv(ele, currentIndex);
  100. ele.parentElement.before(checkboxDiv);
  101. ele.addEventListener("scrollend", scrollMonitor);
  102. } else {
  103. currentIndex = parseInt(currentIndex);
  104. }
  105. var autoScroll = scrollEleIndexMap.get(currentIndex) != -1;
  106. if (autoScroll) {
  107. ele.scrollTop = ele.scrollHeight;
  108. }
  109. });
  110. callScrollToBottom();
  111. }
  112.  
  113. scrollToBottom();
  114. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址