<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          webview 和 React Native 中吸頂效果實(shí)現(xiàn)

          共 6118字,需瀏覽 13分鐘

           ·

          2022-08-02 20:04

          一前言

          在跨端開發(fā)中,離不開一些吸頂?shù)慕换鼍埃梢詤⒖继詫毣蚴蔷〇|類電商 app 中一些 tab ,在整個(gè)容器滑動(dòng)的過程中,吸頂效果非常的連貫和絲滑的,當(dāng)然這些 tab 可能是用 native 開發(fā)的,但是跨端應(yīng)用也能實(shí)現(xiàn)很不錯(cuò)的吸頂效果,那么今天我們就來研究一下跨端開發(fā)是如何實(shí)現(xiàn)吸頂?shù)摹?/p>

          希望通過這篇文章,你將學(xué)習(xí)到:

          • webview 中吸頂?shù)膶?shí)現(xiàn)方式。
          • React Native 中吸頂方法,SectionList 是如何實(shí)現(xiàn)吸頂?shù)摹?/section>

          創(chuàng)作不易,希望屏幕前的你能給筆者賞個(gè)贊,以此鼓勵(lì)我繼續(xù)創(chuàng)作前端硬文。??????

          二 webview 吸頂實(shí)現(xiàn)方式

          在移動(dòng)端開發(fā)中,webview 已經(jīng)成為很重要的一部分,比如 app 中內(nèi)嵌的 web 頁面,或者小程序的視圖載體,本質(zhì)上都是 webview。

          基于 webview 的混合開發(fā)模式非常受到歡迎,回到今天的主題上來,在 webview 中如何實(shí)現(xiàn)吸頂效果呢?

          2.1 position :sticky

          webview 本質(zhì)上就是 web 應(yīng)用,所以我們可以使用 css 屬性來做很多交互效果。如果說到吸頂效果,這里首先想到的就是 position:sticky 粘性屬性。

          position:sticky 是一個(gè)新的css3屬性,它的表現(xiàn)類似于 position:relative 和 position:fixed 的交集。

          • 在目標(biāo)區(qū)域在屏幕中可見時(shí),它的行為就像 position:relative;
          • 而當(dāng)頁面滾動(dòng)超出目標(biāo)區(qū)域時(shí),它的表現(xiàn)就像 position:fixed,它會(huì)固定在目標(biāo)位置。

          通過上面可以得出,如果實(shí)現(xiàn)吸頂效果,設(shè)置一個(gè) css 屬性就能實(shí)現(xiàn)。

          WechatIMG2225.jpeg

          如上圖所示,圖中 head 部分是需要吸頂?shù)膬?nèi)容,那么把 head 加上 position:sticky 就可以了。

          sticky 的缺點(diǎn):

          當(dāng)然 sticky 也有一些缺點(diǎn):

          • sticky 屬性存在兼容性。
          • sticky 和 absolute 定位屬性在 ios 上的表現(xiàn)不友好,在 scrollview 等視圖容器組件內(nèi)部滾動(dòng)時(shí)候,可能存在抖動(dòng)的問題,這樣用戶體驗(yàn)非常差。

          2.2 scrollview

          webview 還有一種實(shí)現(xiàn)吸頂?shù)姆椒ǎ褪峭ㄟ^ scrollview ,scrollview 是什么?scrollview 是一個(gè)滾動(dòng)的容器組件,web 中并沒有現(xiàn)成的 scrollview 組件,常見的 scrollview 組件主要存在小程序或者一些跨段解決方案中,比如 Taro 中的 Scrollview,這些組件并非是原生組件,都是在各個(gè)平臺(tái)底層基于原生的 DOM 元素和 EventListener 封裝的。

          以微信小程序?yàn)槔樱匆幌?scroll-view 如何實(shí)現(xiàn)吸頂,這種方式主要是依靠計(jì)算的方式,來確定什么時(shí)候元素應(yīng)該吸頂了。因?yàn)?scroll-view 上有回調(diào)函數(shù) bindscroll ,可以實(shí)時(shí)的得到滾動(dòng)的距離,使用滾動(dòng)距離,可以推導(dǎo)出吸頂臨界點(diǎn),比如:

          WechatIMG2243.jpeg

          通過上面可以推導(dǎo)出 offsetTop === scrollTop 此時(shí)就是 current 吸頂?shù)呐R界點(diǎn)。當(dāng)然在不同場景下,這個(gè)臨界點(diǎn)可以會(huì)有區(qū)別,但大體思路是不變的。

          但是目前可能存在一些問題,就是如果我們繼續(xù)通過 position:absolute 來觸發(fā)吸頂?shù)脑挘€會(huì)有 2.1 面臨的問題——在 scroll-view 中使用了定位產(chǎn)生抖動(dòng),那么應(yīng)該如何處理呢?

          筆者在這里推薦大家一種方法就是,用兩個(gè)吸頂模塊,來模擬吸頂效果的實(shí)現(xiàn):

          • 如上 current 是需要吸頂?shù)慕M件,但是我們準(zhǔn)備兩個(gè)狀態(tài)一樣的組件 current1 和 current2,current1 在 scroll-view 外部,用 fixed 定位,定位在容器頂部,current2 在 scroll-view 內(nèi)部,不加任何定位效果。
          • 在正常情況下,不是吸頂情況下,current1 是隱藏狀態(tài) ,current2 是顯示狀態(tài)。
          • 如果達(dá)到了吸頂?shù)呐R界點(diǎn),那么改變狀態(tài),current1 變成顯示狀態(tài),current2 變成隱藏狀態(tài),這里有一點(diǎn)需要注意,因?yàn)槲覀冸[藏了 current2 如果不做處理,會(huì)讓下面元素頂上來,這里處理的方案是通過一個(gè)元素占位,如下面代碼塊中 class="hold" 元素,就是占位元素。占位元素的高度和 current2 高度相同。
          WechatIMG2257.jpeg

          用代碼簡單描述一下過程:

          wxml中:

          <current1 wx-if="{{ show }}" >
          <scroll-view bindscroll="{{ handleScroll }}"  >
             <view class="hold" wx-if="{{ show }}" />
             <current2 wx-if="{{ !show }}" >
          </scroll-view>

          js 中:

          /* 處理滾動(dòng)事件 */
          handleScroll(event){
              const { scrollTop } = event.detail
              const { offsetTop,show }= this.data
              const isCeiling = scrollTop === offsetTop
              if(isCeiling !== show ){
                  /* 當(dāng)吸頂狀態(tài)發(fā)生變化時(shí) */
                  this.setData({
                     show:isCeiling
                  })
              }
          }

          這種方式實(shí)現(xiàn)吸頂也有一些缺點(diǎn),就是當(dāng)快速滑動(dòng)的時(shí)候,比如小程序,因?yàn)橛|發(fā)吸頂調(diào)用 setData ,setData 底層會(huì)調(diào)用于 native 通信的方法,這樣視圖上的更新會(huì)滯后,直觀上的感受就是置頂效果滯后。

          三 React Native 中的吸頂方式

          React Native 是跨端開發(fā)的一個(gè)解決方案,不同于 webview,webview 的渲染還是走 web 那一套,而 RN 這個(gè)一點(diǎn)就不同于 webview,采用了 Native 方式來渲染,所以就渲染性能上要優(yōu)于 webview。

          RN 中有很多中實(shí)現(xiàn)吸頂?shù)姆绞剑琒crollView ,F(xiàn)latList ,和 SectionList 都能實(shí)現(xiàn)吸頂效果,

          3.1 ScrollView 和 FlatList

          ScrollView 和 FlatList 一般用于列表組件,兩者中有一個(gè)stickyHeaderIndices 可以輕松實(shí)現(xiàn)吸頂效果。

          <ScrollView
             stickyHeaderIndices={[0]}//第一個(gè)子元素即頭部組件,上滑時(shí)吸頂  
          />
          • stickyHeaderIndices: 一個(gè)子視圖下標(biāo)的數(shù)組,用于決定哪些成員會(huì)在滾動(dòng)之后固定在屏幕頂端。舉個(gè)例子,傳遞stickyHeaderIndices={[0]}會(huì)讓第一個(gè)成員固定在滾動(dòng)視圖頂端。這個(gè)屬性不能和horizontal={true}一起使用。

          但是筆者在工作中,用到吸頂?shù)膱鼍埃⒉皇菃螁瘟斜碇械哪骋粋€(gè)元素,有可能是視圖中某一個(gè) section 模塊的頭部。

          所以接下來重點(diǎn)介紹一個(gè)場景,就是通過 SectionList 來實(shí)現(xiàn)吸頂效果。

          3.2 SectionList 介紹及如何實(shí)現(xiàn)吸頂效果

          SectionList 是高性能的分組(section)列表組件,支持下面這些常用的功能:

          • 完全跨平臺(tái)。
          • 行組件顯示或隱藏時(shí)可配置回調(diào)事件。
          • 支持單獨(dú)的頭部組件。
          • 支持單獨(dú)的尾部組件。
          • 支持自定義行間分隔線。
          • 支持分組的頭部組件。
          • 支持分組的分隔線。
          • 支持多種數(shù)據(jù)源結(jié)構(gòu)
          • 支持下拉刷新。
          • 支持上拉加載。

          SectionList 顧名思義,就是分 Section 模塊的列表。SectionList 的吸頂效果也是得益于一個(gè)屬性——stickySectionHeadersEnabled。

          當(dāng) stickySectionHeadersEnabled 為 true 的時(shí)候,當(dāng)下一個(gè) section 把它的前一個(gè) section 的可視區(qū)推離屏幕的時(shí)候,讓這個(gè) section 的 header 粘連在屏幕的頂端。這個(gè)屬性在 iOS 上是默認(rèn)可用的,因?yàn)檫@是 iOS 的平臺(tái)規(guī)范。

          WechatIMG2259.jpeg

          如上我們期望 section2 的 current 模塊吸頂,那么當(dāng) section1 元素離開可視區(qū)域的時(shí)候,section2 的 current 就會(huì)吸頂了。這樣說,有的同學(xué)可能不明白,我們來看一下具體使用。

          具體使用:

          const defaultSections = [
              { 
                  data:[ name:'section1' ], 
                  key:'section1',
              },
              { 
                  data:[ name:'section2' ], 
                  key:'section2',
              },
          ]
          function Index(){
              //....省去一些邏輯
              const renderContent = ({ item:{ name } }) => ( name === 'section1' ? <Section1Content /> : <Section2Content />);
              /* 當(dāng)只有 section2 有頭部并且會(huì)吸頂 */
              const renderHeader = ({ section:{ key } }) => (key === 'section2' && <Current />)
              return <SectionList  
                  sections={defaultSections}         // section 的配置項(xiàng)
                  renderSectionHeader={renderHeader} // 分 section 渲染頭部
                  renderItem={renderContent}         // 分 section 渲染主體內(nèi)容
                  stickySectionHeadersEnabled        // 設(shè)置吸頂狀態(tài)為 true
              />

          }
          • 如上,可以通過 sections ,renderSectionHeader,renderItem 來自由的組合 SectionList 需要展現(xiàn)的 content 和  header,這樣會(huì)讓吸頂功能更加靈活。

          四 總結(jié)

          本文介紹了跨端開發(fā)中,webview 和 React Native 實(shí)現(xiàn)吸頂?shù)闹髁鞣绞剑M芙o做此類功能的同學(xué)提供一個(gè)解決思路。

          參考文檔

          • React Native 中文網(wǎng)

          參考資料

          [1]

          https://juejin.cn/post/7112770927082864653: https://juejin.cn/post/7112770927082864653


          瀏覽 160
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国 产 成 人 在 线 视频观看 | 性拍拍视频 | 日韩欧美中文字幕在线视频 | 免费的黄色视频网站在线 | 中国东北农村乱子毛片 |