Пример JavaScript-кода для замены стандартного скроллбара на кастомный. В этом примере "капелька" для прокрутки представляет собой круг, а полоса бара — тонкая линия.

Пример кода:


    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Custom Scrollbar</title>
    <style>
        /* Основные стили для контейнера */
        .scroll-container {
            width: 300px;
            height: 400px;
            overflow: hidden;
            position: relative;
            border: 1px solid #ccc;
            margin-bottom: 20px;
        }

        /* Контент, который скроллится */
        .scroll-content {
            width: calc(100% - 30px); /* Уменьшаем ширину на 30px */
            height: 100%;
            overflow: auto;
            scrollbar-width: none; /* Убираем стандартный скроллбар в Firefox */
            -ms-overflow-style: none; /* Убираем стандартный скроллбар в IE */
            padding-right: 10px; /* Небольшой отступ внутри текста */
        }
        .scroll-content::-webkit-scrollbar {
            display: none; /* Убираем стандартный скроллбар в Chrome/Safari */
        }

        /* Полоса прокрутки */
        .scroll-bar {
            position: absolute;
            top: 0;
            right: 5px;
            width: 1px;
            height: 100%;
            background: #ccc;
        }

        /* Капелька прокрутки */
        .scroll-thumb {
            position: absolute;
            top: 0;
            right: -2px;
            width: 6px;
            height: 6px;
            background: #007bff;
            border-radius: 50%;
            cursor: pointer;
        }
    </style>

    <div class="scroll-container">
        <div class="scroll-content">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
            <p>... (много текста) ...</p>
        </div>
        <div class="scroll-bar">
            <div class="scroll-thumb"></div>
        </div>
    </div>
    <div class="scroll-container">
        <div class="scroll-content">
            <p>Second scrollable content starts here...</p>
            <p>... (много текста) ...</p>
        </div>
        <div class="scroll-bar">
            <div class="scroll-thumb"></div>
        </div>
    </div>

    <script>
        // Функция для инициализации скроллбара
        function initializeCustomScrollBar(container) {
            const scrollContent = container.querySelector('.scroll-content');
            const scrollThumb = container.querySelector('.scroll-thumb');
            const scrollBar = container.querySelector('.scroll-bar');

            // Обновляем позицию капельки при скролле
            function updateThumbPosition() {
                const contentHeight = scrollContent.scrollHeight;
                const containerHeight = container.clientHeight;
                const scrollTop = scrollContent.scrollTop;

                // Высота прокручиваемой области
                const scrollRatio = scrollTop / (contentHeight - containerHeight);

                // Максимальная высота для капельки
                const maxThumbTop = scrollBar.clientHeight - scrollThumb.clientHeight;

                // Устанавливаем новую позицию капельки
                scrollThumb.style.top = `${scrollRatio * maxThumbTop}px`;
            }

            // Обработчик прокрутки контента
            scrollContent.addEventListener('scroll', updateThumbPosition);

            // Перемещение капельки мышью
            let isDragging = false;

            scrollThumb.addEventListener('mousedown', (e) => {
                isDragging = true;
                document.body.style.userSelect = 'none'; // Отключаем выделение текста
            });

            document.addEventListener('mousemove', (e) => {
                if (isDragging) {
                    const containerRect = container.getBoundingClientRect();
                    const offsetY = e.clientY - containerRect.top;

                    const maxThumbTop = scrollBar.clientHeight - scrollThumb.clientHeight;

                    // Ограничиваем движение капельки в пределах полосы
                    const thumbTop = Math.max(0, Math.min(offsetY, maxThumbTop));
                    scrollThumb.style.top = `${thumbTop}px`;

                    // Прокручиваем контент в зависимости от позиции капельки
                    const scrollRatio = thumbTop / maxThumbTop;
                    scrollContent.scrollTop = scrollRatio * (scrollContent.scrollHeight - container.clientHeight);
                }
            });

            document.addEventListener('mouseup', () => {
                isDragging = false;
                document.body.style.userSelect = ''; // Включаем выделение текста
            });

            // Обновляем позицию капельки при загрузке
            updateThumbPosition();
        }

        // Инициализация для всех контейнеров
        document.querySelectorAll('.scroll-container').forEach(initializeCustomScrollBar);
    </script>

  1. Инициализация нескольких скроллов:
    • Используется цикл forEach для обработки всех элементов с классом .scroll-container.
    • Каждый контейнер работает независимо.
  2. Функция initializeCustomScrollBar:
    • Позволяет повторно использовать код для инициализации скроллбара.