uni-app小程序开发-滚动到指定位置的实现方式

使用scroll-view标签

scroll-top

页面

1
2
3
4
5
<scroll-view show-scrollbar="false" scroll-y="true" :scroll-top="scrollTop" scroll-with-animation="true">
<view class="scroll-view-item" v-for="(item,index) in servicesLeftList" :key="item.id">
{{item.name}}
</view>
</scroll-view>

数据

1
2
3
4
5
data(){
return {
scrollTop:0,//滚动位置
}
}

方法

1
this.scrollTop = 300;

scroll-into-view

页面

1
2
3
4
5
<scroll-view scroll-y="true" scroll-with-animation="true" :scroll-into-view="targetViewId">
<view v-for="(item,index) in servicesLeftList" :key="item.id" :id="'scroll' + item.id">
{{item.name}}
</view>
</scroll-view>

数据

1
2
3
4
5
data(){
retrun {
targetViewId:"",//描点id
}
}

方法

1
this.targetViewId= 'scroll' + item.id;

使用uni.pageScrollTo

1
2
3
4
5
6
<view class="left-box" >
<view class="scroll-view-item" v-for="(item,index) in servicesLeftList" :key="item.id"
:class="{'active':activeLeftTab==item.id}" :id="textarea"+index>
{{item.name}}
</view>
</view>

JS

1
2
3
4
5
uni.pageScrollTo({
scrollTop: 0,
duration: 500
selector: '#textarea5' //指定位置
});

滚动到底部

页面

1
2
3
4
5
6
7
<scroll-view :style="{height:scrollViewHeight+'px'}" :scroll-y="true" :scroll-top="scrollTop" :scroll-with-animation="true">
<view id="scroll-view-content">
<block v-for="(item,index) in images" :key="index">
<image class="item" :src="item.src" mode="aspectFill"></image>
</block>
</view>
</scroll-view>

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default {
data() {
return {
images:[],
scrollTop:0,//滚动条位置
scrollViewHeight:300,//滚动视图的高度
};
},
methods:{
scrollToBottom(){
this.$nextTick(()=>{
uni.createSelectorQuery().select('#scroll-view-content').boundingClientRect((rect)=>{
let top = rect.height-this.scrollViewHeight;
if(top>0){
this.scrollTop=top;
}
}).exec()
})
}
}
}

标签与滚动区联动

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<template>
<view>
<scroll-view class="myscrollview" scroll-y @scroll="onScroll" :scroll-top="scrollTop" scroll-with-animation="true">
<view v-for="(item, index) in items" :key="index" :id="'item-' + index" class="scroll_item">
<text>{{ item }}</text>
</view>
</scroll-view>

<view class="tag_outer">
<view v-for="(item, index) in items" :key="index" class="tag_item">
<text :style="{ color: selectedIndex === index ? 'blue' : 'black' }" @click="scrollTo(index)">
{{ item }}
</text>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
items: ['标签1', '标签2', '标签3', '标签4', '标签5'],
selectedIndex: 0,
scrollTop: 0
};
},
onReady() {},
methods: {
getRect(selector) {
return new Promise((resolve) => {
uni.createSelectorQuery()
.select(selector)
.boundingClientRect((rect) => {
resolve(rect);
})
.exec();
});
},
onScroll(event) {
const { scrollTop, scrollHeight } = event.detail;
this.updateSelectedIndex(scrollTop, scrollHeight);
},

async updateSelectedIndex(scrollTop, scrollHeight) {
let items = this.items;
let outerRect = await this.getRect('.myscrollview');
if (scrollTop + outerRect.height >= scrollHeight - 10) {
// 滚动到底部
this.selectedIndex = items.length - 1;
} else {
// 未滚动到底部
items.forEach(async (_, index) => {
let rect = await this.getRect(`#item-${index}`);
if (rect) {
const top = rect.top + scrollTop;
const bottom = rect.bottom + scrollTop;
// 判断当前可见区域
if (scrollTop >= top && scrollTop < bottom) {
this.selectedIndex = index;
}
if (index == items.length - 1) {
if (scrollTop + rect.height >= scrollHeight - 10) {
this.selectedIndex = index;
}
}
}
});
}
},
async scrollTo(index) {
this.selectedIndex = index;
let rect = await this.getRect(`#item-${index}`);
if (rect) {
this.scrollTop = rect.top + this.scrollTop;
}
}
}
};
</script>

<style>
.myscrollview {
height: 300px;
background-color: #f0f0f0;
}

.scroll_item {
height: 200px;
background-color: aquamarine;
margin-bottom: 20rpx;
}

.tag_outer {
margin-top: 20rpx;
display: flex;
width: 100%;
}

.tag_item {
margin-left: 10px;
border: 1rpx solid #ddd;
padding: 10rpx 10rpx;
}
</style>

横向滚动的标签条

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
85
86
87
88
89
90
91
92
<template>
<view class="tag_view">
<scroll-view show-scrollbar="false" scroll-x="true" :scroll-into-view="targetViewId" scroll-with-animation="true">
<view class="tag_outer">
<view
class="tag_item"
v-for="(tag, index) in tagList"
:key="index"
:class="{ selected: index === selectIndex }"
@click="itemSelectClick(index)"
:id="'scroll' + tag.tagId"
>
<view class="tag_name">{{ tag.tagName }}</view>
<view class="tag_bar"></view>
</view>
</view>
</scroll-view>
</view>
</template>

<script>
export default {
name: 'comp-tag-view',
data() {
return {
targetViewId: '',
tagList: [
{ tagId: '0', tagName: '全部' },
{ tagId: '1', tagName: '待付款' },
{ tagId: '2', tagName: '待发货' },
{ tagId: '3', tagName: '待收货' },
{ tagId: '4', tagName: '待归还' },
{ tagId: '5', tagName: '归还中' },
{ tagId: '6', tagName: '已完成' },
{ tagId: '7', tagName: '已取消' }
],
selectIndex: 0
};
},
methods: {
itemSelectClick(index) {
let tempIndex = index;
if (tempIndex > 1) {
tempIndex -= 2;
} else if (tempIndex > 0) {
tempIndex -= 1;
}
let item = this.tagList[tempIndex];
this.targetViewId = 'scroll' + item.tagId;

this.selectIndex = index;
}
}
};
</script>

<style lang="scss">
.tag_view {
background-color: white;
}
.tag_outer {
display: flex;
background-color: white;
overflow-x: visible;

.tag_item {
padding-left: 20rpx;
padding-right: 20rpx;
flex: none;
display: flex;
flex-direction: column;
align-items: center;

.tag_name {
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
}
}

.tag_item.selected {
.tag_bar {
height: 9rpx;
width: 48rpx;
border-radius: 8rpx;
opacity: 1;
background: #fa7e31;
}
}
}
</style>