简介

<scroller> 是一个容纳子组件进行横向或竖向滚动的容器组件。如果你的组件需要进行滚动,可以将 <scroller> 当作根元素或者父元素使用,否则页面无法滚动。

  • <scroller> 需要显式的设置其宽高,可使用 position: absolute; 定位或 widthheight 设置其宽高值。

    1. <scroller class="scroller" id="myScroller">
    2. <div class="row" a:for="{{listArray}}">
    3. <text class="text">{{item}}</text>
    4. </div>
    5. </scroller>

    组件演示

    screenshot.png

    axml

    <div class="warpper">
    <x-nav-bar showArrow="{{true}}" title="Scroller"></x-nav-bar>
    <div class="container">
      <div class="button-box">
        <div class="button" onTap="onScrollbar">点击控制是否出现滚动条 showScrollbar:点击{{showScrollbar - 1}}次 - {{showScrollbar%2?'展示滚动条':'隐藏滚动条'}}</div>
        <div class="button" onTap="onScrollDirection">点击控制滚动的方向 scrollDirection: {{scrollDirection%2 == 0?'horizontal(横向)':'vertical(纵向)'}}</div>
        <div class="button" onTap="onOffsetAccuracy">点击控制 scroll 事件触发的频率 offsetAccuracy:{{offsetAccuracy}}px</div>
        <div class="button" a:if="{{scrollDirection%2 == 0}}" onTap="onScrollLeft">点击控制距离左边的位置(横向滚动)scrollLeft:{{scrollLeft}}px</div>
        <div class="button" a:else onTap="onScrollTop" style="padding-left: 120rpx;padding-right: 120rpx">点击控制距离顶部的位置 scrollTop:{{scrollTop}}px</div>
      </div>
      <div class="content">
        <div>滑动距离:滚动条滚动了{{scrollDirection%2 == 0 ? offsetX : offsetY}}rpx -- {{contentStart}} -- {{contentEnd}}</div>
        <div class="flex">
          <div>滚动到顶部:{{contStart}}次</div>
          <div>滚动到底部:{{contEnd}}次</div>
        </div>
      </div>
      <div class="scroller-box">
        <scroller 
          a:if="{{scrollDirection%2 == 0}}"
          class="scroller scroller-horizontal"
          scrollDirection="horizontal" 
          onscroll="onScroll" 
          onscrollend="onScrollEnd" 
          onscrollstart="onScrollStart" 
          onscrollToUpper="onScrollToUpper"
          onscrollToLower="onScrollToLower"
          scrollLeft="{{ scrollLeft }}rpx" 
          offsetAccuracy="{{30}}"
          showScrollbar="{{showScrollbar%2}}"
        >
          <div class="row row-horizontal">
            <text class="col" a:for="{{list}}" a:for-item="item">横向第{{item}}格</text>
          </div>
        </scroller>
    
        <scroller 
          a:else
          class="scroller scroller-vertical"
          scrollDirection="vertical" 
          onscroll="onScroll" 
          onscrollend="onScrollEnd" 
          onscrollstart="onScrollStart" 
          onscrollToUpper="onScrollToUpper"
          onscrollToLower="onScrollToLower"
          scrollTop="{{ scrollTop }}rpx" 
          showScrollbar="{{false}}"
        >
          <div class="row">
            <text class="col" a:for="{{list}}" a:for-item="item">纵向第{{item}}格</text>
          </div>
        </scroller>
      </div>
    </div>
    </div>
    

    css

    ```css .warpper { background-color:white; width:100%; height:100%; display:flex; flex-direction: column; justify-content: center; align-items: center; }

.container{ flex: 1; color: black; } .button-box{ display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; }

.button{ padding: 10rpx; border-radius: 8rpx; line-height: 26rpx; font-size: 22rpx; margin-bottom: 5rpx; border: 1rpx solid #d9d9d9; background-color: #fff; }

.disable{ background-color: red; color: #999; }

.content{ border: 1rpx solid #25b864; border-radius: 8rpx; background-color: #25b864; color: #fff; line-height: 33rpx; font-size: 22rpx; margin-left: 20rpx; margin-right: 20rpx; padding-left: 20rpx; padding-right: 20rpx; } .flex{ display: flex; justify-content: space-between; flex-direction: row; align-items: center; } .scroller-box{ margin-left: 10vw; margin-top: 20rpx; }

.scroller{ border: 1rpx solid red; border-radius: 8rpx; } .scroller-horizontal{ width: 80vw; height: 200rpx; } .scroller-vertical{ width: 22vw; height: 200rpx; } .row{ border: 1rpx solid green; border-radius: 8rpx; display: flex; justify-content: flex-start; align-items: center; } .row-horizontal{ margin-top: 10rpx; height: 180rpx; flex-direction: row; } .col{ display: inline-block; width: 20vw; border: 1rpx solid black; color: #999; text-align: center; line-height: 180rpx; }

<a name="iygDF"></a>
#### ts
```tsx
import { JSON, JSONObject } from "waft-json";
import { console, getDataSource, Page, Props, Event, MessageEvent, getRPX, CustomEvent } from "waft";

