论坛油猴脚本-自用版

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

// ==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);
})();
34 个赞

感谢分享

2 个赞

速度真快

动作好快啊 :+1:

感谢佬友的分享。 :hand_with_index_finger_and_thumb_crossed:

具体咋用?

1 个赞

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

感谢佬分享

感谢分享

感谢分享

大佬太强了:+1:,感谢分享

感谢分享

[!hint]
感谢分享

[!done]

1 个赞

感谢分享

1 个赞

多谢分享

1 个赞

L站的脚本也可以用

太强了!!

1 个赞

:heart_eyes:佬哥太强了

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

1 个赞

这里可以看

1 个赞