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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM