解決移動端滾動穿透

前言

以前一直作PC系統,目前作移動端也遇到一些問題,本文解決移動端滾動的糟心問題!css

全局滾動

全局滾動即滾動是在body上的滾動。若是隻有一個全局滾動是沒有問題的,問題在於全局滾動的頁面出現了彈窗 以下圖所示情景: html

在此狀況下的彈窗會出現以下問題:

滾動穿透--固定彈窗

啥意思呢,就是在彈窗點擊或滑動的時候,底層的全局滾動也會跟着滑動!!! 剛出現問題的時候也在網上查找了一波,嘗試了以下方法:vue

  1. 彈窗時給body設置overflow:hidden;(缺點:ios沒用)
  2. 彈窗時給body設置position:fixed;(缺點:滾動位置會丟失,ios沒用)

針對此情景的完美解決方法是:ios

給彈窗加上@touchmove.stop.prevent,便可阻止touchmove事件傳遞到body,也就解決了滾動穿透git

滾動穿透——滾動彈窗

仍是這張圖,狀況就是彈窗裏也是有滾動的!!!若是使用了@touchmove.stop.prevent,那的確能夠解決滾動穿透的問題,可是因爲阻止了@touchmove,自身也沒法滾動了,不信本身寫demo試試~github

那針對此種狀況完美解決方案是: 在彈窗打開的時候給body的全局滾動設置position:fixed屬性,並設置top值;因爲設置了fixed屬性,那在彈窗的時候body就沒有滾動條了。此時若是這麼設置會發現body雖然沒有了滾動穿透,可是原來的位置丟失了。因此再給body設置fixed屬性的時候,要把當前的滾動位置賦值給css的top屬性,那在視覺上就沒有任何變化了。bash

fixedBody () {
        let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
        document.body.style.cssText += 'position:fixed;width:100%;top:-' + scrollTop + 'px;'
      }
複製代碼

那在彈窗關閉的時候如何處理呢? 彈窗關閉的時候則要清除fixed固定定位和top值;並設置其滾動位置位置top值,則又恢復了滾動功能,並且視覺上沒有任何變化,是目前最完美的解決方案!dom

looseBody () {
        let body = document.body
        body.style.position = ''
        let top = body.style.top
        document.body.scrollTop = document.documentElement.scrollTop = -parseInt(top)
        body.style.top = ''
      }
複製代碼

總結

以上兩種方案解決了固定彈窗和滾動彈窗對於body全局滾動的影響。文章末尾在針對vue作一個自定義指令封裝ui

局部滾動

局部滾動,仍是剛纔的圖片,在彈窗裏的滾動,在Android上滾動沒啥問題,可是在ios局部滾動有時就會實現。spa

復現步驟:

  • ①從滾動區域外從上往下化
  • ②在滑動滾動區域,發現滾動居然失效了!!!活見鬼了....這TM仍是原生屬性。多重發幾回,必定能夠復現的。

解決辦法: 使用插件better-scroll,你們夥本身研究文檔就行。

vue封裝

vue:

directives: {
      fixed: {
        // inserted 被綁定元素插入父節點時調用
        inserted () {
          let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
          document.body.style.cssText += 'position:fixed;width:100%;top:-' + scrollTop + 'px;'
        },
        // unbind 指令與元素解綁時調用
        unbind () {
          let body = document.body
          body.style.position = ''
          let top = body.style.top
          document.body.scrollTop = document.documentElement.scrollTop = -parseInt(top)
          body.style.top = ''
        }
      }
    },
複製代碼

自定義指令使用 html:

<div  v-if="isShowRecordModal" v-fixed>
    ....
    ....
</div>
複製代碼

該指令的注意點是必須使用v-if開啓關閉彈窗,由於該指令依賴於dom的插入和註銷,使用v-show是確定不行的。

結語

種一棵樹最好的時間是十年前,其次是如今。

若是有幫助請點贊喲~

相關文章
相關標籤/搜索