小程序下拉选项动画效果

下拉选项模态框,点击时有慢慢下来、收回动画:

**wxml:**

1. <view class='flex_aic nav'>
2.     <view class='nav_li'>
3.       <view bindtap='open_box' data-type='0' class="nav_li_tit {{box_zhiwu?'text_color':''}}">
4.         <text>菜单一</text>
5.         <text class="iconfont icon-xiala {{box_zhiwu?'text_color':''}}"></text>
6.       </view>
7.       <!-- box -->
8.       <view class='zhiwu_box' hidden="{{!box_zhiwu}}">
9.         <view bindtap='open_box' data-type='0' class='box_bg'></view>
10.         <view class='box_list' style="top:{{top}};" animation="{{animationData}}">
11.           <view bindtap='bindtap' data-type='0' wx:for="{{zhiwu_list}}" data-id='{{item.id}}' wx:key="{{item.id}}" class="box_li {{item.id == zhiwu_active?'text_color':''}}">
12.             <text>{{item.title}}</text>
13.              <icon wx:if="{{item.id == zhiwu_active}}" type="success_no_circle" size="15" color="#ED7701"/>
14.           </view>
15.         </view>
16.       </view>
17.       <!-- box end -->
18.     </view>
19.     <view class='nav_li'>
20.       <view bindtap='open_box' data-type='1' class="nav_li_tit {{box_source?'text_color':''}}">
21.         <text>菜单二</text>
22.         <text class="iconfont icon-xiala {{box_source?'text_color':''}}"></text>
23.       </view>
24.       <!-- box -->
25.       <view class='zhiwu_box' hidden="{{!box_source}}">
26.         <view bindtap='open_box' data-type='1' class='box_bg'></view>
27.         <view class='box_list' style="top:{{top}};" animation="{{animationData}}">
28.           <view bindtap='bindtap' data-type='1' wx:for="{{source_list}}" data-id='{{item.id}}' wx:key="{{item.id}}" class="box_li {{item.id == source_active?'text_color':''}}">
29.             <text>{{item.title}}</text>
30.              <icon wx:if="{{item.id == source_active}}" type="success_no_circle" size="15" color="#ED7701"/>
31.           </view>
32.         </view>
33.       </view>
34.       <!-- box end -->
35.     </view>
36.     <view class='nav_li'>
37.       <view bindtap='open_box' data-type='2' class="nav_li_tit {{box_status?'text_color':''}}">
38.         <text>菜单三</text>
39.         <text class="iconfont icon-xiala {{box_status?'text_color':''}}"></text>
40.       </view>
41.       <!-- box -->
42.       <view class='zhiwu_box' hidden="{{!box_status}}">
43.         <view bindtap='open_box' data-type='2' class='box_bg'></view>
44.         <view class='box_list' style="top:{{top}};" animation="{{animationData}}">
45.           <view bindtap='bindtap' data-type='2'  wx:for="{{status_list}}" data-id='{{item.id}}' wx:key="{{item.id}}" class="box_li {{item.id == status_active?'text_color':''}}">
46.             <text>{{item.title}}</text>
47.              <icon wx:if="{{item.id == status_active}}" type="success_no_circle" size="15" color="#ED7701"/>
48.           </view>
49.         </view>
50.       </view>
51.       <!-- box end -->
52.     </view>
53.
54.   </view>

**wxss:(仅供参考)**

1. .nav {
2.   height: 50px;
3.   padding: 20px 10px;
4.   background-color: #fff;
5.   border-bottom: 1px solid #eee;
6.   font-size: 30rpx;
7.   position: relative;
8. }
9.
10. .nav_li {
11.   border-right: 1px solid #ccc;
12.   padding: 0 10px;
13.   margin: 10px 0;
14.   line-height: 1;
15. }
16.
17. .nav_li_tit {
18.   margin-left: 10px;
19. }
20.
21. .nav_li_tit .icon-xiala {
22.   margin-left: 5px;
23.   color: #d3d3d3;
24. }
25.
26. .zhiwu_box {
27.   position: absolute;
28.   top: 50px;
29.   left: 0;
30.   overflow: hidden;
31.   width: 100vw;
32.   z-index: 1;
33. }
34.
35. .box_bg {
36.   position: fixed;
37.   top: 60px;
38.   left: 0;
39.   width: 100vw;
40.   height: calc(100vh - 50px);
41.   background-color: rgba(0, 0, 0, 0.5);
42.   z-index: 1;
43. }
44.
45. .box_list {
46.   position: relative;
47.   left: 0;
48.   top: 0;
49.   z-index: 2;
50.   background-color: #fff;
51. }
52.
53. .box_li {
54.   width: 100%;
55.   height: 40px;
56.   display: flex;
57.   align-items: center;
58.   justify-content: space-between;
59.   padding: 10px;
60.   border-bottom: 1px solid #eee;
61.   font-size: 30rpx;
62. }

**js:(重点来了)**

