Бесконечная карусель с ванильным JavaScript

Я пытаюсь построить свою собственную карусель с чистым JavaScript.

Я борюсь с выбором наиболее эффективного способа добавить infinite carousel вариант.

По некоторым причинам каждый элемент (фотография, общий объект) должен иметь id

Алгоритм, который я вижу, выглядит так:

  • Вы проверяете, не переполнена ли карусель (достаточно ли объектов, чтобы вместить весь контейнер)
  • Если нет: добавьте в конец копию первого элемента, затем копию второго элемента и так далее. (Но будет проблема с идентификаторами, потому что этот объект будет иметь тот же идентификатор)

Добавление копий - Если пользователь прокручивает до последнего объекта (вправо), тогда добавьте первый объект DOM обратно в массив
- Если пользователь прокручивает до первого объекта (слева), тогда добавьте последнего потомка DOM в начало массива.

Это сработает? Есть ли другой эффективный способ сделать бесконечную карусель?

Я также слышал, что лучше использовать свойство translate, чем изменять свойства left, right, поэтому для GPU будет больше работы, чем для CPU.

2 ответа

Решение

Я создал простой слайдер с CSS-трансформациями в качестве техники анимации и простым Javascript.

var img = document.getElementsByClassName("img")[0]; 
img.style.transform = 'translate('+value+'px)';

Вы можете проверить это в этом фрагменте кода. http://codepen.io/TobiObeck/pen/QKpaBr

Нажатие на кнопку переводит все изображения в соответствующем направлении вдоль оси X. Изображение на краю, установлено прозрачным outerImg.style.opacity = '0'; и переведен на другую сторону. Вы можете добавлять или удалять элементы изображения в HTML, и это все еще работает.

Во втором фрагменте кода вы можете увидеть, как он работает. opacity установлен в 0.5 поэтому можно наблюдать, какое изображение переходит на другую сторону. Так как overflow: hidden удаляется, вы можете увидеть, как изображения на краю ставятся в очередь на другой стороне. http://codepen.io/TobiObeck/pen/WGpdLE

Кроме того, не стоит проверять, завершена ли анимация, в противном случае одновременно добавленные переводы будут выглядеть странно. Поэтому щелчок не будет вызывать другую анимацию, пока анимация не будет завершена.

img.addEventListener("transitionend", transitionCompleted, true);

var transitionCompleted = function(){
    translationComplete = true;
}

leftBtnCLicked(){
    if(translationComplete === true){
       //doAnimation
    }
}

вы можете использовать этот код для управления слайдами. Это в основном вращает массив назад и вперед

              <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style> 

    body {
    width: 100%;
    height: 100%;
    }

    .parentDiv {
    height: 30%;
    width: 100%;
    display: flex;
    }

    </style>
    <title>test</title>
    </head>
    <body>
    <button class="fwd"> Fwd! </button>
    <button class="bkwd"> Bkwd! </button>
    <script type="text/javascript">
    const arr = ['red', 'blue', 'coral', 'green', 'yellow'];
    let narr = ['red', 'blue', 'coral'];
    


    const parentDiv = document.createElement('div');
    parentDiv.setAttribute('class', 'parentDiv');
    document.body.insertAdjacentElement('afterbegin', parentDiv);


    window.onload = ()=> {
    narr.forEach(color => {
    while(parentDiv.children.length < narr.length){
    const childDiv = document.createElement('div');
    parentDiv.appendChild(childDiv);
    };
    });

    Array.from(parentDiv.children).forEach((child, index) => {
    child.style.border = '1px #000 dotted';
    child.style.minWidth = '20%';
    child.style.minHeight = '20vh';
    child.style.backgroundColor = narr[index]
    });
    };



    document.querySelector('.fwd').addEventListener('click', ()=>{
    narr.shift();

    if(narr[narr.length-1] === arr[arr.length-1]){
        narr.push(arr[0])
    } else {
    narr.push(arr[arr.indexOf(narr[narr.length-1])+1])
    }

    narr.forEach(color => {
    while(parentDiv.children.length < narr.length){
    const childDiv = document.createElement('div');
    parentDiv.appendChild(childDiv);
    };
    });

    Array.from(parentDiv.children).forEach((child, index) => {
    child.style.border = '1px #000 dotted';
    child.style.minWidth = '20%';
    child.style.minHeight = '20vh';
    child.style.backgroundColor = narr[index];
    
    
    });


    })


    document.querySelector('.bkwd').addEventListener('click', ()=>{
    narr.pop();
    if(narr[0] === arr[0]){
        narr.unshift(arr[arr.length-1])
    } else {
    narr.unshift(arr[arr.indexOf(narr[0])-1])
    }

    

    narr.forEach(color => {
    while(parentDiv.children.length < narr.length){
    const childDiv = document.createElement('div');
    parentDiv.appendChild(childDiv);
    };
    });

    Array.from(parentDiv.children).forEach((child, index) => {
    child.style.border = '1px #000 dotted';
    child.style.minWidth = '20%';
    child.style.minHeight = '20vh';
    child.style.backgroundColor = narr[index]
    });
    })

    </script>   
    </body>
    </html>
Другие вопросы по тегам