Card Slider 1.0.1 : слайдер для DLE


Слайдеры стали важной частью веб-дизайна, используемой для привлекательной и интерактивной демонстрации контента или изображений. Как новичку, создание слайдера может помочь вам разработать фундаментальные концепции веб-разработки, такие как манипулирование DOM, адаптивный дизайн и слушатели событий jаvascript.


Эти концепции жизненно важны для понимания разработчиками внешнего интерфейса и могут применяться к различным проектам веб-разработки. Итак, в этой статье мы покажем вам, как создать адаптивный перетаскиваемый слайдер карточек на HTML, CSS, jаvascript и PHP, который можно использовать для отображения изображений, продуктов, профилей пользователей и другого контента.

Чтобы по-настоящему понять, как работает перетаскиваемый слайдер карточек, мы не будем использовать какие-либо внешние библиотеки jаvascript, такие как SwiperJs или Owl Carousel. Вместо этого мы создадим слайдер с нуля, используя чистый jаvascript, PHP, HTML и CSS.

Для того, чтобы сделать наш слайдер проще и гибче, был создали адаптированный модуль, подключаемый через систему плагинов DLE, с помощью которого вы сможете легко добавлять, удалять или исправлять информацию о слайдах. После его установки в шаблон сайта следует внести следующие изменения:

Код вывода слайдера в шаблоне:
<div class="wrapper">
        <i id="left" class="fa-solid fa-angle-left"></i>
        <ul class="carousel">
           {include file="engine/modules/ticcix/slider.php?limit=10"}
        </ul>
        <i id="right" class="fa-solid fa-angle-right"></i>
    </div>

Где limit - cколько слайдов вы хотите показать.

Подключаемые к шаблону CSS стили:
/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
display: flex;
padding: 0 35px;
align-items: center;
justify-content: center;
min-height: 100vh;
background: linear-gradient(to left top, #031A9A, #8B53FF);
}
.wrapper {
max-width: 1100px;
width: 100%;
position: relative;
}
.wrapper i {
top: 50%;
height: 50px;
width: 50px;
cursor: pointer;
font-size: 1.25rem;
position: absolute;
text-align: center;
line-height: 50px;
background: #fff;
border-radius: 50%;
box-shadow: 0 3px 6px rgba(0,0,0,0.23);
transform: translateY(-50%);
transition: transform 0.1s linear;
}
.wrapper i:active{
transform: translateY(-50%) scale(0.85);
}
.wrapper i:first-child{
left: -22px;
}
.wrapper i:last-child{
right: -22px;
}
.wrapper .carousel{
display: grid;
grid-auto-flow: column;
grid-auto-columns: calc((100% / 3) - 12px);
overflow-x: auto;
scroll-snap-type: x mandatory;
gap: 16px;
border-radius: 8px;
scroll-behavior: smooth;
scrollbar-width: none;
}
.carousel::-webkit-scrollbar {
display: none;
}
.carousel.no-transition {
scroll-behavior: auto;
}
.carousel.dragging {
scroll-snap-type: none;
scroll-behavior: auto;
}
.carousel.dragging .card {
cursor: grab;
user-select: none;
}
.carousel :where(.card, .img) {
display: flex;
justify-content: center;
align-items: center;
}
.carousel .card {
scroll-snap-align: start;
height: 342px;
list-style: none;
background: #fff;
cursor: pointer;
padding-bottom: 15px;
flex-direction: column;
border-radius: 8px;
}
.carousel .card .img {
background: #8B53FF;
height: 148px;
width: 148px;
border-radius: 50%;
}
.card .img img {
width: 140px;
height: 140px;
border-radius: 50%;
object-fit: cover;
border: 4px solid #fff;
}
.carousel .card h2 {
font-weight: 500;
font-size: 1.56rem;
margin: 30px 0 5px;
}
.carousel .card span {
color: #6A6D78;
font-size: 1.31rem;
}

@media screen and (max-width: 900px) {
.wrapper .carousel {
grid-auto-columns: calc((100% / 2) - 9px);
}
}

