Как использовать несколько Clappr в слайдер, Vue? - PullRequest
1 голос
/ 23 апреля 2019

Я создал слайдер, состоящий из нескольких изображений и видео.Я использую Swiper и Clappr (видеоплеер), но clappr не работает с несколькими видео.

Я пытался исправить это с помощью цикла (код ниже), но даже в этом случае скрипт работает только для первогоvideo.

Vue v.3.1, Clappr v.0.3, Swiper v.4.5.

<section class="content__slider swiper-container"
         v-if="project_data && project_data.length">

    <ul class="swiper-wrapper">
        <li v-for="(object, index) in project_data" :key="index"
            class="content-item swiper-slide">

            <!-- it'll be show, if obj type is images -->
            <v-lazy-image v-if="object.type === 'images'"
                          :src="object.data"
                          class="content-img"/>

            <!-- it'll be show, if obj type is video -->
            <div v-if="object.type === 'video'"
                 class="content-video"
                 :id="'container_' + index"></div>

        </li>
    </ul>

</section>
import axios from 'axios'
import Swiper from "swiper/dist/js/swiper.esm.bundle";
import VLazyImage from "v-lazy-image";
import Clappr from 'clappr'

import 'swiper/dist/css/swiper.min.css'

export default {
    name: "Project",
    data: () => ({
        project_data: [], // data of project
        project_images: [], // arr of images
        project_videos: [], // arr of videos
    }),
    created() {

        axios.get('/getWorks/' + this.$route.params.name)
            .then(response => {

                 let arr = [];

                 this.project_images = response.data.work_images;
                 let images = response.data.work_images;

                 this.project_videos = response.data.work_videos;
                 let videos = response.data.work_videos;

                 for (let i = 0; i < images.length; i++) {
                     arr.push({"type": "images", "data": "/storage/" + images[i]});
                 }
                 for (let i = 0; i < videos.length; i++) {
                     arr.push({"type": "video", "data": "/storage/" + videos[i]});
                 }

                 this.project_data = arr;

            })
            .then(() => {

                // init slider
                new Swiper('.content__slider', {
                    mousewheel: true,
                    keyboard: true,
                    speed: 1200,
                    navigation: {
                        nextEl: '.content-arrow.swiper-button-next',
                        prevEl: '.content-arrow.swiper-button-prev',
                    },
                    pagination: {
                        el: '.content-pagination.swiper-pagination',
                        type: 'fraction',
                    },
                    breakpoints: {
                        959: {
                            zoom: {
                                maxRatio: 5,
                                toggle: true,
                                containerClass: '.content__slider',
                                zoomedSlideClass: '.content-item'
                            },
                        }
                    }
                });

                // init clappr (video player)
                if ( document.querySelector('.content-video') ) {
                    for (let i = 0; i < this.project_videos.length; i++) {
                        new Clappr.Player({
                            source: '/storage/' + this.project_videos[i],
                            parentId: '#container_' + (this.project_images.length - i),
                            mute: true,
                            width: document.querySelector('.content-item').offsetWidth,
                            height: document.querySelector('.content-item').offsetHeight
                        });
                    }
                }
            });
    }
}

Это работает для первого видео в массиве, но не для следующего

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Ваша проблема:

  1. вы инициализируете clappr на созданном хуке (не идеально)
  2. вы инициализируете только первый из-за использования `v-if

Созданный хук срабатывает до того, как компонент завершит сборку своей DOM, поэтому теоретически вы не сможете найти какие-либо элементы через ваш document.querySelector.

Почему это работает?

Поскольку вы запускаете этот querySelector внутри асинхронной функции (вызов ajax из axios), это означает, что время, которое требуетсясервер для ответа на ваш звонок /getWorks/, браузер завершил создание DOM.Это чистая удача, а не то, что вы хотели бы сделать.

Решение для # 1; Заменить созданный крюк на смонтированный крюк.- Монтируется тот хук, который использует Vue, чтобы сообщить вам, что DOM собран и завершен.

Вторая проблема заключается в том, что вы используете v-if, чтобы «скрыть» другие элементы.v-if полностью удаляет элемент из DOM.Это делает ваш querySelector неспособным найти его и инициализировать.(Потому что есть только один, и это ваш первый элемент:

, поэтому скрипт работает только для первого видео.

Решение # 2 Изменить v-if на v-show - v-show хранит элемент в DOM, но скрывает его через CSS, поэтому он доступен через querySelector.

0 голосов
/ 23 апреля 2019

Живи и учись, я не заметил своей ошибки.

parentId: '#container_' + (this.project_images.length + i)

Нужно было подвести итог.Теперь работает)

...