前言
scroll-view是小程序滚动视图组件,用于实现局部区域滚动。动。本案例通过 scroll-view 完成纵向滚动与横向滚动两个场景,演示scroll-into-view、scroll-left等属性,以及bindscrolltoupper、bindscrolltolower、bindscroll滚动事件,并用伪元素::before在色块中央渲染文字。作业拓展需求:在横向滚动视图基础上再增加 "阳光灿烂" 一项,实现四块横向排列滚动。
一、实现效果
- 纵向滚动视图:初始显示第二页,可上下滚动,共 3 个彩色整页。
- 横向滚动视图:初始显示第一页一部分和第二页一小部分,可左右滚动。
- 作业拓展:横向滚动新增第 4 块 "阳光灿烂",橙色背景。
- 滚动过程中,控制台分别打印对应日志。
二、核心知识点
1. 纵向滚动
表格
| 属性 / 事件 | 作用 |
|---|---|
scroll-y="true" | 开启纵向滚动 |
scroll-into-view="page2" | 初始化自动滚动到 id 为 page2 的子元素位置 |
bindscrolltoupper | 滚动到顶部时触发 |
bindscrolltolower | 滚动到底部时触发 |
bindscroll | 滚动过程中持续触发 |
2. 横向滚动
表格
| 属性 / 事件 | 作用 |
|---|---|
scroll-x="true" | 开启横向滚动 |
scroll-left="50" | 初始水平偏移 50px |
bindscroll | 滚动过程中触发 |
3. 横向排列三要素(高频坑)
- 父容器
scroll-view-x设置white-space: nowrap;禁止自动换行。 - 子元素设置
display: inline-block;。 - 子元素不能写
width:100%,要固定宽度(如 600rpx)。
坑点:wxml 里 inline-block 标签之间不要换行,换行产生的空白间隙过大会导致元素自动换行。
4. 伪元素::before实现文字居中
.page1::before { content: '第一页'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
绝对定位 + 偏移 50% + transform 回移 50%,实现水平垂直居中。子元素空 view 标签,文字全部由 css 输出。
5. 渲染引擎
代码中文字使用\n换行符,Skyline 渲染引擎不支持,必须使用"renderer":"webview"。
三、完整代码实现
app.json
{
"pages": [
"pages/index/index"
],
"window": {
"navigationBarTextStyle": "black",
"navigationStyle": "custom"
},
"style": "v2",
"renderer": "webview",
"rendererOptions": {
"skyline": {
"defaultDisplayBlock": true,
"defaultContentBox": true,
"tagNameStyleIsolation": "legacy",
"disableABTest": true,
"sdkVersionBegin": "3.0.0",
"sdkVersionEnd": "15.255.255"
}
},
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}
pages/index/index.wxml
<!--index.wxml-->
<navigation-bar title="scroll-view组件" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<scroll-view class="scrollarea" scroll-y type="list">
<view class="box">
<view class="title">滚动视图示例</view>
<view class="page-section-title">
<text>Vertical Scroll\n纵向滚动</text>
</view>
<scroll-view scroll-y="true" style="height: 300rpx;" class="sheet" scroll-into-view="page2"
bindscrolltoupper="upper" bindscrolltolower="lower" bindscroll="scroll_y">
<view id="page1" class="scroll-view-item-y page1"></view>
<view id="page2" class="scroll-view-item-y page2"></view>
<view id="page3" class="scroll-view-item-y page3"></view>
</scroll-view>
<view class="page-section-title">
<text>Horizontal Scroll\n横向滚动</text>
</view>
<scroll-view scroll-x="true" style="width: 100%;" scroll-left="50" class="scroll-view-x sheet"
bindscroll="scroll_x">
<view id="page1" class="scroll-view-item-x page1"></view>
<view id="page2" class="scroll-view-item-x page2"></view>
<view id="page3" class="scroll-view-item-x page3"></view>
<view class="scroll-view-item-x sunny"></view>
</scroll-view>
</view>
</scroll-view>
pages/index/index.wxss
/**index.wxss**/
page {
height: 100vh;
display: flex;
flex-direction: column;
}
.scrollarea {
flex: 1;
overflow-y: hidden;
}
.page-section-title {
font-size: 40rpx;
text-align: center;
margin-top: 40rpx;
margin-bottom: 20rpx;
}
.scroll-view-item-y {
height: 300rpx;
}
.scroll-view-item-x {
display: inline-block;
width: 100%;
height: 300rpx;
}
.sheet {
font-size: 50rpx;
letter-spacing: 1.2em;
}
.page1 {
position: relative;
background-color: #1AAD19;
color: #FFFFFF;
}
.page1::before {
content: '第一页';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.page2 {
position: relative;
background-color: #2782D7;
color: #FFFFFF;
}
.page2::before {
content: '第二页';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.page3 {
position: relative;
background-color: purple;
color: #FFFFFF;
}
.page3::before {
content: '第三页';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.scroll-view-x {
white-space: nowrap;
}
.sunny {
position: relative;
background-color: #FF9500;
color: #FFFFFF;
}
.sunny::before {
content: '阳 光 灿 烂';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
letter-spacing: normal;
}
pages/index/index.js
// index.js
Page({
upper(e) {
console.log('to upper');
},
lower(e) {
console.log('to lower');
},
scroll_y(e) {
console.log('vertical scrolling');
},
scroll_x(e) {
console.log('Horizontal Scrolling');
}
})
app.wxss
/**app.wxss**/
.box {
margin: 20rpx;
padding: 20rpx;
border: 2rpx solid silver;
}
.title {
font-size: 40rpx;
font-weight: bolder;
text-align: center;
margin-bottom: 30rpx;
color: red;
}
四、运行测试步骤
- 新建项目,不使用云服务、不使用模板,粘贴全部代码。
- 确认 app.json 为
"renderer":"webview"。 - 编译运行:纵向滚动初始定位第二页,可上下滚动;横向滚动初始偏移 50px。
- 作业验证:横向滚动到最右侧,可见橙色 "阳光灿烂" 第 4 块。
- 滚动时控制台输出对应日志。
五、常见踩坑总结
- 横向元素跑到下一行:父容器没有
white-space:nowrap,或子项写了width:100%。 - inline-block 之间换行产生空白间隙导致换行:wxml 子标签写在同一行。
scroll-into-view失效:子元素 id 不能以数字开头,且必须存在。- 文字间距错位:
.sheet的letter-spacing:1.2em被横向元素继承,需用letter-spacing:normal清除或去掉sheet类。 \n换行符显示异常:渲染引擎必须为 webview。
六、拓展思考
- 增加回到顶部按钮,用
scroll-top控制滚动位置。 - 横向滚动加自动轮播,配合
setInterval控制scroll-left。 - 用
scroll-into-view实现锚点导航,点击跳转到指定页。