admin 管理员组

文章数量: 887016

uniapp

uniapp ----小程序上下滑动页面,视频自动播放(完整代码)

<template><view class="box"><f-navbar title="视频详情" navbarType='3'></f-navbar><!-- 注意:这是 H5、微信小程序界面,请勿和 new_index.nvue、index.nvue 混用1. new_index.nvue、index.nvue这两个是App页面2. 另外:data.js 是上一版本留下的假数据,这一版改成了 URL 请求了(如不需要可以删除,也可作为后端请求参考)3. 请各位大神多多留手,我已经把请求内存开到最大了4. 视频 id 切记是字符串类型 --><!-- #ifdef MP --><view class="bgx":style="{height:(windowHeight)+'px',background: 'linear-gradient(to top, rgba('+dataList[k].bkcolor.top+'), rgba('+dataList[k].bkcolor.bottom+'))'}"></view><swiper class="sv-swiper" :style="'width: '+ windowWidth +'px; height: '+ 89 +'%;'" :vertical="true"@animationfinish="animationfinish" @change="change" :current="current" :indicator-dots="false"@touchstart="mpTouchstart" @touchend="mpTouchend"><swiper-item v-for="(item,index) in dataList" :key="index"><view v-if="Math.abs(k-index)<=1" :class="item.font_color==0?'colorFFF':'color101010'"><view><!-- (windowHeight-statusbarH)1.v-if:用于控制视频在节点的渲染数2.muted的默认值是 false,代表默认是禁音视频的3.http-cache默认开启视频缓存4.poster(封面(方案一)):这里的封面默认处理存储在阿里云的视频5.show-loading:这里默认去掉播放转圈的标志v-if="Math.abs(k-index)<=1"--><video v-if="isShow" :id="item.id+''+index" loop autoplay :muted="item.isplay" controls:show-play-btn="false" :custom-cache="false" :http-cache="true" :show-fullscreen-btn="true":show-loading="false" :show-center-play-btn="false" enable-progress-gesture :src="item.path"@ended="ended" @click="tapVideoHover(item.state,$event)":style="'width: '+ windowWidth +'px; height: '+ vplayHei +'rpx;z-index: 9;'":poster="item.bkimg" @fullscreenchange.stop="fullscreenchange"></video><view class="contz  widP100" @click="tapVideoHover(item.state,$event)"><view class="widP100 paddingA20 paddB0 fontSize16 boxSize linHeight40 wordWarp ellipsis">{{item.title}}</view><view class="widP100 fontSize12 paddL20 paddT20 boxSize"><text user-select="auto">{{item.bv}}</text></view><view class="widP100 paddingA20  boxSize display linHeight40 wenzi":style="{height:descHeight+'rpx'}"><view class="fontSize12 texts widP100"><!-- <text :style="{lineHeight: '30rpx'}"class="paddB20">{{item.detail.length>detNum? item.detail.slice(0, (detNum-1)):item.detail}}</text>--><text :id="'getLinehei'+item.id" :style="{lineHeight: '30rpx'}"class="paddB20">{{lineCount>conAll?details:item.detail}}</text><span v-if="lineCount>conAll">{{item.fold ? details:'...'}}<span class="fontSize12 paddL10" @click.stop="foldBtn(item.id)"><span v-show="!item.fold">展开<textclass="iconfont icon-shixinjiantou-xia fontSize12"></text></span><span v-show="item.fold">收起<textclass="iconfont icon-shixinjiantou-shang fontSize12"></text></span></span></span></view></view><!-- item.relation_type 0未关联  1关联健身房  2关联商品(暂时没有) --><view class="kuai widP100 display  fontSize14 marT10":class="item.font_color==0?'colorW':'colorB'" v-if="!item.fold"><text class="FontCenter widP100" v-show="item.relation_type != 0 "@click.stop="goJsf(item.relation_detail.id,item.relation_detail.name,item.relation_type)"><text class="iconfont icon-charulianjie fontSize14"></text><text class="paddL20">{{item.relation_type==1?'运动':'购物'}}</text><textclass="paddL10">|</text><textclass="paddL10">{{item.relation_detail.name}}</text></text></view><view class="paddingA20 boxSize widP100 display" v-show="!item.fold"><image class="widHei36 " :src="item.avatar" @click.stop="goMueber(item.uid)"mode="aspectFill"></image><view class="widP60 marL20 FontLeft " @click.stop="goMueber(item.uid)"><view class="fontSize14 marT10 ">{{item.nickname}}</view><view class="fontSize10 ellipsis widP100">{{item.signature}}</view></view><view class="guanzhu fontSize12 marT10" :class="item.font_color==0?'':'guanzhu1 '"@click.stop="followBtn(item.uid,item.id)">{{item.is_follow==0?'关注':'已关注'}}</view></view><view class="followShare widP100 display " v-if="!item.fold":class="item.font_color==0?'colorW':'colorB'"><view class="" @click.stop="collectORNot(item.id)"><button hover-class="none" :class="item.font_color==0?'colorFFF':'color101010'"><text :class="item.is_collect?'icon-shoucang':'icon-shoucang1'"class="iconfont iconSize20 fontSize20"></text><text class="paddL10">{{item.collect_num}}</text></button></view><view class=""><button open-type="share" hover-class="none":class="item.font_color==0?'colorFFF':'color101010'"><text class="iconfont icon-fenxiang1 iconSize20 fontSize20"></text><text class="paddL10">{{item.share_num}}</text></button></view><view class="" @click.stop="clickComment(item.id)"><button hover-class="none" :class="item.font_color==0?'colorFFF':'color101010'"><text class="iconfont icon-xinxi1 iconSize20 fontSize20"></text><text class="paddL10">{{item.comments_num}}</text></button></view><view class="" @click.stop="likeORNotLike(item.id)"><button hover-class="none" :class="item.font_color==0?'colorFFF':'color101010'"><text :class="item.is_like?'icon-dianzan_kuai':'icon-dianzan'"class="iconfont  iconSize20 fontSize20"></text><text class="paddL10">{{item.like_num}}</text></button></view></view></view><view class="adz widP100 paddL20 paddR20  boxSize marB26 " :style="{height:adHeight+'rpx'}"v-if="!shouldShowAd && !item.fold"><image class="imgz" :src="dataList[k+1].bkimg" mode="aspectFill"></image></view><view class="widP100 paddL20 paddR20  boxSize marB20 adz" v-show="shouldShowAd && !item.fold ":style="{height:adHeight+'rpx'}"><advertising ref="advertising" :type='2'></advertising></view></view></view></swiper-item></swiper><view class="masks" v-if="isShowComment" @click.stop="clickComment(2)"></view><view class="commentBox" v-if="isShowComment"><hb-comment ref="hbComment" @submitComment="submitComment" @del="delVidoeComment" @like="likeBtn"@focusOn="focusOn" @inputOn="inputOn" :deleteTip="'确认删除此条评论吗?'" :vid="vid" :cmData="commentData"v-if="commentData"></hb-comment></view><!-- #endif --></view>
</template><script>// import userList from '../new_index/data.js'//这个是假数据let audo = uni.createInnerAudioContext()audo.loop = trueexport default {data() {return {authorid: '', //他人视频idwindowWidth: 0,windowHeight: 0, // 可视屏幕高度platform: "",model: "",deleteHeight: 0,dataList: [],k: 0,oldVideo: "",voice: "",timeout: "",current: 0,boxStyle: { //视频,图片封面样式🌟💗'height': 0,'width': 0,},isShow: false,showPlay: false, //转轮显示控制rotates: 0, //转轮旋转角度rotateTime: "", //转轮递归事件控制xrotats: "",mpcleartime: "",isClick: false,changeTimeout: "",mptime: 0,mpstartTime: 0,duration: 500,vid: "", //当前视频iduid: uni.getStorageSync('user_id'),statusbarH: 0,adHeight: 200, //适配屏幕高度descHeight: 300, //简介高度vplayHei: 420, //视频高度topHeight: 0,lineCount: 0, //文字占用的行数conAll: 7, //在7行的时候文字隐藏details:'',//截取的文字detNum: 88, //详情文字数量type: 0, //进入状态 0:视频首页(默认) 1:本地2:推荐3:关注 4:作品5:喜欢6:收藏 7:健身房首页gid: 0, //健身房idpageNo: 1, //从首页传过去的页数is_comment: false, //是发布评论 否删除评论isShare: false, //是否分享isShowComment: false, //是否显示评论区commentData: {},readNumer: 193,commentList: [],comment: '', //用户评论内容clientY: 0, //手指滑动方向vertical: true, //是否可以滑动// advInfo: {}, //广告信息count: 1, //在第3条后显示广告page1: 0, //调用接口详情的次数}},components: {},computed: {shouldShowAd: {// 根据计数器的值判断是否应该显示广告get() {return this.count % 3 === 0;},set() {}}},watch: {async k(k, old_k) {// console.log(k, old_k)// #ifndef MPthis.clearToTime();// #endifthis.isShow = falsethis.dataList[old_k].playIng = false; //如果视频暂停,就加载封面this.dataList[old_k].isplay = true;this.dataList[old_k].state = 'pause';// console.log('预留第' + (old_k + 1) + '个视频:' + this.dataList[old_k].id + '' + old_k)// 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行uni.createVideoContext(this.dataList[old_k].id + '' + old_k, this).stop() //如果视频暂停,那么旧视频停止,这里的this.dataList[old_k]._id + '' + old_k,后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题// console.log('已经暂停 --> 第' + (old_k + 1) + '个视频~') //提示this.dataList[k].state = 'play';this.isShow = true;this.xrotats = setTimeout(() => {this.showPlay = true;// #ifndef MPthis.rotateX();// #endif}, 200)// #ifdef MP// 如果是小程序端clearTimeout(this.changeTimeout);this.dataList[k].isplay = false;setTimeout(() => {this.dataList[k].playIng = true;}, 250)if (this.mptime < 0.2) {this.changeTimeout = setTimeout(() => {uni.createVideoContext(this.dataList[this.k].id + '' + this.k, this).play();}, 1400)} else {uni.createVideoContext(this.dataList[this.k].id + '' + this.k, this).play();}// #endifvar p = k + 1;// console.log('预加载第' + (p + 1) + '个视频:' + this.dataList[p].id + '' + p)this.vid = this.dataList[k].id; //全局定义当前视频idthis.onVideoEnd()},count(newValue) {// 计数器变化时,检查是否应该显示广告this.shouldShowAd = newValue % 3 === 0;if (this.shouldShowAd) { //成功后请求广告信息this.getMiniAd();}},},onLoad(option) {// 带参跳转if (option.vid) {this.vid = option.vid;this.type = option.type;this.gid = option.gid;this.pageNo = option.page;this.authorid = option.authorid || '';}this.getVideoDetail(); //刚进入页面加载数据// #ifndef MPthis.rotateX();// #endifthis.getSystemInfoSync();},onShow() {console.log('回到前台');this.uid = uni.getStorageSync('user_id') || '';if (this.dataList.length !== 0) {// #ifdef MPthis.dataList[this.k].state = 'play';uni.createVideoContext(this.dataList[this.k].id + '' + this.k, this).play()// #endif}if (this.isShare) { //判断是否已经分享this.shareVideo();this.isShare = false;}},onShareAppMessage() {console.log('分享-------')this.isShare = true;},onHide() {// #ifdef MPthis.dataList[this.k].state = 'pause';uni.createVideoContext(this.dataList[this.k].id + '' + this.k, this).pause()// #endifconsole.log('到后台');},onReady() {this.getLineNum();},methods: {// 获取视频详情文字占用的行数getLineNum() {setTimeout(() => {uni.createSelectorQuery().in(this).select('#getLinehei' + this.vid).boundingClientRect(rect => {let height = rect.height;let detNum = this.detNum;this.lineCount = parseInt(height / uni.upx2px(30));if (this.lineCount > this.conAll) {  //超出行数 截取文字字数let det = this.dataList[this.k].detail.trim(' ')this.details = det.slice(0,detNum)} }).exec();}, 500)},onVideoEnd() {// 每当视频播放完成时,将计数器加1this.count++;},// 根据手机屏幕的高度适配广告位置getSystemInfoSync() {let datas = uni.getSystemInfoSync();this.platform = datas.platform;this.model = datas.model;this.statusbarH = datas.statusBarHeight;var model = this.modelif (this.platform == 'ios' && (model !== 'iPhone6' || model !== 'iPhone6s' || model !== 'iPhone7' ||model !== 'iPhone8')) {this.deleteHeight = 0 //有 tabbar的 修改这里可以改变视频高度}this.windowWidth = datas.windowWidth;this.windowHeight = datas.windowHeight;this.boxStyle.width = this.windowWidth + 'px'; //给宽度加pxthis.boxStyle.height = this.windowHeight - this.deleteHeight - this.statusbarH; //有 tabbar的 修改这里可以改变视频高度if (datas.windowHeight <= 745) {this.adHeight = 100;this.descHeight = 220;this.conAll = 5;this.detNum = 60;} else {this.adHeight = 220;}},// 获取广告getMiniAd() {this.$refs.advertising[2].getMiniAdv();},// 保证视频可以正常播放fullscreenchange(event) {let v = this.dataList[this.k];// if(v.state!='pause'){}uni.createVideoContext(v.id + '' + this.k, this).play();v.state = 'play';v.isplay = false;},// 跳转健身房goJsf(id, name, type) {if (type == 2) return this.$alert('暂未开放!');this.$jumpMy('/pages/venue/venueDetail?id=' + id + '&name=' + name)},goMueber(uid) {this.$jumpMy('/pages/my/otherHome?otherid=' + uid)},/*封装用户点赞等操作 id:当前视频id res 后台返回的状态1成功0取消 msg提示 type 1点赞 2收藏 3分享 4关注 5评论*/getFunz(id, res, msg = '', type = 1) {const datas = this.dataList.find(item => item.id === id);let num = datas.like_num;switch (type) {case 1:datas.is_like = res;datas.like_num = res ? (num + 1) : (num - 1);break;case 2:num = datas.collect_num;datas.is_collect = res;datas.collect_num = res ? (num + 1) : (num - 1);break;case 3:datas.share_num = datas.share_num + 1;break;case 4:datas.is_follow = res;break;case 5:num = datas.comments_num;datas.is_comment = res;datas.comments_num = res ? (num + 1) : (num - 1);break;}this.$alert(res ? msg + '成功!' : '取消' + msg + '!')},// 视频点赞&& 取消点赞likeORNotLike(id) {this.$myRequest('likeORNotLike', 'POST', {uid: this.uid,video_id: id,}).then(v => {let res = v.data;this.getFunz(id, res, '点赞', 1)})},// 收藏&& 取消收藏collectORNot(id) {this.$myRequest('collectORNot', 'POST', {uid: this.uid,video_id: id,}).then(v => {let res = v.data;this.getFunz(id, res, '收藏', 2)})},// 分享视频shareVideo() {this.$myRequest('shareVideo', 'POST', {vid: this.vid,}).then(v => {let res = v.data;this.getFunz(this.vid, res, '分享', 3)})},// 点击按钮是否关注followBtn(uid, id) {this.$myRequest('followOrNotFollow', 'POST', {id: this.uid,follow_id: uid,}).then(v => {let res = v.data;this.getFunz(id, res, '关注', 4)})},//一开始手指活动的方向fingerstart(e) {this.clientY = e.changedTouches[0].clientY},// 判断页面是上滑还是下滑fingerend(e) {const subY = e.changedTouches[0].clientY - this.clientY;if (subY > 50 || subY < -50) {// if(this.isShowComment) return this.$alert('请先关掉评论区!')if (!this.vertical) return this.$alert('文字收起才可以滑动哦!');}},//文字展开收起的功能foldBtn(id) {this.dataList.forEach(item => {if (item.id == id) {let det = item.detail;item.fold = !item.fold;if (item.fold) {this.detailInfos = det;this.vertical = false; //文字展开后手机禁止滑动} else {this.vertical = true;}}})},// 评论数组转变getTree(data) {let result = [];let map = {};data.forEach(item => {map[item.id] = item;});data.forEach(item => {let parent = map[item.parentId];if (parent) {(parent.children || (parent.children = [])).push(item);} else {result.push(item);}});return result;},// 输入框聚焦focusOn(val) {this.comment = val},// 输入评论inputOn(val) {this.comment = val;},// 点击评论按钮clickComment(id) {//0不能评论  1能if (this.dataList[this.k].can_comment == 0) return this.$alert('未开启评论功能!');// this.getcommentData();this.isShowComment = !this.isShowComment;},// 提交评论并清除记忆submitComment() {this.is_comment = true;this.getFunz(this.vid, this.is_comment, '评论', 5)},// 删除评论delVidoeComment(cid) {this.is_comment = false;this.getFunz(this.vid, this.is_comment, '评论', 5)},// 评论点赞 id评论idlikeBtn(id) {},// 点击空白返回并保存记忆clickOther(e) {this.isShowComment = false;},// 点击评论事件clickCommentlist(e) {console.log('1111', e);},// 点击头像/用户名称事件clickUser(e) {console.log(e);},mpTouchend() {this.mptime = (new Date() / 1000) - this.mpstartTime;},mpTouchstart() {this.mpstartTime = (new Date() / 1000);},dealVoice() {uni.showToast({title: '处理声音',icon: 'none'})},clearToTime() {//清理定时器for (let i = 0; i < 20; i++) {clearTimeout(this.rotateTime);clearTimeout(this.xrotats);this.showPlay = false;this.rotates = 0;}},clearTime() {//清理定时器for (let i = 0; i < 20; i++) {clearTimeout(this.rotateTime);clearTimeout(this.xrotats);}},rotateX() {// clearTimeout(this.rotateTime);this.rotateTime = setTimeout(() => {this.rotateX();this.showPlay = true;this.rotates += 1;}, 30)},closeScrollview() {// 点击评论里面的叉叉,就会关闭评论this.$refs.pinglun.close();},ended() {// 1.播放当前视频结束时触发,自动切换下一个视频// this.current = this.k+1},//点击播放&&暂停tapVideoHover(state, event) {console.log('state--', state);if (state == 'play' || state == 'continue') {this.dataList[this.k].state = 'pause';} else {this.dataList[this.k].state = 'continue';}if (this.dataList[this.k].state == 'continue') {this.isClick = true;this.dataList[this.k].playIng = trueuni.createVideoContext(this.dataList[this.k].id + '' + this.k, this).play(); //暂停以后继续播放// #ifdef MPthis.dataList[this.k].isplay = false// #endif}if (this.dataList[this.k].state == 'pause') {uni.createVideoContext(this.dataList[this.k].id + '' + this.k, this).pause(); //暂停以后继续播放// #ifdef MPthis.dataList[this.k].isplay = true// #endif}},change(event) {this.k = event.detail.current},animationfinish(event) {// 1.这里进行判断,如果是最后一个视频就进入 get() 方法加载视频进入列表if (this.k == this.dataList.length - 1) {this.GETVideoDetail();}},//每一组结束时新的请求GETVideoDetail() {this.pageNo++// 1.这里引入后端请求数据// 需要传的参数let query = {vid: this.vid,uid: this.uid,type: this.type,gid: this.gid || '',area: '',page: this.pageNo,authorid: this.authorid,};this.$myRequest('getVideoDetail1', 'POST', query).then(v => {let datas = v.data;// 2.这里把视频添加到视频列表for (let i = 0; i < datas.length; i++) {this.dataList.push(datas[i])}})},getVideoDetail() {// 1.这里引入后端请求数据// 需要传的参数let query = {vid: this.vid,uid: this.uid,type: this.type,gid: this.gid || '',area: '',page: '',authorid: this.authorid,};this.$myRequest('getVideoDetail1', 'POST', query).then(v => {this.isShow = false;var msg = v.data// 2.这里把视频添加到视频列表for (let i = 0; i < msg.length; i++) {this.dataList.push(msg[i])}// 3.播放当前视频setTimeout(() => {this.isShow = true;// #ifdef MP// 如果是小程序端this.dataList[this.k].isplay = falsethis.dataList[this.k].state = 'play'// #endifthis.dataList[this.k].playIng = truesetTimeout(() => {// #ifdef MPuni.createVideoContext(this.dataList[this.k].id + '' + this.k,this).play()// #endif}, 500)// this.getcommentData();}, 200)this.vid = this.dataList[this.k].id;this.pageNo = this.dataList[0].page;console.log('wwwwww', this.pageNo)})},share() {uni.showToast({title: '分享',icon: 'none'})},cLike(sss) {this.dataList[this.k].like = !this.dataList[this.k].likeconst video = this.dataList[this.k];sss ? video.like_n -= 1 : video.like_n += 1;}}}
</script><style>.boxz {background-color: #000;position: relative;}.wenzi {height: 336rpx;}.contz {/* height: 80%;overflow-y: scroll;position: relative; */position: absolute;/* margin-top: 500rpx; */}.videoPlay,.videoPlay video,.mask1 {width: 100%;height: 420rpx;display: block;/* margin-top: 40rpx; */position: absolute;}.mask1 {background-color: transparent;z-index: 9;}.mask2 {position: absolute;z-index: 99;background-color: transparent;width: 80rpx;height: 80rpx;right: 0;bottom: 0;}/* .videoz1 {position: relative;} */.sv-swiper {position: absolute;width: 100%;left: 0;z-index: 9;}.sv-swiper swiper-item {overflow-y: auto;}/* .sv-swiper swiper-item:nth-child(2),.sv-swiper swiper-item:nth-child(3){margin-top: -200rpx;} */.sv-swiper swiper-item ::-webkit-scrollbar {width: 0 !important;}.bgx {width: 100%;background-color: #000;position: absolute;left: 0;top: 0;}.kuai {height: 72rpx;line-height: 72rpx;}.colorW {background-color: rgba(255, 255, 255, 0.2);}.colorB {background-color: rgba(16, 16, 16, 0.2);}.paddB0 {padding-bottom: 0;}button {font-size: 32rpx;line-height: 80rpx;margin-top: 6rpx;}.guanzhu1 {border: 1px solid #101010;}.videoFullScreen {position: relative;box-sizing: border-box;padding: 0;width: 100vw;height: 100vh;overflow-y: auto;/* height: 100%; */}.videoFullScreen video {width: 100%;object-fit: fill;height: 100%;display: block;}.followShare {/* justify-content: space-around; */height: 90rpx;line-height: 80rpx;/* background-color: rgba(255, 255, 255, 0.2); */z-index: 99;}.followShare view {flex: 1;}.adz {position: fixed;/* padding-bottom: 20rpx; */bottom: 0;left: 0;z-index: 99;}.btnz {float: right;clear: both;}.btnz1 {margin-top: -30rpx;}.fold {text-overflow: -o-ellipsis-lastline;text-overflow: ellipsis;-webkit-box-orient: vertical;display: -webkit-box;overflow: hidden;}.unfold {height: 42%;overflow-y: scroll;position: absolute;z-index: 99;transition: all 0.4s cubic-bezier(0.25, 1, 0.25, 1);}.unfold1 {height: 130rpx;transition: all 0.4s cubic-bezier(0.25, 1, 0.25, 1);}.texts::before {content: '';float: right;height: 80rpx;}
</style>

本文标签: uniapp