title: scroll-view 可滚动视图区域 header: develop nav: component sidebar: view_scroll-view

webUrl: https://qft12m.smartapps.cn/component/scroll-view/scroll-view

解释:可滚动视图区域,可实现横向滚动和竖向滚动。使用竖向滚动时,需要给定一个固定高度,可以通过css来设置height。

属性说明

属性名 类型 默认值 必填 说明
scroll-x Boolean false 允许横向滚动
scroll-y Boolean false 允许纵向滚动
upper-threshold Number | String 50 距顶部/左边多远时(单位 px),触发 scrolltoupper 事件
lower-threshold Number | String 50 距底部/右边多远时(单位 px),触发 scrolltolower 事件
scroll-top Number | String 设置竖向滚动条位置。要动态设置滚动条位置,用法scroll-top="{= scrollTop =}"
scroll-left Number | String 设置横向滚动条位置。要动态设置滚动条位置,用法scroll-left="{= scrollLeft =}"
scroll-into-view String 值应为某子元素 id(id 不能以数字开头),设置滚动方向后,按方向滚动到该元素,动态设置用法scroll-into-view="{= scrollIntoView =}"
scroll-with-animation Boolean false 在设置滚动条位置时使用动画过渡
enable-back-to-top Boolean false ios点击顶部导航栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向
bindscrolltoupper EventHandle 滚动到顶部/左边,会触发 scrolltoupper 事件
bindscrolltolower EventHandle 滚动到底部/右边,会触发 scrolltolower 事件
bindscroll EventHandle 滚动时触发, event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}

示例

在开发者工具中预览效果

扫码体验

webUrl: https://qft12m.smartapps.cn/component/scroll-view/scroll-view - 图1 请使用百度APP扫码

代码示例 1:纵向滚动

:::codeTab

  1. <view class="wrap">
  2. <view class="card-area">
  3. <view class="top-description">纵向滚动</view>
  4. <scroll-view
  5. class="scroll-view"
  6. scroll-y
  7. upper-threshold="1"
  8. lower-threshold="1"
  9. scroll-top="{= scrollTop =}"
  10. scroll-into-view="{= scrollIntoView =}"
  11. scroll-with-animation="true"
  12. enable-back-to-top="true"
  13. bindscrolltoupper="upper"
  14. bindscrolltolower="lower"
  15. bindscroll="scroll">
  16. <view id="one" class="color-a">A</view>
  17. <view id="two" class="color-b">B</view>
  18. <view id="three" class="color-c">C</view>
  19. </scroll-view>
  20. <view class="page-section-btns">
  21. <view class="next" bindtap="tap">下一页</view>
  22. <view bindtap="tapMove">滚动</view>
  23. <view class="scrollToTop" bindtap="scrollToTop">回顶部</view>
  24. </view>
  25. </view>
  26. </view>
  1. const order = ['one', 'two', 'three'];
  2. Page({
  3. data: {
  4. scrollIntoView: 'one',
  5. scrollTop: 0,
  6. scrollLeft: 0
  7. },
  8. upper() {
  9. swan.showToast({
  10. title: '到顶了',
  11. icon: 'none'
  12. });
  13. },
  14. lower() {
  15. swan.showToast({
  16. title: '到底了',
  17. icon: 'none'
  18. });
  19. },
  20. scroll(e) {
  21. console.log('获取滚动事件的详细信息e.detail:', e.detail);
  22. this.setData({
  23. scrollTop: e.detail.scrollTop
  24. })
  25. },
  26. scrollToTop(e) {
  27. console.log(e);
  28. this.setData({
  29. scrollTop: 0,
  30. });
  31. },
  32. tap(e) {
  33. for (let i = 0; i < order.length; ++i) {
  34. if (order[i] === this.data.scrollIntoView) {
  35. const next = (i + 1) % order.length;
  36. this.setData({
  37. scrollIntoView: order[next],
  38. scrollTop: next * 500,
  39. });
  40. break;
  41. }
  42. }
  43. },
  44. tapMove() {
  45. this.setData({
  46. scrollTop: this.data.scrollTop + 10,
  47. });
  48. }
  49. });

:::

代码示例 2:横向滚动

:::codeTab

  1. <view class="wrap">
  2. <view class="card-area">
  3. <view class="top-description">横向滚动</view>
  4. <scroll-view
  5. class="scroll-view"
  6. scroll-x
  7. bindscrolltoupper="toLeft"
  8. bindscrolltolower="toRight"
  9. scroll-left="{= scrollLeft =}"
  10. upper-threshold="1"
  11. lower-threshold="1"
  12. bindscroll="scroll">
  13. <view id="four" class="color-a row-view">A</view>
  14. <view id="five" class="color-b row-view">B</view>
  15. <view id="six" class="color-c row-view">C</view>
  16. </scroll-view>
  17. </view>
  18. </view>
  1. Page({
  2. data: {
  3. scrollLeft: 0
  4. },
  5. toLeft() {
  6. swan.showToast({
  7. title: '到最左边了',
  8. icon: 'none'
  9. });
  10. },
  11. toRight() {
  12. swan.showToast({
  13. title: '到最右边了',
  14. icon: 'none'
  15. });
  16. },
  17. scroll(e) {
  18. console.log('获取滚动事件的详细信息e.detail:');
  19. console.dir(e.detail);
  20. this.setData({
  21. scrollTop: e.detail.scrollTop
  22. })
  23. }
  24. });

:::

