模仿ios浏览器底部弹框效果。
遮罩层淡入淡出,弹框高度根据内容自适应。

  1. <!-- popup-bottom.wxml -->
  2. <view class="wrap" hidden="{{!myVisible}}">
  3. <view class="mask {{visible ? \'mask-show\' : \'\'}}" bindtap="_onCancel"></view>
  4. <view class="box" id="modal-box" animation="{{animationData}}">
  5. <slot />
  6. </view>
  7. </view>
  1. // popup-bottom.js
  2. Component({
  3. properties: {
  4. myVisible: {
  5. type: Boolean,
  6. value: false,
  7. observer: \'_visibleChange\',
  8. },
  9. },
  10. data: {
  11. visible: false,
  12. animation: null,
  13. animationData: null,
  14. },
  15. ready: function () {
  16. const animation = wx.createAnimation({
  17. duration: 200,
  18. timingFunction: "linear",
  19. delay: 0,
  20. });
  21. this.setData({
  22. animation,
  23. })
  24. },
  25. methods: {
  26. _visibleChange: function (newVal, oldVal, changedPath) {
  27. if (oldVal === false && newVal === true) {
  28. setTimeout(function () {
  29. this._onShow();
  30. }.bind(this), 0)
  31. }
  32. },
  33. _onShow: function () {
  34. const __this = this;
  35. const query = wx.createSelectorQuery().in(this);
  36. query.select(\'#modal-box\').boundingClientRect(function (res) {
  37. const { animation } = __this.data;
  38. animation.translateY(-res.height).step();
  39. __this.setData({
  40. visible: true,
  41. animationData: animation.export(),
  42. })
  43. }).exec();
  44. },
  45. _onCancel: function () {
  46. const { animation } = this.data;
  47. animation.translateY(0).step();
  48. this.setData({
  49. visible: false,
  50. animationData: animation.export(),
  51. })
  52. setTimeout(function () {
  53. this.triggerEvent(\'myOnCancel\');
  54. }.bind(this), 200)
  55. },
  56. },
  57. })
  1. /* popup-bottom.wxss */
  2. .wrap {
  3. position: fixed;
  4. left: 0;
  5. top: 0;
  6. z-index: 99999;
  7. width: 100vw;
  8. height: 100vh;
  9. }
  10. .mask {
  11. position: fixed;
  12. top: 0;
  13. left: 0;
  14. z-index: 1;
  15. width: 100%;
  16. height: 100%;
  17. background: #000;
  18. opacity: 0;
  19. transition: 0.2s;
  20. }
  21. .mask-show {
  22. opacity: 0.4;
  23. }
  24. .box {
  25. position: fixed;
  26. top: 100vh;
  27. left: 0;
  28. z-index: 2;
  29. width: 100%;
  30. min-height: 100rpx;
  31. background: #fff;
  32. }
  1. {
  2. "component": true,
  3. "usingComponents": {}
  4. }
  1. <button bindtap="handleShow">点我弹出popup</button>
  2. <popup-bottom myVisible="{{visible}}" bindmyOnCancel="handleCancel">
  3. <view>我是内容</view>
  4. <view>我是内容</view>
  5. <view>我是内容</view>
  6. <view>我是内容</view>
  7. <view>我是内容</view>
  8. </popup-bottom>
  1. Page({
  2. data: {
  3. visible: false,
  4. },
  5. handleShow: function () {
  6. this.setData({ visible: true });
  7. },
  8. handleCancel: function () {
  9. this.setData({ visible: false });
  10. },
  11. })
  1. {
  2. "navigationBarTitleText": "底部弹框",
  3. "usingComponents": {
  4. "popup-bottom": "/components/popup-bottom/popup-bottom"
  5. }
  6. }

版权声明:本文为whosmeya原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/whosmeya/p/12557510.html