1. var animation = wx.createAnimation({
2.     duration: 500,
3.     timingFunction: "linear",
4.     delay: 0
5.   })
6.   Page({
7. /**
8.      * 页面的初始数据
9.      */
10.     data: {
11.       zhiwu_active: 1, // 职务列表默认id
12.       source_active: 1, // 简历来源默认id
13.       status_active: 1, // 简历状态默认id
14.       box_zhiwu: false, // 招聘职务盒子
15.       box_source: false, // 简历来源盒子
16.       box_status: false, // 简历状态盒子
17.       top: '-1000px', // 下拉列表初始位置
18.       animationData: {},
19.       zhiwu_list: [
20.         {
21.           id: 1,
22.           title: '全部'
23.         },
24.         {
25.           id: 2,
26.           title: '律师'
27.         },
28.         {
29.           id: 3,
30.           title: '会计助理'
31.         },
32.         {
33.           id: 4,
34.           title: '数据分析师'
35.         },
36.       ],
37.       source_list: [
38.         {
39.           id: 1,
40.           title: '全部'
41.         },
42.         {
43.           id: 2,
44.           title: '自荐'
45.         },
46.         {
47.           id: 3,
48.           title: '智能匹配'
49.         }
50.       ],
51.       status_list: [
52.         {
53.           id: 1,
54.           title: '全部'
55.         },
56.         {
57.           id: 2,
58.           title: '未查看'
59.         },
60.         {
61.           id: 3,
62.           title: '已查看'
63.         },
64.         {
65.           id: 4,
66.           title: '未邀请'
67.         },
68.         {
69.           id: 5,
70.           title: '已邀请'
71.         },
72.         {
73.           id: 6,
74.           title: '已接受'
75.         },
76.         {
77.           id: 7,
78.           title: '已拒绝'
79.         },
80.         {
81.           id: 8,
82.           title: '不合适'
83.         },
84.         {
85.           id: 9,
86.           title: '未回复'
87.         },
88.       ],
89.     },
90. // 列表点击
91.     bindtap: function (e) {
92.       let _type = e.currentTarget.dataset.type;
93.       let id = e.currentTarget.dataset.id;
94. if(_type == 0){
95. // 招聘职务
96. this.setData({
97.           zhiwu_active: id
98.         })
99.       }else if(_type == 1){
100. // 简历来源
101. this.setData({
102.           source_active: id
103.         })
104.       } else if (_type == 2) {
105. // 简历状态
106. this.setData({
107.           status_active: id
108.         })
109.       }
110.     },
111. // 打开下拉选项
112.     open_box: function (e) {
113.       let _type = e.currentTarget.dataset.type;
114. if (_type == 0) {
115. // 职务下拉
116.         let height = -this.data.zhiwu_list.length * 50 + 'px';
117. if (this.data.box_zhiwu) {
118. this.off_box(height);
119.         } else {
120. this.setData({
121.             box_zhiwu: true,
122.             box_source: false,
123.             box_status: false,
124.             top: height
125.           })
126. this.open_animation()
127.         }
128.       }else if(_type == 1){
129. // 简历来源下拉
130.         let height = -this.data.source_list.length * 50 + 'px';
131. if (this.data.box_source) {
132. this.off_box(height);
133.         } else {
134. this.setData({
135.             box_zhiwu: false,
136.             box_source: true,
137.             box_status: false,
138.             top: height
139.           })
140. this.open_animation();
141.         }
142.       } else if (_type == 2) {
143. // 简历状态下拉
144.         let height = -this.data.status_list.length * 50 + 'px';
145. if (this.data.box_status) {
146. this.off_box(height);
147.         } else {
148. this.setData({
149.             box_zhiwu: false,
150.             box_source: false,
151.             box_status: true,
152.             top: height
153.           })
154. this.open_animation();
155.         }
156.       }else{
157.         console.log('下拉菜单 -- 类型错误')
158.       }
159.     },
160. // 关闭盒子
161.     off_box: function (e) {
162. this.off_animation(e);
163.       setTimeout(() => {
164. this.setData({
165.           box_zhiwu: false,
166.           box_source: false,
167.           box_status: false,
168.           top: '-1000px'
169.         })
170.       }, 400);
171.     },
172. // 打开动画
173.     open_animation: function (e) {
174. this.animation = animation
175.       animation.top(0).step()
176. this.setData({
177.         animationData: animation.export()
178.       })
179.     },
180. // 关闭动画
181.     off_animation: function (e) {
182. this.animation = animation
183.       animation.top(e).step()
184. this.setData({
185.         animationData: animation.export()
186.       })
187.     },
188. })

PS:2018年03月13日16:46:02 ↓

以上代码未兼容苹果手机,把遮罩层那段:

1. <view bindtap='open_box' data-type='0' class='box_bg' hidden="{{!box_zhiwu}}"></view>

放到page{}下,单独最外层。使用hidden控制显示隐藏