# 论坛油猴脚本-自用版

**URL:** <https://idcflare.com/t/topic/2265>\
**Category:** 运营\
**Tags:** 原创\
**Created:** [2025 年9 月 20 日 04:07 UTC](https://idcflare.com/t/topic/2265 "2025-09-20T04:07:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

作者： ![0x6](https://idcflare.com/letter_avatar/0x6/32/6_22734026db12803ebb3e059622ac3534.png) [@0x6](https://idcflare.com/u/0x6)\
发布日期： [2025 年9 月 20 日 04:07 UTC](https://idcflare.com/t/topic/2265/1 "2025-09-20T04:07:30Z")

</div>

分享一个自己使用的论坛脚本，功能不多（显示楼层、自动滚屏），同类型论坛通用

```js
// ==UserScript==
// @name Auto Reading
// @namespace http://tampermonkey.net/
// @version 2024-11-02
// @author 0x6
// @match https://linux.do/*
// @match https://idcflare.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=www.discourse.org/
// @grant GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    if (window.top !== window) {
        return;
    }

    const styles = `
    .topic-post {
        position: relative;
    }
    .topic-post:not(:first-child):before {
        position: absolute;
        top: 0;
        right: calc(100% - 1px);
        font-size: 13px;
        min-width: var(--d-main-content-gap);
        height: 2em;
        line-height: 2em;
        text-align: center;
        color: var(--primary-medium);
        border: 1px solid var(--content-border-color);
        content: attr(data-post-number) !important;
    }
    `

    if ('GM_addStyle' in window) {
        GM_addStyle(styles);
    } else {
        const style = document.createElement('style');
        style.textContent = styles;
        document.head.appendChild(style);
    }

    const AUTO_READ_INTERVAL_MIN = 500;
    const AUTO_READ_INTERVAL_MAX = 1000;
    const AUTO_READ_DISPLACEMENT_MIN = 100;
    const AUTO_READ_DISPLACEMENT_MAX = 180;
    const INITIAL_BUTTON_RIGHT = '20px';
    const INITIAL_BUTTON_BOTTOM = '100px';

    let reading = false;
    let dragging = false;

    let scrollTimeout;
    let lastScrollTop = window.pageYOffset;
    let startX, startY;

    const button = document.createElement('button');
    button.setAttribute('tabindex', '-1');

    const playIcon = `
  <svg width="20px" height="20px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M8 5v14l11-7L8 5z" fill="currentColor"/>
  </svg>`;
    const pauseIcon = `
  <svg width="20px" height="20px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" fill="currentColor"/>
  </svg>`;

    button.innerHTML = playIcon;

    Object.assign(button.style, {
        position: 'fixed',
        width: '38px',
        height: '38px',
        borderRadius: '50%',
        outline: 'none',
        background: 'linear-gradient(135deg, #6D5DFB, #8F6AF8)',
        color: '#fff',
        border: 'none',
        cursor: 'pointer',
        boxShadow: '0 4px 8px rgba(0, 0, 0, 0.3)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        transition: 'transform 0.2s ease, box-shadow 0.2s ease',
        zIndex: '1000'
    });

    const savedPosition = JSON.parse(localStorage.getItem('x-read-pos'));
    if (savedPosition) {
        button.style.left = savedPosition.left;
        button.style.top = savedPosition.top;
    } else {
        button.style.right = INITIAL_BUTTON_RIGHT;
        button.style.bottom = INITIAL_BUTTON_BOTTOM;
    }

    button.addEventListener('mouseenter', () => {
        button.style.transform = 'scale(1.1)';
        button.style.boxShadow = '0 8px 16px rgba(0, 0, 0, 0.4)';
    });

    button.addEventListener('mouseleave', () => {
        button.style.transform = 'scale(1)';
        button.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
    });

    function autoRead() {
        if (reading) {
            const dis = Math.floor(Math.random() * (AUTO_READ_DISPLACEMENT_MAX - AUTO_READ_DISPLACEMENT_MIN + 1)) + AUTO_READ_DISPLACEMENT_MIN;
            const interval = Math.floor(Math.random() * (AUTO_READ_INTERVAL_MAX - AUTO_READ_INTERVAL_MIN + 1)) + AUTO_READ_INTERVAL_MIN;
            window.scrollBy({ top: dis, left: 0, behavior: "smooth" });
            scrollTimeout = setTimeout(autoRead, interval);
        }
    }

    function toggleAutoRead() {
        reading = !reading;
        button.innerHTML = reading ? pauseIcon : playIcon;
        button.style.background = reading
            ? 'linear-gradient(135deg, #FF6B6B, #FF8A5B)'
            : 'linear-gradient(135deg, #6D5DFB, #8F6AF8)';
        if (reading) autoRead(); else clearTimeout(scrollTimeout);
    }

    window.addEventListener('scroll', () => {
        const currentScrollTop = window.pageYOffset;
        if (currentScrollTop < lastScrollTop && reading) toggleAutoRead();
        lastScrollTop = currentScrollTop;
    });

    button.addEventListener('pointerdown', (e) => {
        dragging = false;

        startX = e.clientX;
        startY = e.clientY;
        const offsetX = e.clientX - button.getBoundingClientRect().left;
        const offsetY = e.clientY - button.getBoundingClientRect().top;

        const pointerMoveHandler = (e) => {
            const dx = e.clientX - startX;
            const dy = e.clientY - startY;

            if (Math.abs(dx) > 1 || Math.abs(dy) > 1) {
                dragging = true;
                button.style.transition = 'none';
                button.style.left = `${e.clientX - offsetX}px`;
                button.style.top = `${e.clientY - offsetY}px`;
            }
        }

        const pointerUpHandler = () => {
            if (dragging) {
                const position = { left: button.style.left, top: button.style.top };
                localStorage.setItem('x-read-pos', JSON.stringify(position));
            }
            else {
                toggleAutoRead();
            }
            button.style.transition = 'transform 0.2s ease, box-shadow 0.2s ease';
            document.removeEventListener('pointermove', pointerMoveHandler);
            document.removeEventListener('pointerup', pointerUpHandler);
        }

        document.addEventListener('pointermove', pointerMoveHandler);
        document.addEventListener('pointerup', pointerUpHandler);
    });

    document.body.appendChild(button);
})();

```

---

<div class="post-metadata">

作者： ![crystalccc](https://idcflare.com/letter_avatar/crystalccc/32/6_22734026db12803ebb3e059622ac3534.png) [@crystalccc](https://idcflare.com/u/crystalccc)\
发布日期： [2025 年9 月 20 日 05:15 UTC](https://idcflare.com/t/topic/2265/2 "2025-09-20T05:15:09Z")

</div>

感谢分享

---

<div class="post-metadata">

作者： ![lao](https://idcflare.com/user_avatar/idcflare.com/lao/32/1464_2.png) [@lao](https://idcflare.com/u/lao)\
发布日期： [2025 年9 月 20 日 05:26 UTC](https://idcflare.com/t/topic/2265/3 "2025-09-20T05:26:21Z")

</div>

速度真快

---

<div class="post-metadata">

作者： ![utags](https://idcflare.com/user_avatar/idcflare.com/utags/32/2235_2.png) [@utags](https://idcflare.com/u/utags)\
发布日期： [2025 年9 月 20 日 09:09 UTC](https://idcflare.com/t/topic/2265/4 "2025-09-20T09:09:48Z")

</div>

动作好快啊 👍

---

<div class="post-metadata">

作者： ![WTO](https://idcflare.com/user_avatar/idcflare.com/wto/32/3678_2.png) [@WTO](https://idcflare.com/u/WTO)\
发布日期： [2025 年9 月 21 日 14:10 UTC](https://idcflare.com/t/topic/2265/6 "2025-09-21T14:10:07Z")

</div>

感谢佬友的分享。 🫰

---

<div class="post-metadata">

作者： ![xylon](https://idcflare.com/user_avatar/idcflare.com/xylon/32/321_2.png) [@xylon](https://idcflare.com/u/xylon)\
发布日期： [2025 年9 月 21 日 14:13 UTC](https://idcflare.com/t/topic/2265/7 "2025-09-21T14:13:30Z")

</div>

具体咋用？

---

<div class="post-metadata">

作者： ![touchcat](https://idcflare.com/letter_avatar/touchcat/32/6_22734026db12803ebb3e059622ac3534.png) [@touchcat](https://idcflare.com/u/touchcat)\
发布日期： [2025 年9 月 21 日 14:13 UTC](https://idcflare.com/t/topic/2265/8 "2025-09-21T14:13:40Z")

</div>

你这id很好记，前两天好像见过一个报错，我还问了ai

---

<div class="post-metadata">

作者： ![bai](https://idcflare.com/user_avatar/idcflare.com/bai/32/605_2.png) [@bai](https://idcflare.com/u/bai)\
发布日期： [2025 年9 月 21 日 14:15 UTC](https://idcflare.com/t/topic/2265/9 "2025-09-21T14:15:11Z")

</div>

感谢佬分享

---

<div class="post-metadata">

作者： ![iOS](https://idcflare.com/user_avatar/idcflare.com/ios/32/930_2.png) [@iOS](https://idcflare.com/u/iOS)\
发布日期： [2025 年9 月 21 日 14:15 UTC](https://idcflare.com/t/topic/2265/10 "2025-09-21T14:15:39Z")

</div>

感谢分享

---

<div class="post-metadata">

作者： ![OuO](https://idcflare.com/user_avatar/idcflare.com/ouo/32/1947_2.png) [@OuO](https://idcflare.com/u/OuO)\
发布日期： [2025 年9 月 21 日 14:31 UTC](https://idcflare.com/t/topic/2265/11 "2025-09-21T14:31:21Z")

</div>

感谢分享

---

<div class="post-metadata">

作者： ![Nutanix](https://idcflare.com/letter_avatar/nutanix/32/6_22734026db12803ebb3e059622ac3534.png) [@Nutanix](https://idcflare.com/u/Nutanix)\
发布日期： [2025 年9 月 21 日 14:34 UTC](https://idcflare.com/t/topic/2265/12 "2025-09-21T14:34:56Z")

</div>

大佬太强了👍，感谢分享

---

<div class="post-metadata">

作者： ![sum](https://idcflare.com/user_avatar/idcflare.com/sum/32/316_2.png) [@sum](https://idcflare.com/u/sum)\
发布日期： [2025 年9 月 21 日 15:13 UTC](https://idcflare.com/t/topic/2265/13 "2025-09-21T15:13:05Z")

</div>

感谢分享

---

<div class="post-metadata">

作者： ![yuyehd](https://idcflare.com/user_avatar/idcflare.com/yuyehd/32/1262_2.png) [@yuyehd](https://idcflare.com/u/yuyehd)\
发布日期： [2025 年9 月 22 日 05:40 UTC](https://idcflare.com/t/topic/2265/14 "2025-09-22T05:40:15Z")

</div>

> [!hint]  
> 感谢分享
> 
> > [!done]

---

<div class="post-metadata">

作者： ![ping](https://idcflare.com/user_avatar/idcflare.com/ping/32/4406_2.png) [@ping](https://idcflare.com/u/ping)\
发布日期： [2025 年9 月 23 日 09:44 UTC](https://idcflare.com/t/topic/2265/15 "2025-09-23T09:44:54Z")

</div>

感谢分享

---

<div class="post-metadata">

作者： ![skc](https://idcflare.com/user_avatar/idcflare.com/skc/32/7695_2.png) [@skc](https://idcflare.com/u/skc)\
发布日期： [2025 年9 月 23 日 09:54 UTC](https://idcflare.com/t/topic/2265/16 "2025-09-23T09:54:40Z")

</div>

多谢分享

---

<div class="post-metadata">

作者： ![Waylon](https://idcflare.com/letter_avatar/waylon/32/6_22734026db12803ebb3e059622ac3534.png) [@Waylon](https://idcflare.com/u/Waylon)\
发布日期： [2025 年9 月 23 日 09:55 UTC](https://idcflare.com/t/topic/2265/17 "2025-09-23T09:55:14Z")

</div>

L站的脚本也可以用

---

<div class="post-metadata">

作者： ![TIGA](https://idcflare.com/user_avatar/idcflare.com/tiga/32/8872_2.png) [@TIGA](https://idcflare.com/u/TIGA)\
发布日期： [2025 年9 月 24 日 00:06 UTC](https://idcflare.com/t/topic/2265/18 "2025-09-24T00:06:24Z")

</div>

太强了！！

---

<div class="post-metadata">

作者： ![arkham](https://idcflare.com/user_avatar/idcflare.com/arkham/32/9348_2.png) [@arkham](https://idcflare.com/u/arkham)\
发布日期： [2025 年9 月 24 日 03:02 UTC](https://idcflare.com/t/topic/2265/19 "2025-09-24T03:02:32Z")

</div>

😍佬哥太强了

---

<div class="post-metadata">

作者： ![kuraudowelle](https://idcflare.com/user_avatar/idcflare.com/kuraudowelle/32/7528_2.png) [@kuraudowelle](https://idcflare.com/u/kuraudowelle)\
发布日期： [2025 年9 月 24 日 03:05 UTC](https://idcflare.com/t/topic/2265/20 "2025-09-24T03:05:49Z")

</div>

感谢分享，话说这一类的论坛都不显示楼层，确实有点不太友好。按理讲应该是要显示的才对。

---

<div class="post-metadata">

作者： ![sparks](https://idcflare.com/user_avatar/idcflare.com/sparks/32/6561_2.png) [@sparks](https://idcflare.com/u/sparks)\
发布日期： [2025 年9 月 24 日 04:05 UTC](https://idcflare.com/t/topic/2265/21 "2025-09-24T04:05:34Z")

</div>

这里可以看

 ![image](https://idcflare.com/uploads/default/original/2X/8/89275b3c4136f2fed3fc6b9c71acf927b2c553e9.png)

[下一页](https://idcflare.com/t/topic/2265.md?page=2)
