手指上下滚动播放视频
概念: 轮播+原生video
轮播图任何一个插件都可以,这里我用的是swiper.js
<swiper
class="swiper"
:options="swiperOption"
ref="mySwiper"
style="height: 100%"
>
<swiper-slide
class="swiper-slide"
v-for="(item, index) in videoList"
:key="index"
>
<div style="width: 100%; height: 100%; position: relative">
<div class="video">
// 视频
<video
v-if="item.conthttp"
:src="ossurl + item.conthttp"
@click="showStop($event, index)"
:id="'myVideo' + index"
class="esVideo"
x-webkit-airplay="true"
webkit-playsinline="true"
playsinline="true"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
/>
</div>
// 图片内容
<div class="imgstyle">
//封面图
<img
v-if="item.bpichttp"
:src="ossurl + item.bpichttp"
class="showimg"
:id="'showimgBtn' + index"
/>
//视频中心按钮
<div class="playbtn" :id="'playbtn' + index">
<img
:src="ossurl + 'ddzsc/images/material/play.png'"
@click="playVideo($event, index)"
style="width: 100%; height: auto"
/>
</div>
</div>
</div>
// 视频顶部文字
<div class="video-top">
<div class="hrardimg" @click.stop="showPopUp()">
<img v-if="myinfo.headimg" :src="ossurl + myinfo.headimg" alt />
<img v-show="myinfo.wxHeadimg" v-else :src="myinfo.wxHeadimg" alt />
</div>
<div class="myinfo">
<div class="name" @click="showPopUp()">
{{ myinfo.cardEmpname }}
</div>
<div
class="desc"
v-if="myinfo.cardMobile && myinfo.cardMobile != ''"
>
<a :href="'tel:' + myinfo.cardMobile">{{ myinfo.cardMobile }}</a>
</div>
</div>
<div class="lookhei" @click="goAIcard()">
<p>去看Ta</p>
</div>
<div class="slide">
<img :src="ossurl + 'ddzsc/images/material/uplogo.png'" alt="" />
</div>
</div>
// 视频底部文字
<div class="video-bottom" @click="showPopUp()">
<div class="myinfo">
<div class="name">@{{ myinfo.cardEmpname }}</div>
<div class="mybranch">
{{ myinfo.branch ? myinfo.branch : "太平洋保险" }}
</div>
<div class="desc">{{ item.sdesc }}</div>
</div>
</div>
//视频时间
<div class="video-time">
<div class="myvideotime">
<van-slider
bar-height="0.1rem"
button-size="0.3rem"
class="ranges"
:id="'myrange' + index"
v-model="values[index].value"
min="0"
:max="max"
@input="onChange(index)"
/>
<div class="videotime" style="color: #fff" :id="'mytime' + index">
<span>{{ cm }}</span>
<span>{{ dm }}</span>
</div>
</div>
</div>
<div
v-if="rytype == '1' && item.essay && item.essay != ''"
class="peiwen"
@click="choosepw(item.essay, item)"
>
<div class="tipPW">
<img
:src="
pictureConfig.transmitWord
? getossurl + pictureConfig.transmitWord
: getossurl + 'ddzsc/images/snoTitle/wzpw.png'
"
alt
class="img"
/>
</div>
</div>
</swiper-slide>
</swiper>
轮播配置 :
swiperOption: {
loop: false,
direction: "vertical", // 垂直轮播
mousewheelControl: true, // 鼠标控制切换
autoplay: false, // 停止自动轮播
allowSwipeToPrev: true, // 向上滑动
onSlideChangeEnd: function (swiper) {
that.showrange1 = true;
if (that.videoList.length - swiper.activeIndex == 1) {
that.touchMove();
}
that.stopVideo(swiper.activeIndex);
that.values.forEach((item) => {
item.value = 0;
});
},
}, // 轮播
videoList : 轮播数组接口中获取
this.videoList = [...this.videoList, ...res.data.data];
showStop :视频暂停播放方法
// 视频暂停
showStop(ev, index) {
var ev = ev || event;
this.prevent(ev);
let vdo = document.getElementById(`myVideo${index}`);
vdo.pause(); // 视频暂停播放 原生方法
$(".playbtn").show(); // 播放按钮展示
this.isbf = false;
},
playVideo: 视频开始
playVideo(ev, index) {
// ev把事件对象传进去
var ev = ev || event;
this.prevent(ev);
let that = this;
let vdo = document.getElementById(`myVideo${index}`);
vdo.play();
if (index == 0) {
$(`#myrange${index}`).show();
$(`#mytime${index}`).show();
}
this.isbf = true;
$(".playbtn").hide();
$(".showimg").hide();
this.numVideo = 2;
// 监听时评播放完成,展示弹框
vdo.addEventListener("ended", function () {
$(".playbtn").show();
});
},
手指上下滑动视频
touchMove() {
gunDVideo({ sno: this.osno, empno: this.empno })
.then((res) => {
this.videoList = [...this.videoList, ...res.data.data]; //上拉加载
this.$forceUpdate();
this.values = [];
this.videoList.forEach((item) => {
this.values.push({ value: 0 });
});
this.osno = this.videoList[this.videoList.length - 1].sno;
})
.catch((error) => {
Toast.hide();
});
},
视频停止播放
stopVideo(index, type) {
this.addwxqrcode = false;
let videoItem = this.videoList[index];
this.current++;
window.document.title = this.videoList[index].stitle; // 视频title名称
$(".swiper .swiper-slide video").trigger("pause"); // 其他视频暂停
$(".playbtn").show(); // 播放按钮展示
this.$nextTick(() => {
let vdo = document.getElementById(`myVideo${index}`);
vdo.currentTime = 0; // 从头重新播放
// 安卓直接播放
// ios播放
if (!type) {
$("#showimgBtn" + index).hide();
$("#playbtn" + index).hide(); // 自动播放时播放按钮隐藏
if (window.WeixinJSBridge) {
this.doPlay(vdo);
} else {
document.addEventListener(
"WeixinJSBridgeReady",
function () {
this.doPlay(vdo);
},
false
);
}
}
this.getrange(index);
});
},
// 初始化进度条
getrange(index) {
$(".ranges").hide();
$(".videotime").hide();
let vdo = document.getElementById(`myVideo${index}`);
this.max = vdo.duration;
let dmm =
Math.floor(vdo.duration / 60) >= 10
? Math.floor(vdo.duration / 60)
: "0" + Math.floor(vdo.duration / 60);
let dms =
Math.floor(vdo.duration % 60) >= 10
? Math.floor(vdo.duration % 60)
: "0" + Math.floor(vdo.duration % 60);
this.dm = vdo.duration ? dmm + ":" + dms : "00:00";
if (index != 0 || this.showrange1) {
$(`#myrange${index}`).show();
$(`#mytime${index}`).show();
}
//监听视频的时间更新事件timeupdate并在事件回调函数中更新进度条和时间显示
vdo.addEventListener("timeupdate", () => {
this.max = vdo.duration;
let dmm =
Math.floor(vdo.duration / 60) >= 10
? Math.floor(vdo.duration / 60)
: "0" + Math.floor(vdo.duration / 60);
//总时长除以60,得到分钟数向下取整 ,大于等于10直接去,否则在前面添加0
let dms =
Math.floor(vdo.duration % 60) >= 10
? Math.floor(vdo.duration % 60)
: "0" + Math.floor(vdo.duration % 60);
this.dm = vdo.duration ? dmm + ":" + dms : "00:00";
// 更新进度条
this.values[index].value = vdo.currentTime;
let cmm =
Math.floor(vdo.currentTime / 60) >= 10
? Math.floor(vdo.currentTime / 60)
: "0" + Math.floor(vdo.currentTime / 60);
let cms =
Math.floor(vdo.currentTime % 60) >= 10
? Math.floor(vdo.currentTime % 60)
: "0" + Math.floor(vdo.currentTime % 60);
this.cm = cmm + ":" + cms;
});
},
微信浏览器中 JSBridge 就绪事件的方法
初始化操作 : this.stopVideo(0, true);
//微信浏览器中的某个 API 调用,目的是获取网络类型。
doPlay(video) {
WeixinJSBridge.invoke("getNetworkType", {}, function (e) {
video.play();
});
},
拖动进度条改变视频进度
onChange(index) {
let vdo = document.getElementById(`myVideo${index}`);
if (vdo) {
vdo.currentTime = this.values[index].value;
}
},
剩余的样式部分
<style>
.van-slider__button {
width: 0.5rem !important;
height: 0.5rem !important;
}
</style>
<style scoped lang="stylus">
.videobottom {
height: 3rem;
width: 100%;
margin-top: -2rem;
position: relative;
z-index: 1;
}
.videotime {
color: #fff;
display: flex;
justify-content: space-between;
}
.videotime span {
padding: 0.1rem 0.3rem;
}
.content {
width: 100%;
height: 100%;
position: absolute;
background-color: #000;
}
.video {
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
.esVideo {
width: 100%;
max-height: 100vh;
display: inline-block;
vertical-align: middle;
}
}
.imgstyle {
width: 100%;
height: 100%;
// position: absolute;
top: 0%;
// top: -49.24%;
left: 0%;
.showimg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: auto;
// display: none;
// z-index: 100;
}
}
.video-top {
width: 90%;
box-sizing: border-box;
position: absolute;
top: 1rem;
left: 5%;
display: flex;
justify-content: space-between;
align-items: center;
color: #fff;
.hrardimg {
width: 12%;
img {
width: 100%;
height: auto;
border-radius: 50%;
}
}
.myinfo {
width: 60%;
padding: 0 0.3rem 0 0.3rem;
box-sizing: border-box;
.name {
font-size: 42px;
padding-bottom: 0.04rem;
}
.desc {
font-size: 34px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
a {
text-decoration: none;
color: #fff;
}
}
}
.lookhei {
width: 28%;
p {
font-size: 0.36rem;
padding: 0.1rem 0.5rem 0.11rem;
background-color: #005bac;
float: right;
border-radius: 0.2rem;
}
}
}
.video-bottom {
width: 100%;
box-sizing: border-box;
position: absolute;
bottom: 2.6rem;
padding: 0 0.6rem;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
.myinfo {
width: 90%;
box-sizing: border-box;
.name {
font-size: 40px;
padding-bottom: 0.1rem;
letter-spacing: 0.03rem;
display: inline-block;
margin-right: 0.2rem;
font-weight: bold;
}
.mybranch {
display: inline;
font-size: 0.26rem;
}
.desc {
font-size: 38px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
a {
text-decoration: none;
color: #fff;
}
}
}
}
.peiwen {
position: relative;
}
.peiwen /deep/ .tipPW {
position: absolute !important;
}
.video-time {
width: 100%;
box-sizing: border-box;
position: absolute;
bottom: 1rem;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
.myvideotime {
width: 100%;
}
}
.md-popup-box {
// height: 5rem;
.mycard {
width: 100%;
position: relative;
color: #fff;
padding: 2rem 0 0rem;
.close {
position: absolute;
top: 2.6rem;
right: 0.3rem;
}
.line-box {
padding: 0 0.6rem;
background-color: #343740;
.headimg {
position: absolute;
top: 1.4rem;
left: 0.3rem;
width: 2rem;
height: auto;
border-radius: 50%;
}
.name {
margin-left: 2.3rem;
padding-top: 0.6rem;
font-size: 50px;
letter-spacing: 3px;
}
.mycard-info {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0.4rem 0 0.25rem;
.left {
.phone {
font-size: 34px;
padding-bottom: 0.1rem;
letter-spacing: 3px;
a {
text-decoration: none;
color: #fff;
}
}
.desc {
font-size: 30px;
a {
text-decoration: none;
color: #fff;
}
}
}
.right {
.tel {
width: 1rem;
height: 1rem;
font-size: 36px;
vertical-align: baseline;
margin-right: 0.2rem;
}
.erweima {
width: 1rem;
height: 1rem;
font-size: 36px;
vertical-align: baseline;
}
}
}
.line {
margin: 0.2rem 0 0.6rem;
border-bottom: 1px solid #888B94;
}
.pdesc {
color: #8D9099;
font-size: 30px;
padding-bottom: 0.6rem;
word-break: break-all;
line-height: 0.65rem;
}
}
}
}
.getMore {
background-color: #131811;
padding: 1rem;
.more {
width: 80%;
margin-left: 10%;
background-color: #50525F;
border-radius: 0.2rem;
color: #fff;
text-align: center;
padding: 0.2rem 0;
font-size: 46px;
}
}
.playbtn {
height: 3em;
width: 3em;
// line-height: 2em;
// border-radius: 1em;
position: absolute;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.addwxshow {
background-color: #ffffff;
border-radius: 5%;
padding: 0.5rem 0.3rem;
.qrcodeimg {
width: 2.4rem;
height: 2.4rem;
margin: 0rem auto;
margin-bottom: 0.5rem;
// z-index:999
}
.qrcodeText {
text-align: center;
}
}
.erweim {
z-index: 2000 !important;
}
#array {
position: absolute;
z-index: 999;
-webkit-animation: start 1.5s infinite ease-in-out;
}
/deep/.swiper-slide-active {
height: 674px;
}
.slide {
width: 5%;
position: absolute;
left: 47.5%;
bottom: 3rem;
}
@keyframes bounceInDown {
0%, 60%, 75%, 90%, to {
-webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
0% {
opacity: 1;
-webkit-transform: translate3d(0, 0px, 0) scaleY(0.9);
transform: translate3d(0, 0px, 0) scaleY(0.9);
}
25% {
opacity: 0.6;
-webkit-transform: translate3d(0, 30px, 0) scaleY(0.9);
transform: translate3d(0, 30px, 0) scaleY(0.9);
}
50% {
opacity: 0.4;
-webkit-transform: translate3d(0, 50px, 0) scaleY(0.9);
transform: translate3d(0, 50px, 0) scaleY(0.9);
}
60% {
opacity: 0.8;
-webkit-transform: translate3d(0, 60px, 0) scaleY(0.985);
transform: translate3d(0, 60px, 0) scaleY(0.985);
}
90% {
opacity: 1;
-webkit-transform: translate3d(0, -10px, 0) scaleY(0.985);
transform: translate3d(0, -10px, 0) scaleY(0.985);
}
}
.slide {
-webkit-animation: bounceInDown 2s ease-in-out 1 forwards;
animation: bounceInDown 2s ease-in-out 1 forwards;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
// 配文
.tipPW {
position: fixed;
right: 0;
bottom: 5.5rem;
width: 2.5rem;
// text-align: right;
// padding: 0 0.2rem;
// height: 0.9rem;
// line-height: 0.9rem;
// background-color: #11579d;
// color: #fff;
// font-weight: bold;
// font-size: 0.4rem;
// border-bottom-left-radius: 1rem;
// -moz-border-radius-bottomleft: 1rem;
// -webkit-border-bottom-left-radius: 6rem;
// border-top-left-radius: 1rem;
// -moz-border-radius-topleft: 1rem;
// -webkit-border-top-left-radius: 6rem;
z-index: 99;
.img {
width: 100%;
height: auto;
// width: 0.6rem;
// height: 0.6rem;
// position: absolute;
// left: 0.3rem;
// top: 0.15rem;
}
}
.popbox {
height: 9rem;
background-color: #fff;
overflow-y: auto;
padding: 0 20px;
}
.button {
width: 80%;
height: 1.3rem;
text-align: center;
line-height: 1.3rem;
font-size: 0.5rem;
background: color-primary;
color: #fff;
font-weight: 600;
position: absolute;
bottom: 0.4rem;
left: 10%;
border-radius: 0.15rem;
}
.text p {
margin-top: 0.5rem;
font-size: 0.45rem;
}
.top {
height: 1.5rem;
line-height: 1.5rem;
font-size: 18px;
color: black;
text-align: center;
border-bottom: 1px solid #efefef;
}
.top span {
display: inline-block;
font-size: 0.47rem;
}
.close {
float: right;
padding-right: 10px;
font-size: 18px;
color: color-primary;
}
.pw {
position: relative;
left: 20px;
}
pre {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
}
</style>