小程序模仿抖音
效果图:
一开始思路是使用swiper来实现上下滑的效果,并且在swiper-item里嵌套video,但是一直有莫名其妙的问题,后来在小程序API文档里也看到video无法在swiper中使用。转换思路改成监听用户上下滑,view上绑定如下事件
bindtouchstart="touchstart" bindtouchmove="touchmove" bindtouchend="touchend"
来判断用户是否上下滑
html部分:
<!--pages/index/index.wxml-->
<!-- start 视频区域 -->
<view class='middle' bindtouchstart="touchstart" bindtouchmove="touchmove" bindtouchend="touchend">
<view class='videoBox' style='height:100%;width:100%'>
<video style='height:100%;width:100%' src="{{curvideo}}" controls='false' autoplay="true" id='video0' loop="true" bindtap='pauseVideo' bindtimeupdate="videoProgress">
<!-- start 导航部分 -->
<cover-view class='navBtns'>
<block wx:for="{{typeList}}" wx:for-item="item" wx:for-index="index" >
<cover-view class='{{index==typeChooseIndex?"active":""}} typeButton' data-index='{{index}}' catchtap='styleClick'>
{{item.name}}</cover-view>
</block>
<cover-view class='colorBtns'>
<block wx:for="{{colorList}}" wx:for-item="item" wx:for-index="index" >
<cover-view class='{{index==colorChooseIndex?"active":""}} colorbutton' data-index="{{index}}" catchtap='colorClick' >{{item.colorName}}</cover-view>
</block>
</cover-view>
</cover-view>
<!-- end 导航部分 -->
<!-- start 详情区 -->
<cover-view class='detail'>
<!-- start 左侧详情区 -->
<cover-view class='detailLeft'>
<cover-view class='catCon'>
<cover-view>#品种:{{curCat.typeName}}</cover-view>
<cover-view>#颜色:{{curCat.colorName}}</cover-view>
</cover-view>
<block wx:if="{{curCat.saleStatus==1}}">
<button class='reserve' data-catid="{{curCat.id}}" catchtap='goreserve'>继续支付</button>
</block>
<block wx:if="{{curCat.saleStatus==2}}">
<button class='reserve' data-catid="{{curCat.id}}" catchtap='goreserve'>立即预订</button>
</block>
<block wx:else>
<button class='sold'>已出售</button>
</block>
</cover-view>
<!-- end 左侧详情区 -->
<!-- start 右侧love分享区 -->
<cover-view class='detailRight'>
<cover-view class='detailRightCon'>
<cover-view class='loveCon {{curCat.likeStatus==1?"active":""}}'
catchtap='likeEnt'><!-- 点击喜欢 active-->
<cover-image src='../images/love1.png'></cover-image>
<cover-image src='../images/love2.png'></cover-image>
</cover-view>
<cover-view class='loveNum'>{{curCat.likeNum}}</cover-view>
<cover-view class='shareCon'>
<cover-image src='../images/shareIcon.png'></cover-image>
<button open-type='share' title="袖虎宠物" class='shareBtn'>转发</button>
</cover-view>
<cover-view class='shareNum'>{{curCat.shareNum}}</cover-view>
</cover-view>
</cover-view>
<!-- end 右侧love分享区 -->
<!-- start 底部导航 -->
<cover-view class='bottom clear' catchtap=''>
<cover-view class='vProgress' style='width:{{vProgress}}%'></cover-view>
<cover-view class='bottomBorder'></cover-view>
<button class='active'>首页</button>
<cover-view class='space'></cover-view>
<button open-type='getUserInfo' bindgetuserinfo="bindGetUserInfo" catchtap='goCenter'>我的</button>
</cover-view>
<!-- end 底部导航 -->
</cover-view>
<!-- end 详情区 -->
<!--start 操作提示 -->
<cover-view class='mask {{maskStatus}}' catchtap='closeMask'>
<cover-image src='../images/type2.png' class='tipTop'></cover-image>
<cover-image src='../images/up2.png' class='tipBottom'></cover-image>
</cover-view>
<!--start 操作提示 -->
<!-- start 视频播放按钮 -->
<cover-view class='videoBtn {{videoBtnStatus}}' catchtap='playVideo'>
<cover-image src='../images/pause.png' class='videoBtnIcon'></cover-image>
</cover-view>
<!-- end 视频播放按钮 -->
</video>
</view>
</view>
<!-- end 视频区域 -->
css部分:
/* pages/index/index.wxss */
page{
width: 100%;
height: 100%;
background: #000;
}
swiper,swiper-item{
width: 100%;
height: 900rpx;
}
.videoCon,video{
width: 100%;
height: 100%;
overflow: hidden;
}
.videoCon{
margin-top: 130rpx;
}
.navBtns{
padding-top: 65rpx;
padding-left: 20rpx;
position: fixed;
top: 0rpx;
height: 150rpx;
z-index: 999;
width: 100%;
}
.navBtns .typeButton{
background:rgba(255, 255, 255, 0.5);
display:inline-block;
font-size:14px;
line-height:25px;
width:40px;
height:25px;
margin:2px 5px;
border-radius:5px;
text-align:center;
margin-bottom: 10rpx;
}
.navBtns .typeButton.active{
background: #d82539;
color: #fff;
}
.colorBtns .colorbutton{
display: inline-block;
background: none;
color: rgb(36, 36, 36);
/* border: 1px solid #fff; */
box-shadow: none;
outline: none;
font-size: 24rpx;
/* padding: 5rpx 8rpx; */
padding: 3rpx;
border-radius: 10rpx;
margin:5px 5px;
line-height: 30rpx;
border: 1px solid #fff;
background:rgba(235, 235, 235, 0.5);
text-align: center;
}
.colorBtns .colorbutton.active{
background: none;
border: 1px solid #ffffff;
background:rgba(207, 206, 206, 0.5);
background: #d82539;
color: #fff;
}
.colorBtns .colorbutton::after,.colorbutton .button::before{
border: none;
}
.detailRightCon{
float: right;
margin-right: 10rpx;
width: 80rpx;
height: 220rpx;
overflow: hidden;
}
.loveCon{
width: 180rpx;
height: 60rpx;
}
.loveCon.active{
margin-left: -80rpx;
}
.loveCon cover-image{
float: left;
width: 80rpx;
height: 60rpx;
}
.shareNum,.loveNum{
clear: both;
color: #fff;
font-size: 30rpx;
font-weight: bold;
text-align: center;
padding-right: 5rpx;
}
.shareCon{
height:60rpx;
margin-top: 20rpx;
position: relative;
}
.shareCon cover-image{
width: 77rpx;
height: 62rpx;
}
.shareNum{
display: block;
height: 50rpx;
}
.detailLeft{
float: left;
margin-top: 50rpx;
margin-bottom: 40rpx;
}
.detailRight{
float: right;
}
.catCon{
font-size: 28rpx;
color: #fff;
padding-left: 30rpx;
}
.clear{
clear: both;
}
.catCon button{
display: inline-block;
background: none;
padding: 0px;
font-size: 28rpx;
color: #fff;
line-height: 30rpx;
border-radius: 0rpx;
border: 0rpx;
}
.catCon button::after{
border: none;
}
.catCon{
margin-bottom: 10rpx;
}
.catCon>cover-view{
padding-left: 0rpx;
}
.reserve{
font-size: 28rpx;
background: #f3243b;
color: #fff;
margin-left: 30rpx;
margin-top: 40rpx;
}
.sold{
font-size: 28rpx;
background: #ccc;
color: #fff;
margin-left: 30rpx;
margin-top: 40rpx;
}
.detail{
width: 100%;
position: fixed;
left: 0rpx;
bottom: -2rpx;
height: 360rpx;
}
.bottom button{
width: 50%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background: none;
color: #ccc;
float: left;
font-size: 30rpx;
border-radius: 0rpx;
border-left: 0rpx;
border-right: 0rpx;
border: none;
}
.bottom button::after{
border: none;
border-radius: 0rpx;
/* border-top: 1rpx solid #fff; */
}
.bottom button.active{
/* border-right: 1rpx solid rgba(0, 0, 0, 0.1); */
border-bottom: 2rpx solid #d82539;
font-weight: bold;
color: #d82539;
}
.shareBtn,.shareBtn::after{
background: none;
display: block;
border: none;
outline: none;
height: 120rpx;
width: 90rpx;
line-height:300rpx;
position: absolute;
z-index: 999;
top: 0rpx;
}
.shareBtn .wx-button-cover-view-inner{
height: auto;
overflow: auto;
}
.bottom{
width: 100%;
position: absolute;
bottom: 0rpx;
background: rgba(0, 0, 0, 1);
height: 80rpx;
/* border-top: 1rpx solid rgba(241, 241, 241,0.4); */
}
.bottomBorder{
clear: both;
border-top: 2rpx solid rgba(241, 241, 241,0.4);
}
.videoOut{
position: fixed;
top: 0rpx;
left: 0rpx;
height: 100%;
width: 100%;
}
.bottom .space{
width: 2rpx;
background: rgba(241, 241, 241,0.4);
height:30rpx;
position:absolute;
margin-top:22rpx;
margin-left: 50%;
}
.middle{
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
}
.videoBox{
background: #000;
}
.mask{
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
position: fixed;
z-index: 999;
top: 0rpx;
}
.tipTop{
width:238rpx;
height:225rpx;
position:absolute;
top:43rpx;
left:99rpx;
}
.tipBottom{
width:560rpx;
height:317rpx;
position:absolute;
bottom:513rpx;
left:50%;
margin-left:-280rpx;
}
.videoBtn{
width: 100%;
height: 200rpx;
position: fixed;
top: 615rpx;
z-index: 999;
}
.videoBtnIcon{
width: 120rpx;
height: 100rpx;
display: block;
margin: 0 auto;
}
.vProgress{
height: 2rpx;
background: red;
}
js部分:
// pages/index/index.js
const app = getApp();
var videopage = 0;
var up;
var down;
Page({
/**
* 页面的初始数据
*/
data: {
videoList: [ ],
curvideo: '',
issold: true,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
isnew: true,
typeList: [],
colorList: [],
catList: [],
typeChooseIndex: 0,
colorChooseIndex: 0,
curCat: {},
videoindex: 0,
videoH: 700,
maskStatus:'hide',
videoBtnStatus:'hide'
},
curColorType: '', //选择的颜色
curTypeCode: '', //选择的类型
page: 1, //第几页
pageSize: 20, //每页显示数量
openId: app.openId,
isEnd :false,
isAjax:false,
noDataTip:'暂无数据,切换一个标签吧',
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this;
wx.getSystemInfo({//适配
success: function (res) {
console.info("版本号", +res.SDKVersion.replace(/\./g, ""));
if (+res.SDKVersion.replace(/\./g, "")<=210){
wx.showToast({
title: '您当前微信版本太低,部分功能不支持,请升级到最新微信版本',
icon: 'none',
duration: 10000
})
}
var isPlus = res.model.search("Plus");
var isX = res.model.search("iPhone X");
var ipad = res.model.search("iPad");
if (isX != -1) {
that.setData({
videoH: 1000
})
}
if (isPlus != -1) {
that.setData({
videoH: 800
})
}
if (ipad != -1) {
that.setData({
videoH: 400
})
}
}
})
var that = this;
if (!that.openId) {
that.openId = app.openId
}
app.getDate('api/wechat/queryLabel', {}, function (data) {
var d = data.data;
that.setData({
typeList: data.data,
colorList: d[0].listColor
});
});
that.queryCatList();
//用户第一次显示操作提示
try {
const isfirst = wx.getStorageSync('first');
if (isfirst == 1) {
that.setData({
maskStatus:'hide'
})
}else{
wx.setStorageSync('first', 1);
that.setData({
maskStatus: 'show'
})
}
} catch (e) {
console.info(e);
}
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
this.btnshare();
return {
title: app.data.shareTitle,
path: app.data.sharePath,
}
},
videowait: function () {
wx.showLoading({
title: "拼命加载中...",
})
},
goreserve: function (e) {
var id = e.target.dataset.catid;
wx.navigateTo({
url: '../reserve/reserve?id=' + id
})
},
bindGetUserInfo(e) {
var that = this;
console.log(e.detail.userInfo);
if (!!e.detail.userInfo) {
const userInfo = e.detail.userInfo;
try {
wx.setStorageSync('userInfo', userInfo);
} catch (e) {
console.info(e);
}
that.setData({
isnew: false
})
wx.navigateTo({
url: '../center/center',
})
} else {
that.setData({
isnew: true
})
wx.showToast({
title: '授权失败',
icon: 'none',
duration: 2000
})
console.info("授权失败")
}
},
goCenter: function () {
if (!wx.canIUse('button.open-type.getUserInfo')) {
wx.showToast({
title: '请升级微信版本',
icon: 'none',
duration: 2000
})
}
},
btnshare: function () {
var that = this;
//that.onShareAppMessage;
that.data.curCat.shareNum = that.data.curCat.shareNum + 1;
that.setData({
curCat: that.data.curCat
});
app.getDate('api/wechat/share/' + that.data.curCat.id + '.do', {});
},
/**
* 上面风格点击事件
*/
styleClick: function (e) {
var index = e.target.dataset.index;
var that = this;
var curTypeinfo=that.data.typeList[index];
console.info(index, curTypeinfo, curTypeinfo.listColor);
that.setData({
colorList:curTypeinfo.listColor,
typeChooseIndex:index,
colorChooseIndex: 0
});
videopage=0;
that.curColorType = '';
that.curTypeCode = !curTypeinfo.typeCode ? '' : curTypeinfo.typeCode;
that.data.catList=[];
that.page = 1;
that.isEnd = false;
that.queryCatList();
that.videoPlay(1);
//console.info(e.target.dataset);
},
colorClick: function (e) {
var index = e.target.dataset.index;
var that = this;
var curTypeinfo = that.data.typeList[that.data.typeChooseIndex] ;
var curColor = curTypeinfo.listColor[index];
console.info(curTypeinfo, curColor);
that.curColorType = curColor.colorCode;
that.curTypeCode = curTypeinfo.typeCode;
that.page = 1;
that.setData({
colorChooseIndex: index
})
videopage=0;
that.data.catList = [];
that.page = 1;
that.isEnd = false;
that.queryCatList();
// that.queryCatList();
//console.info(e.target.dataset);
that.videoPlay(1);
},
likeEnt: function (e) {
var that = this;
var curCat = that.data.curCat;
if (curCat.likeStatus == 1) {
curCat.likeStatus = 0;
curCat.likeNum = curCat.likeNum > 0 ? curCat.likeNum - 1 : 0;
} else {
curCat.likeStatus = 1;
curCat.likeNum = curCat.likeNum + 1;
}
that.setData({
catList: that.data.catList,
curCat: curCat
})
app.getDate('api/wechat/updateLike.do', {
catId: curCat.id,
openId: that.openId,
status: curCat.likeStatus
});
},
queryCatList: function () {
var that = this;
if(that.isEnd){
return ;
}
app.getDate('api/wechat/queryVideoCat', {
typeCode: that.curTypeCode,
colorCode: that.curColorType,
page: that.page,
openId: that.openId,
rows: that.pageSize
}, function (data) {
that.page++;
var d = data.data;
if (!d || d.length <= 0) {
that.isEnd=true;
if (that.data.catList.length>0){
videopage=0;
var catList = that.data.catList;
that.setData({
curCat: catList[videopage],
curvideo: catList[videopage].attaEntity[0].url
});
return ;
}
wx.showToast({
title: that.noDataTip,
icon: 'none',
duration: 2000
})
return ;
} else {
if(d.length<that.pageSize){
that.isEnd=true;
}
var tdata=that.data.catList.concat(d);
that.setData({
catList: tdata ,
curCat: tdata[videopage],
curvideo: tdata[videopage].attaEntity[0].url
})
}
});
},
//触摸开始事件
touchstart: function (e) {
var that = this;
//console.log(e.touches[0].clientY)
that.setData({
touchstartY: e.touches[0].clientY
})
this.data.touchstartY = e.touches[0].clientY;
up = false;
down = false;
},
//触摸移动事件
touchmove: function (e) {
// console.log(e)
let touchendY = e.touches[0].clientY;
let touchstartY = this.data.touchstartY;
//向上滑动
if (touchendY - touchstartY <= -40) {
console.log("向上滑动");
up = true;
down = false;
}
//向下滑动
if (touchendY - touchstartY >= 40) {
console.log("向下滑动");
up = false;
down = true;
}
},
//触摸结束事件
touchend: function (e) {
var that = this;
var videoList = that.data.catList;
if (up === true) {
if (videopage >= videoList.length - 1) {
if(that.isEnd){ //如果已经结束了
if (videoList.length <= 0) {
wx.showToast({
title: that.noDataTip,
icon: 'none',
duration: 2000
});
return;
} else {
videopage = 0;
}
}else{ //如果还没有结束,加载下一个
videopage++;
that.queryCatList();
return ;
}
} else {
videopage++;
}
}
if (down === true) {
if (videopage == 0) {
if (videoList.length>0){
videopage = videoList.length-1 ;
}else{
wx.showToast({
title: that.noDataTip,
icon: 'none',
duration: 2000
})
return;
}
} else {
videopage--;
}
}
var curCat = videoList[videopage];
that.setData({
curvideo: curCat.attaEntity[0].url,
curCat: curCat
});
up = false;
down = false;
that.videoPlay(1);
},
//关闭操作提示
closeMask:function(){
var that = this;
that.setData({
maskStatus:'hide'
})
},
//视频暂停与播放封装 status:1播放 2暂停
videoPlay: function (status) {
console.info(status);
var that = this;
var v = wx.createVideoContext("video0");
if (status == 1){//播放
v.play();
that.setData({
videoBtnStatus: 'hide'
})
} else if (status == 2){//暂停
v.pause();
that.setData({
videoBtnStatus:'show'
})
}
},
pauseVideo:function(){
var that = this;
that.videoPlay(2);
},
playVideo:function(){
var that = this;
that.videoPlay(1);
},
videoProgress:function(e){
var that = this;
console.info(e.detail.duration, e.detail.currentTime);
var duration = e.detail.duration;
var currentTime = e.detail.currentTime;
var progress = currentTime / duration*100;
that.setData({
vProgress: progress
})
}
});
本文地址:https://blog.csdn.net/u012011360/article/details/85990811