let _this: Index;
export class Index extends Page {
  constructor(props: Props){
    super(props);
    _this = this;
    // 设置默认的state
    this.setState(getDataSource());

    this.addEventListener('onScrollbar', () => {
      console.log('onScrollbar')
      const showScrollbar = _this.state.getInteger('showScrollbar');
      const newState = new JSONObject;
      const newShowScrollbar = showScrollbar + 1
      const c = newShowScrollbar % 2? "显示滚动条":"隐藏滚动条";
      // newState.set('content', "点击了"+showScrollbar.toString()+"下"+c.toString());
      newState.set('showScrollbar', newShowScrollbar);
      _this.setState(newState);
    })
    this.addEventListener('onScrollDirection', () => {
      const scrollDirection = _this.state.getInteger('scrollDirection');
      const newState = new JSONObject;
      newState.set('scrollDirection', scrollDirection + 1);
      _this.setState(newState);
    })
    this.addEventListener('onOffsetAccuracy', () => {
      console.log('onOffsetAccuracy')
      const offsetAccuracy = _this.state.getInteger('offsetAccuracy');
      const newState = new JSONObject;
      newState.set('offsetAccuracy', offsetAccuracy + 5);
      _this.setState(newState);
    })
    this.addEventListener('onScrollTop', () => {
      console.log('onScrollTop')
      const scrollTop = _this.state.getInteger('scrollTop');
      const newState = new JSONObject;
      newState.set('scrollTop', scrollTop + 50);
      _this.setState(newState);
    })
    this.addEventListener('onScrollLeft', () => {
      console.log('onScrollLeft')
      const scrollLeft = _this.state.getInteger('scrollLeft');
      const newState = new JSONObject;
      newState.set('scrollLeft', scrollLeft + 50);
      _this.setState(newState);
    })
    this.addEventListener('onScrollToUpper', (event) => {
      console.log('滚动到顶部/左边,会触发该事件。')
      const contStart = _this.state.getInteger('contStart');
      const newState = new JSONObject;
      newState.set('contStart', contStart + 1);
      _this.setState(newState);
    })
    this.addEventListener('onScrollToLower', (event) => {
      console.log('滚动到底部/右边,会触发该事件。')
      const contEnd = _this.state.getInteger('contEnd');
      const newState = new JSONObject;
      newState.set('contEnd',contEnd + 1);
      _this.setState(newState);
    })
    this.addEventListener('onScroll', (event) => {
      console.log((event as CustomEvent).detail);
      const offsetX = _this.getOffsetX(event)
      const offsetY = _this.getOffsetY(event)
      const newState = new JSONObject;
      newState.set('offsetX', offsetX);
      newState.set('offsetY', offsetY);
      _this.setState(newState);
      console.log('滚动时触发, event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth}。')
    })
    this.addEventListener('onScrollStart', (event) => {
      console.log('滑动开始')
      const newState = new JSONObject;
      newState.set('contentStart', "滑动开始");
      newState.set('contentEnd', "");
      _this.setState(newState);
    })
    this.addEventListener('onScrollEnd', (event) => {
      console.log('滑动结束')
      const newState = new JSONObject;
      newState.set('contentEnd', "滑动结束");
      newState.set('contentStart', "");
      _this.setState(newState);
    })
  }

  // 获取滑块位置
  getOffsetX(event: Event): i64 {
    const offsetX = event
      .toJSONObject()
      .getObject("detail")
      .getObject("contentOffset")
      .getInteger("x");

    return getRPX(offsetX);
  }
  getOffsetY(event: Event): i64 {
    const offsetY = event
      .toJSONObject()
      .getObject("detail")
      .getObject("contentOffset")
      .getInteger("y");

    return getRPX(offsetY);
  }

  onShow(): void{
    // 页面显示
    console.log('page onShow');
  }
  onLoad(query: JSONObject): void{
    // 页面加载后
    console.log('page onLoad:' + JSON.stringify(query));
  }
  onMessage(event: MessageEvent): void{
    // 信息推送更新
    console.log('page onMessage:' + JSON.stringify(event.data));
  }
}

API

scrollOffset

节点滚动位置查询

import { document, ScrollerElement } from 'waft'

const scroller = document.querySelector("#myScroller") as ScrollerElement;
scroller.scrollOffset((data)=>{
    console.log("scrollOffset:" + data.toString());
});

返回值

{
 "scrollLeft":0, //隐藏在滚动条左侧的页面的宽度
 "scrollOrientation":"horizontal", //滚动方向
 "scrollTop":0 //隐藏在滚动条上方的页面的高度
}

属性

参数 说明 类型 默认值
showScrollbar 控制是否出现滚动条 boolean true
scrollDirection 控制滚动的方向 string(horizontal 或者 vertical) vertical
offsetAccuracy 控制
scroll
事件触发的频率,默认值为 10,表示两次
scroll
事件之间列表至少滚动了 10px。注意,将该值设置为较小的数值会提高滚动事件采样的精度,但同时也会降低页面的性能
number 10
scrollTop 距离顶部的位置 string true
scrollLeft 距离左边的位置(横向滚动) string 0px
scrollWithAnimation 是否开启滚动动画 boolean false
scrollAnimationDuration 滚动动画时长(milliseconds) number 200

**备注:**
scrollDirection 定义了 scroller 的滚动方向,样式表属性 flexDirection 定义了 scroller 的布局方向,两个方向必须一致。例如:

  • scrollDirection 的默认值是 verticalflexDirection 的默认值是 column
  • 当需要一个水平方向的 scroller 时,使用 scrollDirection="horizontal"flexDirection: row;
  • 当需要一个竖直方向的 scroller 时,使用 scrollDirection="vertical"flexDirection: column,由于这两个值均是默认值,当需要一个竖直方向的 scroller 时,这两个值可以不设置。

    事件

    | onScrollToUpper | 滚动到顶部/左边,会触发该事件。 | | —- | —- | | onScrollToLower | 滚动到底部/右边,会触发该事件。 | | onScroll | 滚动时触发, event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth}。 | | onScrollStart | 滑动开始 | | onScrollEnd | 滑动结束 |