@media screen and (max-width: 600px) {
.wrapper .carousel {
grid-auto-columns: 100%;
}
}

Подключаемый к шаблону JS:
const wrapper = document.querySelector(".wrapper");
const carousel = document.querySelector(".carousel");
const firstCardWidth = carousel.querySelector(".card").offsetWidth;
const arrowBtns = document.querySelectorAll(".wrapper i");
const carouselChildrens = [...carousel.children];

let isDragging = false, isAutoPlay = true, startX, startScrollLeft, timeoutId;

// Get the number of cards that can fit in the carousel at once
let cardPerView = Math.round(carousel.offsetWidth / firstCardWidth);

// Insert copies of the last few cards to beginning of carousel for infinite scrolling
carouselChildrens.slice(-cardPerView).reverse().forEach(card => {
    carousel.insertAdjacentHTML("afterbegin", card.outerHTML);
});

// Insert copies of the first few cards to end of carousel for infinite scrolling
carouselChildrens.slice(0, cardPerView).forEach(card => {
    carousel.insertAdjacentHTML("beforeend", card.outerHTML);
});

// Scroll the carousel at appropriate postition to hide first few duplicate cards on Firefox
carousel.classList.add("no-transition");
carousel.scrollLeft = carousel.offsetWidth;
carousel.classList.remove("no-transition");

// Add event listeners for the arrow buttons to scroll the carousel left and right
arrowBtns.forEach(btn => {
    btn.addEventListener("click", () => {
        carousel.scrollLeft += btn.id == "left" ? -firstCardWidth : firstCardWidth;
    });
});

const dragStart = (e) => {
    isDragging = true;
    carousel.classList.add("dragging");
    // Records the initial cursor and scroll position of the carousel
    startX = e.pageX;
    startScrollLeft = carousel.scrollLeft;
}

const dragging = (e) => {
    if (!isDragging) return; // if isDragging is false return from here
    // Updates the scroll position of the carousel based on the cursor movement
    carousel.scrollLeft = startScrollLeft - (e.pageX - startX);
}

const dragStop = () => {
    isDragging = false;
    carousel.classList.remove("dragging");
}

const infiniteScroll = () => {
    // If the carousel is at the beginning, scroll to the end
    if (carousel.scrollLeft === 0) {
        carousel.classList.add("no-transition");
        carousel.scrollLeft = carousel.scrollWidth - (2 * carousel.offsetWidth);
        carousel.classList.remove("no-transition");
    }
    // If the carousel is at the end, scroll to the beginning
    else if (Math.ceil(carousel.scrollLeft) === carousel.scrollWidth - carousel.offsetWidth) {
        carousel.classList.add("no-transition");
        carousel.scrollLeft = carousel.offsetWidth;
        carousel.classList.remove("no-transition");
    }

    // Clear existing timeout & start autoplay if mouse is not hovering over carousel
    clearTimeout(timeoutId);
    if (!wrapper.matches(":hover")) autoPlay();
}

const autoPlay = () => {
    if (window.innerWidth < 800 || !isAutoPlay) return; // Return if window is smaller than 800 or isAutoPlay is false
    // Autoplay the carousel after every 2500 ms
    timeoutId = setTimeout(() => carousel.scrollLeft += firstCardWidth, 2500);
}
autoPlay();

carousel.addEventListener("mousedown", dragStart);
carousel.addEventListener("mousemove", dragging);
document.addEventListener("mouseup", dragStop);
carousel.addEventListener("scroll", infiniteScroll);
wrapper.addEventListener("mouseenter", () => clearTimeout(timeoutId));
wrapper.addEventListener("mouseleave", autoPlay);

card-slider-1_0_1-slajder-dlja-dle.zip
Создайте аккаунт или авторизуйтесь для скачивания
 
Демо
 
Версия DLE: 13.x и выше
Интерфейс: Английский, Грузинский
Автор: Ticcix
Источник

Примечание от Oxigen: ппри создании статьи использовался машинный перевод с английского

Информация
Посетители, находящиеся в группе Гость, не могут оставлять комментарии к данной публикации.