自动滚动

给网页添加自动向上、向下滚动的按钮,对于看文章,看小说,看漫画等场景下使用极为舒适

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        自动滚动
// @author      Kaiter-Plus
// @description 给网页添加自动向上、向下滚动的按钮,对于看文章,看小说,看漫画等场景下使用极为舒适
// @namespace   https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/AutoScroll
// @include     *://*
// @grant       none
// @version     1.01
// @license     BSD-3-Clause
// @noframes
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_addElement
// ==/UserScript==
;(function () {
  'use strict'

  // 默认速度
  let defaultSpeed = 5
  // 定时器id
  let currentFrameId = 0
  // 记录上一次执行的时间
  let prevTIme = 0
  // 按下的位置
  const pressPosition = { top: 0, left: 0 }

  // 初始化速度
  const speed = GM_getValue('speed')
  speed ? (defaultSpeed = +speed) : GM_setValue('speed', defaultSpeed)

  // 创建一个滚动容器
  const scrollContainer = GM_addElement(document.body, 'div', {
    id: 'scroll-container',
    class: 'scroll-container'
  })
  scrollContainer.addEventListener('mousedown', press)

  // 创建自动向上的按钮
  const scrollUp = GM_addElement(scrollContainer, 'div', {
    id: 'scroll-up',
    class: 'scroll-up'
  })
  scrollUp.addEventListener('mouseover', () => {
    autoScroll(-1)
  })
  scrollUp.addEventListener('mouseout', stopScroll)

  // 创建速度显示
  const scrollSpeed = GM_addElement(scrollContainer, 'div', {
    id: 'scroll-speed',
    class: 'scroll-speed',
    textContent: speed
  })
  scrollSpeed.addEventListener('wheel', settingSpeed)

  // 创建自动向下的按钮
  const scrollDown = GM_addElement(scrollContainer, 'div', {
    id: 'scroll-down',
    class: 'scroll-down'
  })
  scrollDown.addEventListener('mouseover', () => {
    autoScroll(1)
  })
  scrollDown.addEventListener('mouseout', stopScroll)

  // 自动滚动
  function autoScroll(direction) {
    scroll(direction)
  }

  // 滚动
  function scroll(direction) {
    currentFrameId = window.requestAnimationFrame(time => {
      if (!prevTIme) prevTIme = time
      const elapsed = (time - prevTIme) / 1000
      // 每 50ms 执行一次
      window.scrollBy(0, defaultSpeed * 10 * direction * elapsed)
      prevTIme = time
      scroll(direction)
    })
  }

  // 停止滚动
  function stopScroll() {
    prevTIme = 0
    window.cancelAnimationFrame(currentFrameId)
  }

  // 设置滚动速度
  function settingSpeed(e) {
    e.preventDefault()
    if (e.deltaY < 0) defaultSpeed += 1
    else defaultSpeed -= 1
    scrollSpeed.textContent = defaultSpeed
    GM_setValue('speed', defaultSpeed)
  }

  // 按下事件
  function press(e) {
    // 设置只有在速度显示区域才能拖动
    if (e.target.id === 'scroll-speed') {
      // 记录位置
      pressPosition.top = e.clientY - e.currentTarget.offsetTop
      pressPosition.left = e.clientX - e.currentTarget.offsetLeft
      // 修改样式显示
      scrollSpeed.style.cursor = 'move'
      // 开始监听移动事件
      document.addEventListener('mousemove', move)
      document.addEventListener('mouseup', release)
    }
  }

  // 移动事件
  function move(e) {
    const top = e.clientY - pressPosition.top
    const left = e.clientX - pressPosition.left
    scrollContainer.style.right = `unset`
    scrollContainer.style.top = `${top}px`
    scrollContainer.style.left = `${left}px`
  }

  // 抬起事件
  function release(e) {
    // 修改样式显示
    scrollSpeed.style.cursor = 's-resize'
    // 清除事件
    document.removeEventListener('mousemove', move)
    document.removeEventListener('mouseup', release)
  }

  // 添加自定义样式
  GM_addStyle(`
    .scroll-container {
      position: fixed;
      top: 50%;
      right: 10px;
      z-index: 99999;
      text-align: center;
      transform: translateY(-50%);
      border-radius: 20px;
      overflow: hidden;
      background-color: rgba(204, 204, 204, 0.4);
      line-height: 40px;
      color: rgba(60, 60, 67, .92);
    }
    .scroll-up,
    .scroll-down {
      width: 40px;
      height: 40px;
      text-align: center;
    }
    .scroll-up::after,
    .scroll-down::after {
      content: '';
      display: inline-block;
      width: 16px;
      height: 16px;
      font-size: 16px;
      box-sizing: border-box;
      border-width: 2px;
      border-style: solid;
    }
    .scroll-up::after {
      transform: rotate(-45deg);
      border-color: rgba(60, 60, 67, .92) rgba(60, 60, 67, .92) transparent transparent;
      margin-top: 14.3425px;
    }
    .scroll-down::after {
      transform: rotate(-45deg);
      border-color: transparent transparent rgba(60, 60, 67, .92) rgba(60, 60, 67, .92);
      margin-top: 8.685px;
    }
    .scroll-up:hover,
    .scroll-down:hover {
      background-color: rgba(204, 204, 204, 0.8);
    }
    
    .scroll-speed {
      font-size: 18px;
      user-select: none;
      cursor: s-resize;
    }    
  `)
})()