Skip to content

generators sample 9

garevna edited this page Feb 1, 2019 · 1 revision

Создадим ☕ слайдер с помощью итератора

Для начала определим массив картинок pictures

const pictures = [
    "https://cdn.pixabay.com/photo/2017/03/29/15/18/tianjin-2185510__340.jpg",
    "https://cdn.pixabay.com/photo/2018/01/11/19/02/architecture-3076685__340.jpg",
    "https://cdn.pixabay.com/photo/2017/01/18/16/46/hong-kong-1990268__340.jpg",
    "https://cdn.pixabay.com/photo/2013/03/02/02/41/city-89197__340.jpg",
    "https://cdn.pixabay.com/photo/2017/12/10/17/40/prague-3010407__340.jpg",
    "https://cdn.pixabay.com/photo/2018/01/31/12/16/architecture-3121009__340.jpg",
    "https://cdn.pixabay.com/photo/2015/02/24/13/23/city-647400__340.jpg",
    "https://cdn.pixabay.com/photo/2018/11/29/21/19/hamburg-3846525__340.jpg"
]

Добавим массиву pictures метод createSlide

pictures.createSlide = function () {
    const slide = document.body.appendChild (
        document.createElement ( "figure" )
    )
    slide.style = `
        position: fixed;
        top: 10%;
        bottom: 10%;
        left: 10%;
        right: 10%;
        transition: all 0.5s;
        background-size: contain;
        background-repeat: no-repeat;
        background-position: center center;
    `
    slide.onclick = function () {
        this.iterator.next ()
    }.bind ( this )

    return slide
}

Этот метод создает и возвращает html-элемент с заданными стилевыми атрибутами и обработчиком события click

Обратите внимание, что обработчик события click вызывает метод next() итератора

Определим этот итератор

Для этого нужно объявить и вызвать функцию-генератор

Мы объединим два этих действия в одно с помощью IIFE

pictures.iterator = (
    function* () {
        ...
    }
).call ( pictures )

Обратите внимание, что мы вызываем анонимную функцию-генератор в контексте объекта pictures

Теперь this внутри генератора будет показывать в правильном направлении 👌

Внутри анонимной функции-генератора:

📋 объявим вспомогательную функцию moveSlide,

которая будет сдвигать слайд в нужном направлении

в зависимости от значения второго аргумента active

Этот аргумент принимает логическое значение

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

В противном случае слайд "уходит" из видимой зоны

Первым аргументом передается ссылка на сдвигаемый слайд

function moveSlide ( slide, active ) {
    slide.style.left = `${ active ? 10 : -100 }%`
    slide.style.right = `${ active ? 10 : 100 }%`
    slide.style.opacity = active ? 1 : 0
}

📋 Создадим приватный метод getNextPictureNum, который будет возвращать индекс следующего элемента массива pictures

Обратите внимание, что этой функции мы заранее "закрепляем" контекст вызова с помощью метода bind(), поскольку в противном случае это будет глобальный контекст

let getNextPictureNum = function () {
    return this.currentPicture < this.length - 1 ?
        this.currentPicture + 1 : 0
}.bind ( this )

📋 Теперь создадим массив их двух слайдов

const slides = [
    this.createSlide (),
    this.createSlide ()
]

Для этого, как видите, мы воспользовались публичным методом createSlide массива pictures

📋 Объявим еще пару переменных

  • приватное свойство currentSlide будет индексом активного слайда
  • публичное свойство currentPicture будет содержать индекс текущего элемента массива pictures
let currentSlide = 0
this.currentPicture = 0

📋 Осталось совсем немного - написать сам протокол итерирования

В процессе итерирования слайды slides[0] и slides[1] будут постоянно меняться местами

т.е. активным текущим слайдом по очереди будет то slides[0], то slides[1]

вычислять индекс неактивного слайда для смены слайдов мы будем так:

Math.abs ( currentSlide - 1 )

Итак, протокол итерирования:

while ( true ) {
    this.nextPicture = getNextPictureNum ()
    slides [ Math.abs ( currentSlide - 1 ) ].style.backgroundImage = `
        url(${ this [ this.nextPicture ] })
    `
    moveSlide ( slides [ currentSlide ], false )
    await waitFor ( 500 )
    moveSlide ( slides [ Math.abs ( currentSlide - 1 ) ], true )
    await waitFor ( 500 )
    this.currentPicture = this.nextPicture
    this.nextPicture = getNextPictureNum ()
    currentSlide = Math.abs ( currentSlide - 1 )
            
    yield slides [ currentSlide ]
            
}
Полный код генератора
pictures.iterator = (
    function* () {
        function moveSlide ( slide, active ) {
            slide.style.left = `${ active ? 10 : -100 }%`
            slide.style.right = `${ active ? 10 : 100 }%`
            slide.style.opacity = active ? 1 : 0
        }
        
        let getNextPictureNum = function () {
            return this.currentPicture < this.length - 1 ?
                this.currentPicture + 1 : 0
        }.bind ( this )

        const slides = [
            this.createSlide (),
            this.createSlide ()
        ]

        let currentSlide = 0
        this.currentPicture = 0
        
        while ( true ) {
            this.currentPicture = getNextPictureNum ()
            slides [ Math.abs ( currentSlide - 1 ) ]
                .style.backgroundImage = `
                    url(${ this [ this.currentPicture ] })
                `
            moveSlide ( slides [ currentSlide ], false )
            moveSlide ( slides [ Math.abs ( currentSlide - 1 ) ], true )
            currentSlide = Math.abs ( currentSlide - 1 )
            
            yield slides [ currentSlide ]
            
        }
    }
).call ( pictures )
Запуск
pictures.iterator.next()

© Irina H.Fylyppova 2018
Использование данных материалов или любой их части коммерческими школами ( курсами ) является нарушением авторских прав


Новая версия


1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19

Занятие 1

⤵️

Занятие 2

⤴️ ⤵️

Занятие 3

⤴️ ⤵️

Занятие 4

⤴️ ⤵️

Занятие 5

⤴️ ⤵️

Занятие 6

⤴️ ⤵️

Занятие 7

⤴️ ⤵️

Занятие 8

⤴️ ⤵️

Занятие 9

⤴️ ⤵️

Занятие 10

⤴️ ⤵️

Занятие 11

⤴️ ⤵️

Занятие 12

⤴️ ⤵️

Занятие 13

⤴️ ⤵️

Занятие 14

⤴️ ⤵️

Занятие 15

⤴️ ⤵️

Занятие 16

⤴️ ⤵️

Занятие 17

⤴️ ⤵️

Занятие 18

⤴️ ⤵️

Занятие 19

⤴️ ⤵️

⤴️

ico20 Дополнительно
dir-20 Справочная инфо

Clone this wiki locally