• uni-app scroll-view 点击实现元素居中?


    前言

    在 uni-app 开发中  scroll-view 组件用到几率也是比较大滴,存在问题主要是:点击子元素,子元素在什么位置展示?

    今天我们来好好总结一下 0.0~

    Part.1  可能出现的需求

    效果一:当前点击子元素靠左展示

    效果二:当前点击子元素靠左留一展示

    效果三:当前点击子元素居中展示

    应该常见的用户体验效果就这三种了,我们看看怎么实现?go~

    Part.2  我的思路

    在 uni-app 的官方( https://uniapp.dcloud.io/component/scroll-view ) API中对 scroll-view 组件有详细的介绍和属性说明,今天我们主要用到的属性是:scroll-left (设置横向滚动条的位置)

    一般偷懒或者常用的方式是使用 scroll-into-view 这个属性,随着当前点击元素的ID滚动,但是这个属性制作出来后会和我上面 效果一 样靠左展示,这种展示方式体验不是太好(从前往后点击可能还好,但是从后往前就很...),这种方式配合 swiper 或者其它组件做长列表或者其它还可勉强接受,因为不用去点击,直接手动滑动就可切换。但是假如不存在手可滑动的话,就会很糟糕。

    接下来我们具体来看看,这三种效果如何实现:

    效果一: 可直接使用 scroll-into-view 属性实现  或者 也可使用  scroll-left

    思路:第一种, scroll-into-view 绑定一个动态 ID,子元素循环产出ID,点击时进行绑定(这次就不做代码产出了)

               第二种, 计算每个子元素的宽度,点击时获取当前点击元素前面的元素宽度之和

    效果二:使用  scroll-left

    思路:计算每个子元素的宽度,点击时获取当前点击元素索引 - 1 的前面元素宽度之和,相比于效果一的第二种情况,这里少算当前点击元素前面的一个元素的宽度,实现留一

    效果三:使用  scroll-left

    思路:当前点击子元素距离左边栏的距离 - scroll-view 宽度的一半  + 当前点击子元素一半的宽度 实现居中展示

    Part.3  代码实现

     1 <template>
     2     <view class="lxy-content">
     3         <scroll-view scroll-x="true" 
     4                      class="content-scroll" 
     5                      scroll-with-animation 
     6                      :scroll-left="scrollLeft">  
     7             <view v-for="(item, index) in category"
     8                   :key="index"
     9                   class="scroll-item"
    10                   @click="changeTitle(index)">
    11                 <text class="item-text"
    12                       :class="curIndex == index? 'active' : ''">{{item.name}}</text>
    13             </view>
    14         </scroll-view>
    15     </view>
    16 </template>
      1 <script>
      2     export default {
      3         data() {
      4             return {
      5                 category: [
      6                     {
      7                         id: 1,
      8                         name: '星期一' 
      9                     },
     10                     {
     11                         id: 2,
     12                         name: '星期二' 
     13                     },
     14                     {
     15                         id: 3,
     16                         name: '星期三' 
     17                     },
     18                     {
     19                         id: 4,
     20                         name: '星期四' 
     21                     },
     22                     {
     23                         id: 5,
     24                         name: '星期五' 
     25                     },
     26                     {
     27                         id: 6,
     28                         name: '星期六' 
     29                     },
     30                     {
     31                         id: 7,
     32                         name: '星期七' 
     33                     },
     34                     {
     35                         id: 8,
     36                         name: '星期八' 
     37                     },
     38                     {
     39                         id: 9,
     40                         name: '星期九' 
     41                     },
     42                     {
     43                         id: 10,
     44                         name: '星期十' 
     45                     }
     46                 ],
     47                 
     48                 contentScrollW: 0, // 导航区宽度
     49                 curIndex: 0, // 当前选中
     50                 scrollLeft: 0, // 横向滚动条位置
     51             }
     52         },
     53         mounted() {
     54             // 获取标题区域宽度,和每个子元素节点的宽度
     55             this.getScrollW()
     56         },
     57         methods: {
     58             // 获取标题区域宽度,和每个子元素节点的宽度以及元素距离左边栏的距离
     59             getScrollW() {
     60                 const query = uni.createSelectorQuery().in(this);
     61                 
     62                 query.select('.content-scroll').boundingClientRect(data => {
     63                     // 拿到 scroll-view 组件宽度
     64                     this.contentScrollW = data.width
     65                 }).exec();
     66                 
     67                 query.selectAll('.scroll-item').boundingClientRect(data => {
     68                     let dataLen = data.length;
     69                     for (let i = 0; i < dataLen; i++) {
     70                         //  scroll-view 子元素组件距离左边栏的距离
     71                         this.category[i].left = data[i].left;
     72                         //  scroll-view 子元素组件宽度
     73                         this.category[i].width = data[i].width
     74                     }
     75                 }).exec()
     76             },
     77             
     78             
     79             // 选择标题
     80             changeTitle(index) {
     81                 this.curIndex = index;
     82     
     83                 // 效果一(当前点击子元素靠左展示)  局限性:子元素宽度相同
     84                 this.scrollLeft = index  * this.category[index].width
     85                 
     86                 // 效果一(当前点击子元素靠左展示)  子元素宽度不相同也可实现
     87                 /* this.scrollLeft = 0;
     88                 for (let i = 0; i < index; i++) {
     89                     this.scrollLeft += this.category[i].width
     90                 }; */
     91                 
     92                 
     93                 // 效果二(当前点击子元素靠左留一展示)  局限性:子元素宽度相同
     94                 /* this.scrollLeft = (index - 1)  * this.category[index].width */
     95                 
     96                 // 效果二(当前点击子元素靠左留一展示)  子元素宽度不相同也可实现
     97                 /* this.scrollLeft = 0;
     98                 for (let i = 0; i < index - 1; i++) {
     99                     this.scrollLeft += this.category[i].width
    100                 }; */
    101                 
    102                 
    103                 // 效果三(当前点击子元素居中展示)  不受子元素宽度影响
    104                 /* this.scrollLeft = this.category[index].left - this.contentScrollW / 2 + this.category[index].width / 2; */
    105                 
    106             }
    107         }
    108     }
    109 </script>
     1 <style lang="scss" scoped>
     2     .lxy-content {
     3         width: 100%;
     4         height: 100rpx;
     5         margin-top: 50rpx;
     6         box-sizing: border-box;
     7         .content-scroll {
     8             height: 100rpx;
     9             white-space: nowrap;
    10             .scroll-item {
    11                 height: 100rpx;
    12                 padding: 0 20rpx;
    13                 display: inline-block;
    14                 text-align: center;
    15                 .item-text {
    16                     font-size: 30rpx;
    17                     line-height: 100rpx;
    18                     &.active {
    19                         color: #1468FF;
    20                     }
    21                 }
    22             }
    23         }
    24     }
    25 </style>
  • 相关阅读:
    RxJava API使用示例
    使用create-react-app模板模仿12306app
    web 基本概念辨异 —— URI 与 URL
    RESTful 架构与 RESTful 服务
    python startswith和endswith
    python enumerate函数用法
    python中PIL.Image和OpenCV图像格式相互转换
    Linux查看当前在线用户信息
    Linux查看GPU信息和使用情况
    python中的编码和解码
  • 原文地址:https://www.cnblogs.com/langxiyu/p/13159055.html
Copyright © 2020-2023  润新知