Как добавить класс к следующему DIV и исчезнуть текущий с динамическим количеством элементов - несколько экземпляров - PullRequest
0 голосов
/ 02 ноября 2019

Мне было интересно, есть ли способ создать масштабируемое (в основном) CSS-слайд-шоу для текстовых элементов - без изображений.

У меня есть текущая структура HTML:

<div class="mb-panel-container cf">
    <div class="mb-panel-section mb-slider">
        <div class="mb-panel active">
            <h1>1.1</h1>
            <p>slide 1.1</p>
            <p class="datetime"></p>
        </div>
        <div class="mb-panel">
            <h1>1.2</h1>
            <p>slide 1.2</p>
            <p class="datetime"></p>
        </div>
        <div class="mb-panel">
            <h1>1.3</h1>
            <p>slide 1.3</p>
            <p class="datetime"></p>
        </div>
    </div>
    <div class="mb-panel-section mb-slider">
        <div class="mb-panel active">
            <h1>2.1</h1>
            <p>slide 2.1</p>
            <p class="datetime"></p>
        </div>
        <div class="mb-panel">
            <h1>2.2</h1>
            <p>slide 2.2</p>
            <p class="datetime"></p>
        </div>
        <div class="mb-panel">
            <h1>2.3</h1>
            <p>slide 2.3</p>
            <p class="datetime"></p>
        </div>
    </div>
    <div class="mb-panel-section mb-slider">
        <div class="mb-panel active">
            <h1>3.1</h1>
            <p>slide 3.1</p>
            <p class="datetime"></p>
        </div>
        <div class="mb-panel">
            <h1>3.2</h1>
            <p>slide 3.2</p>
            <p class="datetime"></p>
        </div>
        <div class="mb-panel">
            <h1>3.3</h1>
            <p>slide 3.3</p>
            <p class="datetime"></p>
        </div>
    </div>
</div>

Ноколичество слайдов будет варьироваться в зависимости от количества сделанных уведомлений.

У меня есть текущий CSS:

.mb-panel-container {
    width: 100vw;
    margin-top: 1px;
    text-align: center;
}
.mb-panel-section {
    width: calc( ( 100vw - 3px ) / 3 );
    float: left;
    margin-right: 1px;
}
.mb-panel-section.mb-slider {
    height: calc( 100vh - (4em + 1.75em + 2em + 5em) );
}
.mb-panel-section .mb-panel {
    line-height: 1em;
    padding: 1em;
    height: 100%;
    width: 100%;
}
.mb-panel-section.mb-slider .mb-panel {
    padding: 5em 2em 3em;
    opacity: 0;
    transition: opacity 2s linear;
}
.mb-panel-container .mb-panel-section .mb-panel.active { opacity: 1; }

И Javascript:

$(document).ready(function() {
    var items = $('.mb-panel');
    var currentItem = items.filter('.active');
    window.setInterval( function(){
        var nextItem = currentItem.next();
        currentItem.removeClass('active');
        if ( nextItem.length ) {
            currentItem = nextItem.addClass('active');
        } else {
            // If you want it to loop around
            currentItem = items.first().addClass('active');
        }
    }, 5000);
}); 

Тем не менее, хотя она и проходит через первую панель бесконечно, две другие не будут зацикливаться, а заканчиваются на последней панели.

Я не совсем уверен, где изменить код, и не хочудублировать код JS для каждой секции панели.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2019

В случае, если кто-то ищет решение позже, вот что я сделал:

$(document).ready(function() {
    var items       = $(".mb-panel"),
        currentItem = items.filter(".active");

    window.setInterval( function() {
        var nextItem = currentItem.next();
        currentItem.removeClass("active");

        if( nextItem.length ) {
            currentItem = nextItem.addClass("active");
        } else {
            currentItem = items.first().addClass("active");
        }
    }, 5000);
});

По существу добавляет класс active к следующему элементу в div, а затем удаляет его и добавляетэто к следующему, и так далее. Делает это масштабируемым до бесконечности.

0 голосов
/ 02 ноября 2019

Я считаю, что то, что вы ищете, проще, чем редактировать все эти элементы. Чистое решение CSS и JS, без JQuery, будет выглядеть примерно так:

const allSlides = document.querySelectorAll(".mb-slide");
const active = allSlides.filter(slide => slide.classList.contains("active"))[0];
const activeIndex = allSlides.findIndex(slide => slide === active);
const nextItem = allSlides[activeIndex + 1];
active.classList.remove("active");
nextItem.classList.add("active");

Между тем вы начнете со страницы с первым слайдом, имеющим класс .active. В вашем CSS вы можете установить что-то вроде:

.mb-slide{
 // all your other CSS
 opacity: 0;
 transition: opacity 0.3s linear;
 }
.active{
opacity: 1;
transition: opacity 0.3s linear;
}
...