<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          BetterScroll移動端滾動場景的應用

          時間:?2017-11-24閱讀:?3055標簽:?滾動

          BetterScroll 是一款重點解決移動端各種滾動場景需求的開源插件(GitHub地址),有下列功能支持滾動列表,下拉刷新,上拉刷新,輪播圖,slider等功能。
          為了滿足這些功能,better-scroll通過使用慣性滾動、邊界回彈、滾動條淡入淡出來確保滾動的流暢。同時還支持很多API和事件,具體支持的事件可以查看官網講的非常詳細。
          由于它基于原生JavaScript 實現,不依賴任何框架,所以既可以原生 JavaScript 引用,也可以與目前前端 MVVM 框架結合使用,比如,其官網上的示例就是與 Vue 的結合。


          如何使用:

          再講如何使用的之前,我們先來了解一下他的滾動原理:在瀏覽器中的滾動中,當內容的高度高于外邊容器的高度的時候也就出現了滾動條,我們可以通過使用滾動條來看到超出的部分.

          better-scroll的原理正是基于這里,內容部分的寬度/高度必須大于外部寬度/高度。所以在使用
          的時候外部容器的需要設置固定寬度,還有一個問題需要設置overflow:hidden,這是因為為了隱藏超出部分。然后就是什么時候對better-scroll進行初始化,這個有點麻煩,但是所幸,作者已經在vue框架下進行封裝,我們只需要像個麻瓜一樣往里邊填東西就行了。但是有一點需要注意:滾動的元素只能是第一個容器的第一個元素。源碼如下:

            // this.scroller就是滾動的內容,this.wrapper是容器
              this.scroller = this.wrapper.children[0]
          

          如果我們需要滾動多個內容怎么辦呢,就用一個元素將其包裹住,讓他成為容器的第一個子元素就行了。


          讓滾動更流暢

          在移動端,如果你使用過 overflow: scroll 生成一個滾動容器,會發現它的滾動是比較卡頓,呆滯的。為什么會出現這種情況呢?

          因為我們早已習慣了目前的主流操作系統和瀏覽器視窗的滾動體驗,比如滾動到邊緣會有回彈,手指停止滑動以后還會按慣性繼續滾動一會,手指快速滑動時頁面也會快速滾動。而這種原生滾動容器卻沒有,就會讓人感到卡頓。

          BetterScroll 的滾動體驗

          試一試 BetterScroll 的滾動體驗吧。體驗地址

          可以發現,在增加慣性滾動,邊緣回彈等效果之后,明顯流暢、舒服了很多。那么,這些效果是怎么實現的呢?

          慣性滾動

          BetterScroll 在用戶滑動操作結束時,還會繼續慣性滾動一段。首先看一下源碼中的 BScroll.prototype._end 函數,這是 touchend、mouseup、touchcancel、mousecancel 事件的處理函數,也就是用戶滾動操作結束時的邏輯。

          BScroll.prototype._end = function (e) {
              ...
              if (this.options.momentum && duration < this.options.momentumLimitTime && (absDistY > this.options.momentumLimitDistance || absDistX > this.options.momentumLimitDistance)) {
                let momentumX = this.hasHorizontalScroll ? momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options)
                  : {destination: newX, duration: 0}
                let momentumY = this.hasVerticalScroll ? momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options)
                  : {destination: newY, duration: 0}
                newX = momentumX.destination
                newY = momentumY.destination
                time = Math.max(momentumX.duration, momentumY.duration)
                this.isInTransition = 1
              }
              ...
          }

          以上代碼的作用是,在用戶滑動操作結束時,如果需要開啟了慣性滾動,用 momentum 函數計算慣性滾動距離和時間。該函數,根據用戶滑動操作的速度和 deceleration選項 ——慣性減速來計算滾動距離,至于滾動時間,也是一個可配置的選項。

          function momentum(current, start, time, lowerMargin, wrapperSize, options) {  
            ...
            let distance = current - start
            let speed = Math.abs(distance) / time
            ...
            let duration = swipeTime
            let destination = current + speed / deceleration * (distance < 0 ? -1 : 1)
            ...
          }

          邊緣回彈

          超過邊緣時的回彈,有兩個處理步驟,第一步是滾動到超過邊界時速度要變慢,第二步是回彈到邊界。其中,第一步是在源碼的 BScroll.prototype._move 函數,這是 touchmove 和 mousemove 事件的處理函數,也就是在用戶滑動操作過程中的邏輯。

          // Slow down or stop if outside of the boundaries
          if (newY > 0 || newY < this.maxScrollY) {
              if (this.options.bounce) {
                  newY = this.y + deltaY / 3
              } else {
                  newY = newY > 0 ? 0 : this.maxScrollY
              }
          }

          第二步是調用 BScroll.prototype.resetPosition 函數,回彈到邊界。

          BScroll.prototype.resetPosition = function (time = 0, easeing = ease.bounce) {
              ...
              let y = this.y
              if (!this.hasVerticalScroll || y > 0) {
                y = 0
              } else if (y < this.maxScrollY) {
                y = this.maxScrollY
              }
              ...
              this.scrollTo(x, y, time, easeing)
              ...
            }

          流暢的滾動僅僅是基礎,BetterScoll 真正的能力在于:提供了大量通用 / 定制的option 選項 、API 方法和事件,讓各種滾動需求實現起來更高效。


          如何應用于各種需求場景

          下面,以結合 Vue 的使用為例,說一下 BetterScroll 在各種場景下的姿勢。

          普通滾動列表

          比如,有如下列表:

          • {{item}}

          我們想要讓它垂直滾動,只需要對該容器進行簡單的初始化。

          import BScroll from 'better-scroll'
          
          const options = {
            scrollY: true // 因為scrollY默認為true,其實可以省略
          }
          
          this.scroll = new BScroll(this.$refs.wrapper, options)

          對于 Vue 中使用 BetterScroll,有一個需要注意的點是,因為在 Vue 模板中列表渲染還沒完成時,是沒有生成列表 DOM 元素的,所以需要在確保列表渲染完成以后,才能創建 BScroll 實例,因此在 Vue 中,初始化 BScroll 的最佳時機是 mouted 的 nextTick。

          // 在 Vue 中,保證列表渲染完成時,初始化 BScroll
          mounted() {
             setTimeout(() => {
               this.scroll = new BScroll(this.$refs.wrapper, options)
             }, 20)
          },

          初始化之后,這個 wrapper 容器就能夠優雅地滾動了,并且可以通過 BScroll 實例 this.scroll 使用其提供的 API 方法和事件。

          下面介紹幾個常用的選項、方法和事件。

          滾動條

          scrollbar 選項,用來配置滾動條,默認為 false。當設置為 true 或者是一個 Object,開啟滾動條。還可以通過 fade 屬性,配置滾動條是隨著滾動操作淡入淡出,還是一直顯示。

          // fade 默認為 true,滾動條淡入淡出
          options.scrollbar = true
          
          // 滾動條一直顯示
          options.scrollbar = {
            fade: false
          }
          
          this.scroll = new BScroll(this.$refs.wrapper, options)

          具體效果可見普通滾動列表-示例。

          下拉刷新

          pullDownRefresh 選項,用來配置下拉刷新功能。當設置為 true 或者是一個 Object 的時候,開啟下拉刷新,可以配置頂部下拉的距離(threshold)來決定刷新時機,以及回彈停留的距離(stop)

          options.pullDownRefresh = {
            threshold: 50, // 當下拉到超過頂部 50px 時,觸發 pullingDown 事件
            stop: 20 // 刷新數據的過程中,回彈停留在距離頂部還有 20px 的位置
          }
          
          this.scroll = new BScroll(this.$refs.wrapper, options)

          監聽 pullingDown 事件,刷新數據。并在刷新數據完成之后,調用 finishPullDown() 方法,回彈到頂部邊界

          this.scroll.on('pullingDown', () => {
            // 刷新數據的過程中,回彈停留在距離頂部還有20px的位置
            RefreshData()
              .then((newData) => {
                this.data = newData
                // 在刷新數據完成之后,調用 finishPullDown 方法,回彈到頂部
                this.scroll.finishPullDown()
            })
          })

          具體效果可見普通滾動列表-示例。

          上拉加載

          pullUpLoad 選項,用來配置上拉加載功能。當設置為 true 或者是一個 Object 的時候,可以開啟上拉加載,可以配置離底部距離閾值(threshold)來決定開始加載的時機

          options.pullUpLoad = {
            threshold: -20 // 在上拉到超過底部 20px 時,觸發 pullingUp 事件
          }
          
          this.scroll = new BScroll(this.$refs.wrapper, options)

          監聽 pullingUp 事件,加載新數據。

          this.scroll.on('pullingDown', () => {
            loadData()
              .then((newData) => {
                this.data.push(newData)
            })
          })

          具體效果可見普通滾動列表-示例。

          選擇器

          wheel 選項,用于開啟并配置選擇器。可配置選擇器當前選擇的索引(selectedIndex),列表的彎曲弧度(rotate),以及切換選擇項的調整時間(adjustTime)。

          options.wheel = {
            selectedIndex: 0,
            rotate: 25,
            adjustTime: 400
          }
          
          // 初始化選擇器的每一列
          this.wheels[i] = new BScroll(wheelWrapper.children[i], options)

          具體效果可見選擇器 - 示例。

          其中聯動選擇器,需要監聽每個選擇列表的選擇,來改變其他選擇列表。

          data() {
             return {
               tempIndex: [0, 0, 0]
             }
          },
          ...
          // 監聽每個選擇列表的選擇
          this.wheels[i].on('scrollEnd', () => {
            this.tempIndex.splice(i, 1, this.wheels[i].getSelectedIndex())
          })
          ...
          // 根據當前選擇項,確定其他選擇列表的內容
          computed: {
            linkageData() {
              const provinces = provinceList
              const cities = cityList[provinces[this.tempIndex[0]].value]
              const areas = areaList[cities[this.tempIndex[1]].value]
          
              return [provinces, cities, areas]
            }
          },

          具體效果可見選擇器 - 示例中的聯動選擇器。

          輪播圖

          snap 選項,用于開啟并配置輪播圖。可配置輪播圖是否循環播放(loop),每頁的寬度(stepX)和高度(stepY),切換閾值(threshold),以及切換速度(speed)。

          options = {
            scrollX: true,
            snap: {
              loop: true, // 開啟循環播放
              stepX: 200, // 每頁寬度為 200px
              stepY: 100, // 每頁高度為 100px
              threshold: 0.3, // 滾動距離超過寬度/高度的 30% 時切換圖片
              speed: 400 // 切換動畫時長 400ms
            }
          }
          
          this.slide = BScroll(this.$refs.slide, options)

          具體效果可見輪播圖 - 示例。


          特殊場景

          除了普通滾動列表、選擇器、輪播圖等基礎滾動場景,還可以利用 BetterScroll 提供的能力,做一些特殊場景。

          索引列表

          索引列表,首先需要在滾動過程中實時監聽滾動到哪個索引的區域了,來更新當前索引。在這種場景下,我們可以使用 probeType 選項,當此選項設置為 3 時,會在整個滾動過程中實時派發 scroll 事件。從而獲取滾動過程中的位置。

          options.probeType = 3
          this.scroll = new BScroll(this.$refs.wrapper, options)
          
          this.scroll.on('scroll', (pos) => {
            const y = pos.y
          
            for (let i = 0; i < listHeight.length - 1; i++) {
              let height1 = listHeight[i]
              let height2 = listHeight[i + 1]
              if (-y >= height1 && -y < height2) {
                this.currentIndex = i
              }
            }
          })

          當點擊索引時,使用 scrollToElement()方法 滾動到該索引區域。

          scrollTo(index) {
            this.$refs.indexList.scrollToElement(this.$refs.listGroup[index], 0)
          }

          具體效果可見索引列表 - 示例。

          開屏引導

          開屏引導,其實就是一種不自動循環播放的橫向滾動輪播圖而已。

          options = {
            scrollX: true,
            snap: {
              loop: false
            }
          }
          
          this.slide = BScroll(this.$refs.slide, options)

          具體效果可見開屏引導 - 示例。因為此需求場景一般只有移動端才有,所以最好在手機模式下看效果。

          自由滾動

          freeScroll 選項,用于開啟自由滾動,允許橫向和縱向同時滾動,而不限制在某個方向。

          options.freeScroll = true

          另外需要注意的是,此選項在eventPassthrough 設置了保持原生滾動時無效。

          具體效果可見自由滾動-示例。


          小結

          BetterScroll 可以用于幾乎所有滾動場景,本文僅介紹了在一些典型場景下的使用姿勢。

          作為一款旨在解決移動端滾動需求的插件,BetterScroll 開放的眾多選項、方法和事件,其實,就是提供了一種讓我們更加快捷、靈活、精準時機地處理滾動的能力。

          作者:滴滴webapp架構組-付楠。
          原文鏈接:http://www.tuicool.com/articles/UJvIjmJ  


          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/163

          CSS-界面滾動時不顯示滾動條

          ::-webkit-scrollbar CSS偽類選擇器影響了一個元素的滾動條的樣式,你可以使用以下偽元素選擇器去修改各式webkit瀏覽器的滾動條樣式:::-webkit-scrollbar — 整個滾動條.::-webkit-scrollbar-button — 滾動條上的按鈕 (上下箭頭).

          scrollBehavior 切換到新路由時,頁面要滾動到頂部或保持原先的滾動位置

          當創建一個 Router 實例,可以提供一個 scrollBehavior 方法:scrollBehavior 方法接收 to 和 from 路由對象。第三個參數 savedPosition 當且僅當 popstate 導航 (通過瀏覽器的 前進/后退 按鈕觸發) 時才可用。

          jquery擴展方法:實現模擬Marquee無限循環滾動

          在一些網站的公告欄有這樣的一個效果,如果有多條公告就會出現上下滾動效果【也叫做跑馬燈效果】,這是如何實現的呢?下面通過基于jquery的擴展

          JS 判斷元素是否可以滾動

          今天在解決 ios 移動端滾動穿透的問題時遇到一個問題,就是判斷元素能否滾動,把這個過程記錄下來。以下以縱向滾動為例,橫向滾動同理。scrollHeight 是一個元素內容高度的度量,包括由于溢出導致的視圖中不可見的內容

          JS原生實現連續滾動文字

          最近在工作中遇到,文字在大屏中,出現底部有留白導致不連續的現象,很奇怪,故寫這篇文章細究其原因;offsetTop 小于等于 scrollTop時 scrollTop至為0,此次滾動條回到初始位置

          Js獲取滾動的頭部距離和左邊距離

          Js獲取滾動的頭部距離和左邊距離:在js中,經常會用到需要獲取頭部距離和左邊距離的小功能,在這里封裝一下,以后可以直接調用即可:

          DOM盒模型和位置 client offset scroll 和滾動的關系

          在dom里面有幾個描述盒子位置信息的值,pading border margin,width height,client;盒模型生產環境一般使用 box-sizing: border-box,效果:width == content.width + pading + border

          頁面平滑滾動小技巧

          今天寫需求的時候發現一個小的優化點:用戶選擇了一些數據之后, 對應列表中的數據需要高亮, 有時候列表很長, 為了提升用戶體驗,需要加個滾動, 自動滾動到目標位置。

          overflow滾動條如何隱藏?

          隱藏滾動條有很多方法,比較簡單和直觀的方法可以使用::-webkit-scrollbar來完成,這樣的話就把box本身的滾動條隱藏了。如果要兼容 PC 其他瀏覽器

          vue 無限滾動問題

          如今web開發中,無限加載是必需的一項功能,尤其是在移動端開發中,一個列表往往默認只加載10條,想看更多只能逐漸往下翻頁。那么今天就看看如何在Vue-Cli中實現這個功能

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网