美文网首页
小程序获取指定区滚动高度,scrollview的高度

小程序获取指定区滚动高度,scrollview的高度

作者: smallzip | 来源:发表于2020-05-31 18:35 被阅读0次

    在业务中,经常需要用到滚动视图scrollview,特别是使用自定义导航栏的情况下,如果不使用scrollview会导致自定义导航栏被连带滚动上去,所以不得不使用scrollview。scrollview默认是必须要设置高度的,当业务页面多了之后每个也都设置一遍高度既繁琐又重复,这样的情况不得已封装了一个获取scrollview搞的方法,能够实现只获取需要滚动的视图位置高度。

    效果1

    小程序滚动视图1.gif

    效果2

    小程序滚动视图2.gif

    效果1代码块

    <!--pages/about-us/index.wxml-->
    
    <view class="container">
      <!-- 头部导航 -->
      <nav-bar name="关于我们" typeBar="2" id="header"></nav-bar>
    
    
      <view-box ids="{{['#header']}}" isRefresh="{{false}}">
        <view class="content">
         <view wx:for="{{[1,2,3,4,5,6,6,7,8,9]}}" wx:key="*this" style="height:20vh;width:100vw;text-align:center;background:#f6f4fc;">
          {{item}}
         </view>
        </view>
      </view-box>
    
    </view>
    

    效果2代码块

    <!--pages/about-us/index.wxml-->
    
    <view class="container">
        <!-- 头部导航 -->
        <nav-bar name="关于我们" typeBar="2" id="header"></nav-bar>
    
      <view id="desc" style="height:20vh;text-align:center;">
        我在上面,占了一些空间
        </view>
    
        <!-- 使用滚动视图 -->
        <view-box ids="{{['#header','#foot','#desc']}}" bind:bindrefresherrefresh="bindrefresherrefresh" isRefresh="{{true}}">
            <view class="content">
                <view wx:for="{{[1,2,3,4,5,6,6,7,8,9]}}" wx:key="*this" style="height:20vh;width:100vw;text-align:center;background:#f6f4fc;">
                    {{item}}
                </view>
            </view>
        </view-box>
    
        <view id="foot" style="height:20vh;text-align:center;">
            我是底部,我占了一些空间
        </view>
    
    </view>
    

    我们可以看到,效果1中头部的导航头是不动的,然后内容区域实现了滚动,再看效果1的代码块中,并没有看到使用scrollview标签,那它去哪里了呢?
    答案就是封装在了view-box里面。view-box标签上可以看到ids属性,里面是一个数组,数组里面对应的是页面中其他的试图块的id名称,我们只需要把其他视图快的id赋值进ids数组里面,就可以得到当前的视图块高度了。

    来看看view-box组件

    view-box组件有四个自定义属性

    属性名称 接受参数类型 默认值 说明
    ids Array [] 标签id名数组
    animationTime Number 1500 下拉刷新执行时间
    isRefresh Boolean true 是否允许下拉刷新,默认开启
    isTabBar Boolean false 是否属于主页,即有底部导航栏tabbar的那几个页面

    view-box组件的核心是getScrollHeight.js

    通过wx.createSelectorQuery()方法来获取节点,和节点高度。

    getScrollHeight.js代码如下:

    /**
     * 获取对应视图内容的高度
     * @param array - 传来的id数组
     */
    const app = getApp()
    module.exports = (params, isTabBar) => {
      return new Promise((resolve, reject) => {
        // 获取设备高度
        wx.getSystemInfo({
          success: function(res) {
            let screenHeight = res.windowHeight
            let query = wx.createSelectorQuery();
            for (let i of params) {
              query.select(i).boundingClientRect();
            }
            if (isTabBar) {
              query.select('#container').boundingClientRect();
            }
            query.exec((res) => {
              // 取出每个对应标签容器的高度
              let containerHeight = 0
              if (isTabBar) {
                containerHeight = res[res.length - 1].height
              }
              let noScrollHeight = res.reduce((total, item, index) => {
                if (isTabBar && index == res.length - 1) return total;
                return total + item.height
              }, 0)
    
              // 用设备高度做减法
              let scrollViewHeight
              if (isTabBar) {
                scrollViewHeight = containerHeight - noScrollHeight
              } else {
                scrollViewHeight = screenHeight - noScrollHeight;
              }
              // 算出来最终滚动条的高度
              resolve(scrollViewHeight)
            });
          }
        })
    
      })
    }
    

    view-box组件代码如下

    
    // components/view-box/index.js
    const getScrollHeight = require('../../utils/getScrollHeight.js')
    const app = getApp()
    Component({
      lifetimes: {
        attached: function() {
          // 在组件实例进入页面节点树时执行
          const ids = this.data.ids
          getScrollHeight([...ids], this.data.isTabBar).then(res => {
            this.setData({
              scrollHeight: res
            })
          })
        },
        detached: function() {
          // 在组件实例被从页面节点树移除时执行
        },
      },
      /**
       * 组件的属性列表
       */
      properties: {
        ids: {
          type: Array,
          value: []
        },
        animationTime: {  // 下拉刷新动画时间,默认1500
          type: Number,
          value: 1500
        },
        isRefresh: {  // 是否允许下拉刷新
          type: Boolean,
          value: true
        },
        isTabBar: {  // 是否属于主页,即有底部导航栏tabbar的那几个页面
          type: Boolean,
          value: false
        }
      },
      /**
       * 组件的初始数据
       */
      data: {
        scrollHeight: 0,
        refresher: false,
        scrollTop: 0
      },
    
      /**
       * 组件的方法列表
       */
      methods: {
        // 自定义下拉刷新被触发
        bindrefresherrefresh(e) {
          this.triggerEvent('bindrefresherrefresh', e)
          setTimeout(e => {
            this.setData({
              refresher: false,
              scrollTop: 0
            })
          }, this.data.animationTime)
        }
      }
    })
    
    <!--components/view-box/index.wxml-->
    <scroll-view scroll-y style="width:100vw;height:{{isRefresh?scrollHeight-1:scrollHeight}}px;" refresher-triggered="{{refresher}}" scroll-top="{{scrollTop}}" refresher-enabled bindrefresherrefresh="bindrefresherrefresh">
      <view style="width:100vw;height:100%;padding-bottom: {{isRefresh?1:0}}rpx;">
        <slot></slot>
      </view>
    </scroll-view>
    

    如何使用

    这个组件是很多页面都需要用得到的,建议放在根目录的app.json里面

    组件位置

    配置好之后,组件的使用有两种场景,一种是在有tabbar的页面中使用,另外一种是在非tabbar页面中使用。

    tabbar页面中使用方法

    <!--pages/my-order/index.wxml-->
    
    <!-- 这里要注意,需要设置 id="container",只有tabbar页面才需要设置 -->
    <view class="container tabbar" id="container">
    
       <!-- 头部导航栏 -->
       <nav-bar name="订单" id="navbar" typeBar="3"></nav-bar>
    
     <!-- 内容滚动视图区域,ids是要减去的节点高度, isRefresh是设置可以下拉刷新, isTabBar是设置为tabbar页面,bindrefresherrefresh 是下拉刷新执行的函数,可以在函数内做一些操作,比如重新请求数据 -->
       <view-box ids="{{['#navbar']}}" isRefresh="{{true}}" isTabBar="{{true}}" bind:bindrefresherrefresh="bindrefresherrefresh">
           <view class="content">
         内容
           </view>
       </view-box>
    
    </view>
    

    非tabbar页面使用方法

    <!--pages/about-us/index.wxml-->
    
    <!-- 非tabbar页面不需要设置 id="container" -->
    <view class="container">
      <!-- 头部导航 -->
      <nav-bar name="关于我们" typeBar="2" id="navbar"></nav-bar>
    
      <view-box ids="{{['#navbar']}}" isRefresh="{{false}}">
        <view class="content">
         非tabbar页面
        </view>
      </view-box>
    
    </view>
    

    观看其他内容

    小程序自定义navbar导航栏的实现

    相关文章

      网友评论

          本文标题:小程序获取指定区滚动高度,scrollview的高度

          本文链接:https://www.haomeiwen.com/subject/bsdrzhtx.html