Scroll Button | by Solid | v3

Добавляет анимированную кнопку прокрутки вверх с настройками в меню LztScrollButton.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Scroll Button | by Solid | v3
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Добавляет анимированную кнопку прокрутки вверх с настройками в меню LztScrollButton.
// @author       solid
// @match        https://zelenka.guru/*
// @match        https://lolz.guru/*
// @match        https://lolz.live/*
// @match        https://lzt.market/*
// @icon         https://i.ibb.co/qMy4vtTK/solid-tampermonkey.png
// @grant        none
// @run-at       document-start
// ==/UserScript==
(function() {
    'use strict';
 
    let isVisible = false;
    let lastScrollTop = 0;
    let settings = JSON.parse(localStorage.getItem('LztScrollButtonSettings')) || {
        isCustomScrollEnabled: true,
        hideDefaultScroll: true,
        position: 'bottom-right',
        customPosition: null
    };
    let tempSettings = { ...settings };
    let isDragging = false;
 
    const customButton = document.createElement('div');
    Object.assign(customButton.style, {
        position: 'fixed',
        bottom: '15px',
        right: '15px',
        width: '60px',
        height: '60px',
        backgroundColor: 'rgb(34, 142, 93)',
        borderRadius: '50%',
        textAlign: 'center',
        cursor: 'pointer',
        zIndex: '9999',
        opacity: '0',
        transition: 'opacity 0.2s ease-in-out, background-color 0.2s ease-in-out',
        visibility: 'hidden'
    });
 
    // Медиа-запрос для скрытия кнопки при ширине экрана < 1260px
    const mediaQuery = window.matchMedia('(max-width: 1260px)');
    const handleMediaQuery = (e) => {
        customButton.style.display = e.matches ? 'none' : 'block';
    };
    mediaQuery.addEventListener('change', handleMediaQuery);
    handleMediaQuery(mediaQuery);
 
    const arrowIcon = document.createElement('i');
    arrowIcon.className = 'fas fa-arrow-up';
    arrowIcon.style.cssText = `
        font-family: 'Font Awesome 5 Pro';
        font-weight: 600;
        color: rgb(39, 39, 39);
        font-size: 30px;
        line-height: 60px;
    `;
    customButton.appendChild(arrowIcon);
 
    const updateButtonPosition = () => {
        if (isDragging) return;
 
        const navHeight = document.querySelector('#navigation')?.offsetHeight || 0;
        const headerHeight = document.querySelector('.Market_Up_Header')?.offsetHeight || 0;
        const offset = 15;
 
        if (settings.position === 'custom' && settings.customPosition) {
            customButton.style.left = `${settings.customPosition.x}px`;
            customButton.style.top = `${settings.customPosition.y}px`;
            customButton.style.right = 'auto';
            customButton.style.bottom = 'auto';
        } else {
            switch (settings.position) {
                case 'bottom-right':
                    customButton.style.right = `${offset}px`;
                    customButton.style.bottom = `${offset}px`;
                    customButton.style.left = 'auto';
                    customButton.style.top = 'auto';
                    break;
                case 'middle-right':
                    customButton.style.right = `${offset}px`;
                    customButton.style.top = `calc(50% - 30px)`;
                    customButton.style.bottom = 'auto';
                    customButton.style.left = 'auto';
                    break;
                case 'top-right':
                    customButton.style.right = `${offset}px`;
                    customButton.style.top = `${navHeight + headerHeight + offset}px`;
                    customButton.style.bottom = 'auto';
                    customButton.style.left = 'auto';
                    break;
                case 'bottom-left':
                    customButton.style.left = `${offset}px`;
                    customButton.style.bottom = `${offset}px`;
                    customButton.style.right = 'auto';
                    customButton.style.top = 'auto';
                    break;
                case 'middle-left':
                    customButton.style.left = `${offset}px`;
                    customButton.style.top = `calc(50% - 30px)`;
                    customButton.style.bottom = 'auto';
                    customButton.style.right = 'auto';
                    break;
                case 'top-left':
                    customButton.style.left = `${offset}px`;
                    customButton.style.top = `${navHeight + headerHeight + offset}px`;
                    customButton.style.bottom = 'auto';
                    customButton.style.right = 'auto';
                    break;
            }
        }
    };
 
    const saveSettings = () => {
        settings = { ...tempSettings };
        localStorage.setItem('LztScrollButtonSettings', JSON.stringify(settings));
        updateButtonPosition();
        hideDefaultButton();
        if (!settings.isCustomScrollEnabled && isVisible) {
            customButton.style.opacity = '0';
            setTimeout(() => {
                customButton.style.visibility = 'hidden';
                isVisible = false;
            }, 200);
        } else if (settings.isCustomScrollEnabled && window.pageYOffset > 0) {
            showButton();
        }
    };
 
    const hideDefaultButton = () => {
        const defaultButton = document.querySelector('.cd-top');
        if (defaultButton) defaultButton.style.display = settings.hideDefaultScroll ? 'none' : 'block';
    };
 
    customButton.addEventListener('mouseenter', () => {
        if (!isDragging) customButton.style.backgroundColor = 'rgb(30, 125, 82)';
    });
 
    customButton.addEventListener('mouseleave', () => {
        if (!isDragging) customButton.style.backgroundColor = 'rgb(34, 142, 93)';
    });
 
    const showButton = () => {
        if (settings.isCustomScrollEnabled && !isVisible) {
            customButton.style.visibility = 'visible';
            customButton.style.opacity = '1';
            isVisible = true;
        }
    };
 
    const hideButton = () => {
        if (!window.pageYOffset) {
            customButton.style.opacity = '0';
            setTimeout(() => {
                if (!window.pageYOffset) {
                    customButton.style.visibility = 'hidden';
                    isVisible = false;
                } else {
                    customButton.style.opacity = '1';
                }
            }, 200);
        }
    };
 
    customButton.addEventListener('click', (e) => {
        if (!isDragging) {
            e.preventDefault();
            const $ = window.jQuery || window.$;
            if ($) {
                $('html, body').animate({ scrollTop: 0 }, 500, () => {
                    hideButton();
                });
            } else {
                window.scrollTo({ top: 0, behavior: 'smooth' });
                setTimeout(hideButton, 500);
            }
        }
    });
 
    const handleScroll = () => {
        const currentScrollTop = window.pageYOffset;
        if (currentScrollTop > lastScrollTop && currentScrollTop > 50) {
            showButton();
        } else if (!currentScrollTop) {
            hideButton();
        }
        lastScrollTop = currentScrollTop;
    };
 
    window.addEventListener('scroll', handleScroll, { passive: true });
    window.addEventListener('resize', () => {
        updateButtonPosition();
        if (window.pageYOffset > 0) showButton();
    }, { passive: true });
 
    const init = () => {
        document.body.appendChild(customButton);
        hideDefaultButton();
        updateButtonPosition();
        if (window.pageYOffset > 0) showButton();
        lastScrollTop = window.pageYOffset;
 
        const accountMenu = document.getElementById('AccountMenu');
        if (accountMenu) {
            const profileSettingsLi = accountMenu.querySelector('a[href="account/personal-details"]').parentElement;
            const scrollButtonLi = document.createElement('li');
            scrollButtonLi.innerHTML = '<a href="#" class="scrollSettingsTrigger">Кнопка прокрутки</a>';
            profileSettingsLi.insertAdjacentElement('afterend', scrollButtonLi);
 
            const overlay = document.createElement('div');
            overlay.id = 'overlay_lzt_scroll';
            overlay.style.cssText = `
                background-color: rgba(0, 0, 0, 0.7);
                z-index: 10001;
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                display: none;
            `;
            document.body.appendChild(overlay);
 
            const menu = document.createElement('div');
            menu.className = 'LztScrollButtonMenu';
            menu.style.cssText = `
                text-align: center;
                position: fixed;
                top: 50%;
                left: 50%;
                z-index: 10002;
                transform: translate(-50%, -50%);
                background-color: #272727;
                padding: 20px;
                border-radius: 10px;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
                display: none;
                color: #e4e4e4;
                font-family: Arial, sans-serif;
            `;
            menu.innerHTML = `
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                    <div style="font-size: 14px;">LztScrollButton</div>
                    <div class="closeButton" style="cursor: pointer; font-size: 18px;">✖</div>
                </div>
                <div style="margin-bottom: 15px;">
                    <label style="display: block; margin-bottom: 5px;">Расположение:</label>
                    <select id="scrollPosition" style="width: 100%; padding: 5px; background: #333; color: #e4e4e4; border: 1px solid #555; border-radius: 5px;">
                        <option value="bottom-right" ${tempSettings.position === 'bottom-right' ? 'selected' : ''}>Справа внизу</option>
                        <option value="middle-right" ${tempSettings.position === 'middle-right' ? 'selected' : ''}>Справа посередине</option>
                        <option value="top-right" ${tempSettings.position === 'top-right' ? 'selected' : ''}>Справа вверху</option>
                        <option value="bottom-left" ${tempSettings.position === 'bottom-left' ? 'selected' : ''}>Слева внизу</option>
                        <option value="middle-left" ${tempSettings.position === 'middle-left' ? 'selected' : ''}>Слева посередине</option>
                        <option value="top-left" ${tempSettings.position === 'top-left' ? 'selected' : ''}>Слева вверху</option>
                        <option value="custom" ${tempSettings.position === 'custom' ? 'selected' : ''}>Своё расположение</option>
                    </select>
                </div>
                <div style="margin-bottom: 15px;">
                    <label style="display: block; margin-bottom: 5px;">
                        <input type="checkbox" id="hideDefaultScroll" ${tempSettings.hideDefaultScroll ? 'checked' : ''} style="vertical-align: middle; margin-right: 5px;"> Скрыть стандартную кнопку
                    </label>
                    <label style="display: block;">
                        <input type="checkbox" id="enableCustomScroll" ${tempSettings.isCustomScrollEnabled ? 'checked' : ''} style="vertical-align: middle; margin-right: 5px;"> Включить кастомную кнопку
                    </label>
                </div>
                <div id="saveSettings" style="cursor: pointer; margin-top: 20px; padding: 8px; background: #228e5d; color: #fff; border-radius: 5px; text-align: center;">Сохранить</div>
            `;
            document.body.appendChild(menu);
 
            const dragControls = document.createElement('div');
            dragControls.style.cssText = `
                position: fixed;
                bottom: 20px;
                left: 50%;
                transform: translateX(-50%);
                z-index: 10003;
                display: none;
            `;
            dragControls.innerHTML = `
                <button id="saveDrag" style="padding: 8px 16px; background: #228e5d; color: #fff; border: none; border-radius: 5px; cursor: pointer; margin-right: 10px;">Сохранить</button>
                <button id="cancelDrag" style="padding: 8px 16px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;">Отменить</button>
            `;
            document.body.appendChild(dragControls);
 
            const openMenu = () => {
                tempSettings = { ...settings };
                overlay.style.display = 'block';
                menu.style.display = 'block';
                accountMenu.style.display = 'none';
                isDragging = false;
            };
 
            const closeMenu = () => {
                overlay.style.display = 'none';
                menu.style.display = 'none';
                dragControls.style.display = 'none';
                customButton.style.cursor = 'pointer';
                customButton.style.opacity = isVisible ? '1' : '0';
                customButton.style.zIndex = '9999';
                customButton.style.visibility = isVisible ? 'visible' : 'hidden';
                updateButtonPosition();
                isDragging = false;
                customButton.onmousedown = null; // Сбрасываем перетаскивание
            };
 
            scrollButtonLi.querySelector('.scrollSettingsTrigger').addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                openMenu();
            });
 
            menu.querySelector('.closeButton').addEventListener('click', closeMenu);
            overlay.addEventListener('click', (e) => {
                if (!isDragging) closeMenu();
            });
 
            document.getElementById('scrollPosition').addEventListener('change', (e) => {
                tempSettings.position = e.target.value;
                if (e.target.value === 'custom') {
                    menu.style.display = 'none';
                    customButton.style.zIndex = '10003';
                    customButton.style.opacity = '1';
                    customButton.style.visibility = 'visible';
                    customButton.style.left = '50%';
                    customButton.style.top = '50%';
                    customButton.style.transform = 'translate(-50%, -50%)';
                    customButton.style.cursor = 'grab';
                    dragControls.style.display = 'block';
                    isDragging = true;
                    makeDraggable(customButton);
                } else {
                    dragControls.style.display = 'none';
                    customButton.style.cursor = 'pointer';
                    customButton.style.transform = 'none';
                    isDragging = false;
                    customButton.onmousedown = null; // Сбрасываем перетаскивание
                    updateButtonPosition();
                }
            });
 
            document.getElementById('hideDefaultScroll').addEventListener('change', (e) => {
                tempSettings.hideDefaultScroll = e.target.checked;
            });
 
            document.getElementById('enableCustomScroll').addEventListener('change', (e) => {
                tempSettings.isCustomScrollEnabled = e.target.checked;
            });
 
            document.getElementById('saveSettings').addEventListener('click', () => {
                saveSettings();
                closeMenu();
            });
 
            function makeDraggable(element) {
                let offsetX = 0, offsetY = 0;
                element.onmousedown = dragMouseDown;
 
                function dragMouseDown(e) {
                    e.preventDefault();
                    offsetX = e.clientX - element.offsetLeft;
                    offsetY = e.clientY - element.offsetTop;
                    document.onmouseup = closeDragElement;
                    document.onmousemove = elementDrag;
                    element.style.cursor = 'grabbing';
                }
 
                function elementDrag(e) {
                    e.preventDefault();
                    let newLeft = e.clientX - offsetX;
                    let newTop = e.clientY - offsetY;
                    newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - element.offsetWidth));
                    newTop = Math.max(0, Math.min(newTop, window.innerHeight - element.offsetHeight));
                    element.style.left = `${newLeft}px`;
                    element.style.top = `${newTop}px`;
                    element.style.transform = 'none';
                }
 
                function closeDragElement() {
                    document.onmouseup = null;
                    document.onmousemove = null;
                    element.style.cursor = 'grab';
                }
            }
 
            document.getElementById('saveDrag').addEventListener('click', () => {
                tempSettings.position = 'custom';
                tempSettings.customPosition = {
                    x: parseInt(customButton.style.left),
                    y: parseInt(customButton.style.top)
                };
                saveSettings();
                customButton.onmousedown = null; // Делаем кнопку неперетаскиваемой
                closeMenu();
            });
 
            document.getElementById('cancelDrag').addEventListener('click', () => {
                tempSettings.position = settings.position;
                tempSettings.customPosition = settings.customPosition;
                customButton.onmousedown = null; // Сбрасываем перетаскивание
                closeMenu();
            });
        }
    };
 
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
 
    const observer = new MutationObserver(() => {
        hideDefaultButton();
        updateButtonPosition();
        if (window.pageYOffset > 0 && !isVisible) showButton();
    });
 
    document.addEventListener('DOMContentLoaded', () => {
        observer.observe(document.body, { childList: true, subtree: true });
    });
})();