Что делает скрипт

Слайдер карточек с точками и стрелками, крайние карточки упираются в границы.

Как подключить

  1. Zero Block слайдера задайте класс uc-rsn.
  2. Внутри: .arrows со стрелками .arrow-left / .arrow-right, .cards-container с карточками .card и .dots с точками .dot.
  3. Вставьте код в блок T123 «HTML-код» на страницу (или в «Настройки страницы» → «HTML-код для вставки внутрь head»).
  4. Опубликуйте страницу: код выполняется только на опубликованной странице.

Код

Код для вставки
<script src="https://cdn.jsdelivr.net/npm/scrollbooster@3.0.2/dist/scrollbooster.min.js" defer=""></script>

<style>

.uc-rsn .scrollbooster-viewport {
    /* горизонтальный скролл, скрытые скроллбары */
    cursor: grab;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;       /* Firefox */
    -ms-overflow-style: none;    /* IE 10+ */
}

/* Скрываем в WebKit-браузерах */
.uc-rsn .scrollbooster-viewport::-webkit-scrollbar {
    height: 0;
    background: transparent;
}

.uc-rsn .dot.active .tn-atom {
    opacity: 1 !important;
}


</style>

<script>
$(() => {
    const $record = $(".uc-rsn");

    const $leftArrow = $record.find(".arrow-left");
    const $rightArrow = $record.find(".arrow-right");

    const $scrollContainer = $record.find(".cards-container").addClass("scrollbooster-viewport");

    $scrollContainer.wrapInner('<div class="scrollbooster-content"></div>');


    $scrollContainer.on("scroll", () => updateControls());
    $(window).on("resize", () => updateControls());

    const cards = $scrollContainer.find(".card").toArray().toSorted((a, b) => getX(a) - getX(b));


    $leftArrow.click(e => {
        e.preventDefault();
        $scrollContainer
            .animate( { scrollLeft: '-=' + getShiftSize(false) }, 300 )
            .queue(updateControls);
    })
    $rightArrow.click(e => {
        e.preventDefault();
        $scrollContainer
            .animate( { scrollLeft: '+=' + getShiftSize(true) }, 300 )
            .queue(updateControls);
    })


    const $dotsContainer = $record.find(".dots");
    const $firstDot = $dotsContainer.find(".dot");
    for(let i = 1; i < cards.length; i++) {
        $firstDot.clone().appendTo($dotsContainer.find(".tn-molecule"));
    }
    $firstDot.addClass("active");
    const $dots = $dotsContainer.find(".dot");



    function updateControls(next) {
        let leftArrowDisabled = $scrollContainer.scrollLeft <= 10;
        let rightArrowDisabled = $scrollContainer.scrollLeft >= $scrollContainer.scrollWidth - $scrollContainer.clientWidth - 10;

        $leftArrow.add($rightArrow).toggleClass("hidden", leftArrowDisabled && rightArrowDisabled);
        $leftArrow.toggleClass("disabled", leftArrowDisabled);
        $rightArrow.toggleClass("disabled", rightArrowDisabled);

        const currentSlideIndex = cards.indexOf(
            getNearestBlock(cards, window.innerWidth / 2, false)
        );

        $dotsContainer.find(".dot.active").removeClass("active");
        $dots[currentSlideIndex].classList.add("active");

        if(next) next();
    }

    function getX(block) {
        return block.getBoundingClientRect().x;
    }

    function getNearestBlock(blocks, pointX, direction) {
        let nearestBlock;
        let nearestBlockX;

        for(const block of blocks) {
            const blockX = getX(block);

            if(direction ? (blockX <= pointX+10) : (blockX >= pointX-10)) continue;

            if(
                nearestBlockX === undefined ||
                (direction ? (blockX < nearestBlockX) : (blockX > nearestBlockX))
            ) {
                nearestBlock = block;
                nearestBlockX = blockX;
            }
        }

        if(nearestBlockX === undefined)
            return blocks.at(direction ? -1 : 0);

        return nearestBlock;
    }

    function getShiftSize(direction) {
        const containerX = getX( $scrollContainer[0] );
        // const containerX = $scrollContainer[0].offsetLeft + cards[0].offsetLeft;

        const nearestCardX = getX( getNearestBlock(cards, containerX, direction) );

        return Math.abs(containerX - nearestCardX);
    }

    // Ширина скроллбара для css костылей
    function _calculateScrollbarWidth() {
      document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");
    }
    window.addEventListener('resize', _calculateScrollbarWidth, false);
    document.addEventListener('DOMContentLoaded', _calculateScrollbarWidth, false); 
    window.addEventListener('load', _calculateScrollbarWidth);

    _calculateScrollbarWidth();

    setTimeout(() => {
        const sb = new ScrollBooster({
            viewport: $scrollContainer[0],
            content:  $record.find(".scrollbooster-content")[0],
            scrollMode: 'native',
            pointerMode: 'all',
            bounce: false,
        });
    }, 1);
});

</script>
тут нужно написать стили и js/css для того, чтобы отображались файлы скриптов