javascript - 如何在滑块、vue 中使用多个 Clappr?
问题描述
我创建了一个由多个图像和视频组成的滑块。我使用 Swiper 和 Clappr(视频播放器),但 clappr 不适用于多个视频。
我试图通过一个循环来修复它(下面的代码),但即便如此,该脚本仅适用于第一个视频。
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
});
}
}
});
}
}
它适用于数组中的第一个视频,但不适用于以下
解决方案
你的问题是:
- 您正在创建的钩子上初始化 clappr(不理想)
- 由于使用了`v-if,你只初始化了第一个
created 钩子在组件完成构建其 DOM 之前触发,因此理论上,您将无法通过document.querySelector
.
为什么这行得通?
由于您在异步函数(来自 axios 的 ajax 调用)中运行此 querySelector,这意味着服务器响应您的调用所花费的时间/getWorks/
,浏览器已完成创建 DOM。这纯粹是运气,而不是你想要做的。
#1的解决方案;将创建的钩子更改为已安装的钩子。– Mounted 是 Vue 用来告诉您 DOM 已构建并完成的钩子。
第二个问题是您使用 v-if 来“隐藏”其他元素。v-if 从 DOM 中完全删除元素。这使您的 querySelector 无法找到它并对其进行初始化。(因为只有一个,这是你的第一个元素:
因此,该脚本仅适用于第一个视频。
解决方案 #2更改v-if
为v-show
- v-show 将元素保留在 DOM 中,但通过 CSS 隐藏它。因此它可以通过 querySelector 访问。
推荐阅读
- javascript - 寻找循环解决方案的方形文本问题
- sql - 如何在 SQL 中对数组进行 string_agg?
- node.js - 在 Node 8.x 及更高版本中调试 Protractor 测试
- python - 两个排序的部分重叠的numpy数组之间的索引映射
- r - 计算多个因子变量中的出现次数
- regex - 使用正则表达式查找和替换 - 仅删除字母之间的双空格
- javascript - 我们可以说 String 是 Javascript 中的对象吗?
- javascript - 如何将外部网站链接到导入的 React src 图像?
- javascript - 如何在html中控制滑块速度
- django - 必须与数据库交互的 django 应用程序启动代码在哪里?