Bug & Tip

  • Tip:请勿在 scroll-view 中使用 textarea、map、canvas、video 组件;更多请看原生组件说明
  • Tip:scroll-into-view 的优先级低于 scroll-top、scroll-left。
  • Bug:在滚动 scroll-view 时会阻止页面回弹,所以在 scroll-view 中滚动,是无法触发 onPullDownRefresh。
  • Tip:若要使用下拉刷新,请使用页面的滚动,而不是 scroll-view。
  • Tip:scroll-into-view、scroll-top、scroll-left 需要在页面数据高度(或宽度)撑开时生效,若有异步加载数据,请在数据渲染完成时,重新动态赋值,才可生效。
  • Tip:在设置 scroll-view 组件 height 属性不是内容可视区总高度时,使用 swan.pageScrollTo() API 无法生效。

参考示例

参考示例 1: 横向滚动套纵向滚动常用业务场景

在开发者工具中预览效果

:::codeTab

  1. <view class="wrap">
  2. <view class="card-area">
  3. <view class="top-description border-bottom">推荐列表</view>
  4. <scroll-view
  5. scroll-x
  6. class="scroll-view"
  7. >
  8. <view class="flex">
  9. <scroll-view class="item" scroll-y s-for="item in list">
  10. <image class="image" src="{{item.src}}"></image>
  11. <view class="introduce">{{item.description}}</view>
  12. </scroll-view>
  13. </view>
  14. </scroll-view>
  15. </view>
  16. </view>

:::

参考示例 2: 隐藏scroll-view的滚动条

在开发者工具中预览效果

:::codeTab

  1. /* 添加此属性隐藏scroll-view的滚动条 */
  2. ::-webkit-scrollbar {
  3. width: 0;
  4. height: 0;
  5. color: transparent;
  6. }

:::

参考示例 3: 竖向锚点示例

在开发者工具中预览效果

:::codeTab

  1. <view class='scroll-box' style='height:{{ht}}px;'>
  2. <scroll-view scroll-y class='menu-tab' scroll-into-view="{{toView}}" scroll-with-animation="true">
  3. <view s-for="{{tabList}}" s-key="">
  4. <view class='item-tab {{item.checked ? "item-act":""}}' id="t{{index}}" data-index="{{index}}" bindtap='intoTab'>{{item.title}}</view>
  5. </view>
  6. </scroll-view>
  7. <scroll-view scroll-y style='height:{{ht}}px;'
  8. scroll-with-animation="true"
  9. bindscrolltoupper="upper"
  10. bindscrolltolower="lower"
  11. bindscroll="scrollRight"
  12. scroll-into-view="{{toViewRt}}">
  13. <view s-for="{{contList}}" s-key="">
  14. <view class='cont-box' id="t{{index}}" style='height:{{ht}}px;'>{{item.cont}}</view>
  15. </view>
  16. </scroll-view>
  17. </view>
  1. var app = getApp();
  2. Page({
  3. data: {
  4. current: 0,
  5. // 左侧菜单
  6. tabList: [
  7. { title: 'tab1', checked: true },
  8. { title: 'tab2', checked: false },
  9. { title: 'tab3', checked: false },
  10. { title: 'tab4', checked: false },
  11. { title: 'tab5', checked: false },
  12. { title: 'tab6', checked: false }
  13. ],
  14. // 右侧内容
  15. contList: [
  16. { cont: 'tab1'},
  17. { cont: 'tab2'},
  18. { cont: 'tab3'},
  19. { cont: 'tab4'},
  20. { cont: 'tab5'},
  21. { cont: 'tab6'}
  22. ],
  23. },
  24. // 循环切换
  25. forTab(index) {
  26. let lens = this.data.tabList.length;
  27. let _id = 't' + index;
  28. for (let i = 0; i < lens; i++) {
  29. this.data.tabList[i]['checked'] = false;
  30. }
  31. this.data.tabList[index]['checked'] = true;
  32. this.setData({
  33. tabList: this.data.tabList,
  34. toView: _id,
  35. current: index
  36. });
  37. },
  38. // 点击左侧菜单栏
  39. intoTab(e) {
  40. let lens = this.data.tabList.length;
  41. let _index = e.currentTarget.dataset.index;
  42. this.forTab(_index);
  43. let _id = 't' + _index;
  44. this.setData({
  45. toViewRt: _id
  46. });
  47. },
  48. // 滚动右侧菜单
  49. scrollRight(e) {
  50. //console.log(e)
  51. let _top = e.detail.scrollTop;
  52. let progress = parseInt(_top / this.data.ht); // 计算出 当前的下标
  53. if (progress > this.data.current) { // 向上拉动屏幕
  54. this.setData({ current: progress });
  55. this.forTab(this.data.current);
  56. } else if (progress == this.data.current) {
  57. return false;
  58. } else { // 向下拉动屏幕
  59. this.setData({
  60. current: progress == 0 ? 0 : progress--
  61. });
  62. this.forTab(progress);
  63. }
  64. },
  65. onLoad: function (options) {
  66. console.log(this.data.tabList)
  67. // 框架尺寸设置
  68. swan.getSystemInfo({
  69. success: (options) => {
  70. var wd = options.screenWidth; // 页面宽度
  71. var ht = options.windowHeight; // 页面高度
  72. this.setData({ wd: wd, ht: ht })
  73. }
  74. });
  75. },
  76. onShow: function () {
  77. // 初始化状态
  78. this.setData({
  79. toView: 't' + this.data.current,
  80. toViewRt: 't' + this.data.current
  81. })
  82. }
  83. })

:::