Back to top

scroll to top

当前为 2020-06-20 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Back to top
  3. // @namespace cyyyu
  4. // @version 0.3
  5. // @description scroll to top
  6. // @author Chuang Yu
  7. // @match https://*/*
  8. // @grant none
  9. // @run-at document-end
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. /* written in es5 */
  16.  
  17. var rootNode = document.querySelector("html")
  18. var prevLocations = new Map() // node: number
  19. var timers = new Map() // node: number
  20. var backToPrevLocationDelay = 10000 // 10s
  21.  
  22. rootNode.addEventListener("dblclick", function (evt) {
  23. var path = evt.path
  24.  
  25. for (var i = 0; i < path.length; i++) {
  26. var node = path[i]
  27. if (!isScrollable(node)) continue;
  28. if (!evt.altKey) return
  29.  
  30. if (!isAtTop(node)) {
  31. clearTimeout(timers.get(node))
  32. scrollTo(node, 0)
  33. } else if (prevLocations.has(node)) {
  34. scrollTo(node, prevLocations.get(node))
  35. }
  36. }
  37. })
  38.  
  39. function isAtTop(node) {
  40. return node.scrollTop === 0
  41. }
  42.  
  43. function scrollTo(node, top) {
  44. var prevScrollBehavior = node.style.scrollBehavior
  45. var prevLocation = node.scrollTop
  46.  
  47. node.style.scrollBehavior = "smooth"
  48. node.scrollTop = top
  49. node.style.scrollBehavior = prevScrollBehavior
  50.  
  51. if (top === 0) {
  52. prevLocations.set(node, prevLocation)
  53. var timer = setTimeout(
  54. function () { prevLocations.delete(node) },
  55. backToPrevLocationDelay
  56. )
  57. timers.set(node, timer)
  58. }
  59. }
  60.  
  61. function isScrollable(node) {
  62. return (
  63. (node.scrollHeight - node.clientHeight > 100) &&
  64. (node.clientHeight > 50)
  65. )
  66. }
  67.  
  68. })();