微信小程序搬砖记(一)

微信小程序遇到的坑——两种效果实现

据说没有一个小姐姐来镇这篇博客,我的浏览量是上不去的 😂。
程序媛小姐姐

微信小程序首页吸顶的效果实现

在实现的过程中,需要把该准备的东西先准备一波,不然老司机开车也开不动呀!🚌

首先需要 wxml 的支持:

1
2
3
4
5
6
<view
class="recomend-title {{ scrollStatus ? 'recomend-fixed':''}}"
id="recommend"
>
{{item.jobTypeName}}
</view>

再者需要 wxss 的支持:

1
2
3
4
5
6
.recomend-fixed {
position: fixed;
top: 0;
left: 0;
z-index: 99;
}

准备好了,开始通过js来实现最核心的部分。开车了 🚍,小伙伴们,开始上车了。

方法 1 通过 scroll-view 来实现吸顶的效果

使用scroll-view组件,上面的 wxml 的内容需要包裹在<scroll-view scroll-y style="height: 100%" bindscroll="scroll"></scroll-view>里面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Page({
data: {
scrollStatus: false,
fixTop: ''
},
onShow() {
let that = this;
let query = wx.createSelectorQuery();
// 设置吸顶元素离顶部的距离
query
.select('#recommend')
.boundingClientRect(function(rect) {
// 获取元素的top太小,为了实现滚动到适合的位置+280
that.setData({
fixTop: rect.top + 280
});
})
.exec();
},
// 监听滚动函数
scroll(e) {
let top = e.detail.scrollTop;
this.setData({
scrollStatus: top > this.data.fixTop
});
}
});
方法 2 通过 onPageScroll 来实现吸顶的效果

如果不使用scroll-view,利用页面的onPageScroll方法,但是你在使用的过程中会有一些问题:

1.在 page 标签的样式会携带一个样式overflow-y:hidden,导致你页面滚动不了,不能触发onPageScroll方法 2.在 page 标签和包含上面的 wxml 的父标签里面不能同时使用height:100%.

JS实现部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Page({
data: {
scrollStatus: false,
fixTop: ''
},
onShow() {
let that = this;
let query = wx.createSelectorQuery();
// 设置吸顶元素离顶部的距离
query
.select('#recommend')
.boundingClientRect(function(rect) {
// 获取元素的top太小,为了实现滚动到适合的位置+280
that.setData({
fixTop: rect.top + 280
});
})
.exec();
},
// 监听滚动函数
onPageScroll: function(e) {
let top = e.scrollTop;
this.setData({
scrollStatus: top > this.data.fixTop
});
}
});
方法 3 通过 position:sticky 来实现吸顶的效果(后续补充)

在 CSS3 中有一个属性可以简单的实现吸顶的效果,实现的代码:

1
2
3
4
5
.sticky {
position: sticky;
position: -webkit-sticky;
top: 0;
}

**注意:**该方法在微信小程序的应用效果不是很好,开始吸顶后滚动着就不见了

微信小微信头部滑动切换效果实现

方法 1 通过设置固定的滑动距离来实现点击滑动

头部 tab 页有很多标签通过点击其中一个进行滑动对应的标签。

所需的wxml的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<scroll-view
class="list"
scroll-x="true"
scroll-with-animation="true"
scroll-left="{{scrollX}}"
>
<text
wx:for="{{ topicList }}"
wx:key="{{ index }}"
bind:tap="directTopicPage"
class="{{topicid === item.id?'active':''}}"
data-index="{{index}}"
>{{ item.title }}</text
>
</scroll-view>

所需的wxss的内容:

1
2
3
.active {
color: #34b9b4;
}

最重要的JS部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Page({
data: {
// 里面包含的数据,请自行填充
topicList: [],
scrollX: 0
},
directTopicPage(e) {
let index = e.currentTarget.dataset.index;
// 通过约定一标签的宽度来设置滑动活动的距离,同时可以在可视化界面看到
this.setData({
scrollX: ~~(index - 1) * 60
});
}
});
方法 2 通过获取点击元素距离左边的距离跟屏幕宽度的一半来实现点击居中(后续补充)

实现的思想:

  • 获取屏幕宽度的一半
  • 获取点击元素距离屏幕左边的距离
  • 获取点击元素的宽度一半
  • 获取已经滚动的距离
  • 计算距离的变化:点击元素与屏幕左边的距离-屏幕的一半+点击元素宽度的一半
  • 计算最终需要滚动的距离:原先滚动距离+变化距离

所需的wxml的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<scroll-view
class="list"
scroll-x="true"
scroll-with-animation="true"
scroll-left="{{scrollX}}"
bindscroll="scrollMove"
>
<text
wx:for="{{topicList}}"
wx:key="{{index}}"
id="topic{{index}}"
bindtap="directTopicPage"
class="{{current === index ? 'active':''}}"
data-index="{{index}}"
>{{ item.type || item.name}}</text>
</scroll-view>

所需的wxss的内容:

1
2
3
4
5
6
.single-line .list {
flex: 1;
/* 这两个一定存在 不然实现不了点击自动居中 */
white-space: nowrap;
overflow: scroll;
}

最重要的JS部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
* 组件的初始数据
*/
data: {
showAll: false,
scrollLeft: 0, // scroll-view滚动的距离,默认为0,因为没有触发滚动
slideWidth:60,
// ? subLeft 点击元素距离屏幕左边的距离
// ? subHalfWidth 点击元素的宽度一半
// ? screenHalfWidth 屏幕宽度的一半
moveParams: {
subLeft // 点击元素距离屏幕左边的距离
subHalfWidth // 点击元素的宽度一半
screenHalfWidth // 屏幕宽度的一半
}
},
ready: function() {
let that = this;
// 获取手机屏幕信息(宽度)
wx.getSystemInfo({
success: (res) => {
that.data.moveParams.screenHalfWidth = res.screenWidth / 2;
},
fail: () => {},
complete: () => {}
});
},
/**
* 组件的方法列表
*/
methods: {
//获取点击元素的信息,ele为传入的id
getRect(ele,index,currentItem) {
var that = this;
// 获取ele的dom元素,同时获取DOM元素一些基本信息
const query = wx.createSelectorQuery().in(this);
query.select(ele).boundingClientRect(function (rect) {
let moveParams = that.data.moveParams;
moveParams.subLeft = rect.left;
moveParams.subHalfWidth = rect.width/2;
that.moveTo(index,currentItem);
}).exec()
},
// 跳转到选中的项居中
moveTo(index,currentItem) {
let {moveParams,scrollLeft} = this.data;

let {subLeft,screenHalfWidth,subHalfWidth} = moveParams;
// 用于计算DOM元素距离屏幕一半的距离
let distance = subLeft - screenHalfWidth + subHalfWidth;
// 用于计算滑动的距离
scrollLeft = scrollLeft + distance;

this.setData({
scrollLeft: scrollLeft
})
// 用于父子组件的通信
this.triggerEvent('doSetting', {
current: index,
id: currentItem.id,
ScrollX: scrollLeft
});

},
// 计算没点击DOM元素滑动的距离
scrollMove(e) {
let moveParams = this.data.moveParams;
this.setData({
scrollLeft: e.detail.scrollLeft,
moveParams: moveParams
})
},
// 点击DOM元素实现DOM元素居中
directTopicPage(e) {
let index = e.currentTarget.dataset.index;
let currentItem = this.data.topicList[index];
let ele = `#topic${index}`;
let type = e.currentTarget.dataset.type || '';
if (type) {
this.showAllTopic();
}
this.getRect(ele,index,currentItem);
},
}

总结

通过上述方法实现的吸顶和 tab 列表横向滑动效果,吸顶效果在 ios 上时比较流畅,android 上滑动慢一点还算流畅,但是快一点就卡顿;tab 列表横向滑动效果补充了一种点击自动居中的方法,如果大家有更好的方法推荐,请望各位赐教。

参考链接

微信小程序点击元素居中


本文由 Abert 创作,采用 知识共享署名 4.0 国际许可协议。

本站文章除注明转载/出处外,均为本站原创或翻译,转载请务必署名。