前言
近期对前段时间做的电商小程序的商品详情做了一些优化,主要涉及到视频播放和底部弹起弹框,因此来做一下总结
视频组件化
视频在电商系统中,是一个很常见的功能,在很多地方都会用到,因此,可以封装成一个组件,以供多处使用,当页面滑动的过程中,视频进入不可见区域,视频暂停播放
WXML
<view class="video-box">
<video class='c_video' id="myVideo" src="{{videoUrl}}" controls show-center-play-btn='{{false}}' wx:if='{{!showCover}}' show-fullscreen-btn='{{false}}' bindended='playEnd' show-play-btn='{{false}}'>
<image class='pause_img' src='/static/newIcon/video-{{isPlay ? "pause":"play"}}.png' bindtap="play"></image>
</video>
<view class="controls f_row f_r_cnt f_jc_cnt" bindtap='toPlay' wx:else='{{showCover}}'>
<image lazy-load src="{{coverUrl}}" class='slide_img' />
<image class='pause_img' src='/static/newIcon/video-play.png'></image>
</view>
</view>
js
Component({
properties: {
//视频url
videoUrl: {
type: String,
value: ''
},
//视频封面图
coverUrl: {
type: String,
value: ''
}
},
lifetimes: {
attached() {
//可以自动"观察"元素是否可见
//wx.createIntersectionObserver(Object component, Object options)
/**创建并返回一个 IntersectionObserver 对象实例。在自定义组件或包含自定义组件的页面中,应使用
*this.createIntersectionObserver([options]) 来代替
**/
this._observer = this.createIntersectionObserver()
this._observer.relativeToViewport()
.observe('.video-box', (res) => {
if(this.data.isPlay){
this.setData({
isPlay:false
})
this.videoCtx.pause()
}
})
}
},
data: {showCover: true},
methods: {
//点击播放按钮,封面图片隐藏,播放视频
toPlay(e) {
if (!this.videoCtx) {
//wx.createVideoContext(string id, Object this)用于创建video上下文
/**
id video组件的id
this 在自定义组件下,当前组件实例的this,以操作组件内 video 组件
**/
this.videoCtx = wx.createVideoContext('myVideo', this)
}
this.videoCtx.play()
this.setData({
showCover: false,
isPlay: true
})
},
//暂停、播放视频
play() {
let {
isPlay
} = this.data
isPlay = !isPlay
this.setData({
isPlay: isPlay
})
if (isPlay) {
this.videoCtx.play()
} else {
this.videoCtx.pause()
}
},
//视频播放完成以后 显示视频封面图
playEnd() {
this.setData({
showCover: true
})
}
}
})
小程序对IntersectionObserver对象和视频都进行了部分封装,使用起来也比较方便
具体的IntersectionObserver API的使用方法可以查看:www.ruanyifeng.com/blog/2016/1…
底部动画弹框
底部弹框也是相对而言一个很常见的功能,但是太过生硬的弹框,会给人一种不好的体验, 所以一般在做弹框的过程中,会给弹框添加一些动画特效,优化用户体验(一般弹框都会是fixed或者absolute不存在文档流中,所以不存在回流,对性能影响不大),这里实现底部动画弹框,主要用到的是transform 和 transition,这个也经常用到,也可以封装成组件的形式
WXML
<view class="pop_prop_box {{showShare ? 'm_slideUp':''}}" catchtouchmove='preventClose' >
<view class="mask" bindtap='closePopup'></view>
<view class="m_bot_box f_col">
<view class="service_titile" wx:if='{{viewTitle}}'>
<text class="txt">{{viewTitle}}</text>
</view>
<image class="icon-close" src='/static/newIcon/goods-close.png' bindtap="closePopup" wx:if='{{showCloseIcon}}'></image>
<slot></slot>
<view class='service_finish bgb_color' bindtap="closePopup" wx:if='{{showFinish}}'>完成</view>
</view>
</view>
WXSS
.pop_prop_box {
position: fixed;
width: 100%;
z-index: 99;
bottom: 0;
left: 0;
}
.mask {
width: 100%;
height: 100%;
bottom: 0;
left: 0;
position: fixed;
background: rgba(0, 0, 0, 0.5);
transition: all 0.3s ease-in-out;
z-index: 99;
display: none;
}
.m_slideUp .mask{
display: block;
}
.m_bot_box {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
box-sizing: border-box;
transition: all 0.3s ease-in-out 0.08s;
transform: translate3d(0, 200%, 0);
z-index: 101;
background: #fff;
color: #333;
border-radius: 16rpx 16rpx 0 0;
}
.m_slideUp .m_bot_box {
transform: translate3d(0, 0, 0);
}
这里简单的运用 transform 和 transition的基本特性,实现了简单的向上弹起的动效,左右动画也差不多的方法,有兴趣的人可以去用一个其他特性,另外这种方式实现的时候要注意position:fixed定位生效的背景,有需要了解的同学,可以看一下这片文章:www.cnblogs.com/coco1s/p/73…
总结
这次实现视频组件化和顶部动画弹框,让我对css3 的动画特性,有了更深刻的了解,以及IntersectionObserver API的基本使用和功能,积累更多的知识,以便解决更多的需求和问题