描述
模仿ios浏览器底部弹框效果。
遮罩层淡入淡出,弹框高度根据内容自适应。
效果
源码
popup-bottom.wxml
<!-- popup-bottom.wxml -->
<view class="wrap" hidden="{{!myVisible}}">
<view class="mask {{visible ? 'mask-show' : ''}}" bindtap="_onCancel"></view>
<view class="box" id="modal-box" animation="{{animationData}}">
<slot />
</view>
</view>
popup-bottom.js
// popup-bottom.js
Component({
properties: {
myVisible: {
type: Boolean,
value: false,
observer: '_visibleChange',
},
},
data: {
visible: false,
animation: null,
animationData: null,
},
ready: function () {
const animation = wx.createAnimation({
duration: 200,
timingFunction: "linear",
delay: 0,
});
this.setData({
animation,
})
},
methods: {
_visibleChange: function (newVal, oldVal, changedPath) {
if (oldVal === false && newVal === true) {
setTimeout(function () {
this._onShow();
}.bind(this), 0)
}
},
_onShow: function () {
const __this = this;
const query = wx.createSelectorQuery().in(this);
query.select('#modal-box').boundingClientRect(function (res) {
const { animation } = __this.data;
animation.translateY(-res.height).step();
__this.setData({
visible: true,
animationData: animation.export(),
})
}).exec();
},
_onCancel: function () {
const { animation } = this.data;
animation.translateY(0).step();
this.setData({
visible: false,
animationData: animation.export(),
})
setTimeout(function () {
this.triggerEvent('myOnCancel');
}.bind(this), 200)
},
},
})
popup-bottom.wxss
/* popup-bottom.wxss */
.wrap {
position: fixed;
left: 0;
top: 0;
z-index: 99999;
100vw;
height: 100vh;
}
.mask {
position: fixed;
top: 0;
left: 0;
z-index: 1;
100%;
height: 100%;
background: #000;
opacity: 0;
transition: 0.2s;
}
.mask-show {
opacity: 0.4;
}
.box {
position: fixed;
top: 100vh;
left: 0;
z-index: 2;
100%;
min-height: 100rpx;
background: #fff;
}
popup-bottom.json
{
"component": true,
"usingComponents": {}
}
使用
test.wxml
<button bindtap="handleShow">点我弹出popup</button>
<popup-bottom myVisible="{{visible}}" bindmyOnCancel="handleCancel">
<view>我是内容</view>
<view>我是内容</view>
<view>我是内容</view>
<view>我是内容</view>
<view>我是内容</view>
</popup-bottom>
test.js
Page({
data: {
visible: false,
},
handleShow: function () {
this.setData({ visible: true });
},
handleCancel: function () {
this.setData({ visible: false });
},
})
test.json
{
"navigationBarTitleText": "底部弹框",
"usingComponents": {
"popup-bottom": "/components/popup-bottom/popup-bottom"
}
}