最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端如何解決滾動穿透問題詳解

 更新時間:2025年03月11日 10:46:53   作者:IT楓斗者  
這篇文章主要介紹了前端解決滾動穿透問題的五種常見方法,并詳細分析了它們的優(yōu)缺點和適用場景,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

前言

滾動穿透是指在移動端(或具有滾動條的容器中),當一個可滾動的模態(tài)框(或類似元素)被打開時,如果用戶在該模態(tài)框內(nèi)滾動到盡頭,會導致底層頁面(或父容器)也跟著滾動。這是一種糟糕的用戶體驗。

以下是前端解決滾動穿透問題的幾種常見方法,以及它們的優(yōu)缺點和適用場景:

1. overflow: hidden; (最簡單,但有局限性)

  • 原理: 當模態(tài)框打開時,給 body 或根元素添加 overflow: hidden; 樣式,阻止其滾動。模態(tài)框關(guān)閉時,移除該樣式。

  • 實現(xiàn) (以 Vue 為例):

    <template>
      <div>
        <button @click="showModal = true">Open Modal</button>
        <div v-if="showModal" class="modal">
          <div class="modal-content">
            <!-- 模態(tài)框內(nèi)容 -->
            <button @click="showModal = false">Close</button>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          showModal: false,
        };
      },
      watch: {
        showModal(newValue) {
          if (newValue) {
            document.body.style.overflow = 'hidden';
          } else {
            document.body.style.overflow = ''; // 或 'auto'
          }
        },
      },
      beforeDestroy() { // 重要: 組件銷毀時也要移除
        document.body.style.overflow = '';
      }
    };
    </script>
    
    <style>
    .modal {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      overflow-y: auto; /* 允許模態(tài)框自身滾動 */
    }
    .modal-content{
       /* 模態(tài)框內(nèi)容樣式 */
    }
    </style>
    
  • 優(yōu)點: 簡單易用,代碼量少。

  • 缺點:

    • 頁面跳動: 當 body 的滾動條被隱藏時,頁面可能會因為滾動條消失而產(chǎn)生輕微的跳動(尤其是在 Windows 上)。
    • 丟失滾動位置: 關(guān)閉模態(tài)框后,body 的滾動位置會丟失,回到頂部。
    • 影響其他 fixed 元素: 如果頁面上有其他 position: fixed 的元素(例如固定頭部、固定側(cè)邊欄),它們的位置可能會受到影響,因為 fixed 定位是相對于視口的,而 body 的 overflow: hidden 可能會改變視口的計算方式。
    • 鍵盤可訪問性問題: 如果模態(tài)框是使用鍵盤導航打開的,隱藏body的滾動可能會導致焦點丟失或行為異常.
  • 適用場景: 簡單的模態(tài)框,不需要保留底層頁面滾動位置,且頁面上沒有其他復雜的 fixed 元素。

2. 阻止事件冒泡 (適用于特定場景)

  • 原理: 在模態(tài)框的滾動容器上阻止 touchmove 事件的冒泡(以及可能的 wheel 事件)。

  • 實現(xiàn):

    <template>
      <div v-if="showModal" class="modal">
        <div class="modal-content" @touchmove.prevent.stop @wheel.prevent.stop>
          </div>
      </div>
    </template>
    

    或使用原生JS

    javascript 代碼解讀復制代碼 modalContent.addEventListener('touchmove', function(event) {
        event.preventDefault();
        event.stopPropagation(); //有時候不需要.stop,只阻止默認行為
     }, { passive: false }); //passive:false 是關(guān)鍵
    
* **注意**: 必須要加上 `{ passive: false }` , 默認 passive 是 true,表示不會調(diào)用 preventDefault(). 如果你設(shè)置了 passive: true, 又調(diào)用了 preventDefault(), 瀏覽器會忽略 preventDefault(), 并報一個警告。
  • 優(yōu)點: 只阻止模態(tài)框內(nèi)的滾動事件,不影響其他元素。
  • 缺點:
    • 只能阻止 touchmove 和 wheel: 無法阻止通過鍵盤(如 Page Up/Down)或滾動條拖動引起的滾動。
    • 模態(tài)框內(nèi)部滾動問題: 如果模態(tài)框內(nèi)部本身有多個可滾動區(qū)域,阻止 touchmove 會導致這些區(qū)域也無法滾動。 需要更精細的控制,例如判斷當前滾動元素是否已經(jīng)到達邊界。
  • 適用場景: 模態(tài)框內(nèi)部只有一個滾動區(qū)域,并且不需要鍵盤或滾動條進行滾動的情況。

3. position: fixed; (較好的解決方案)

  • 原理: 當模態(tài)框打開時,將 body 設(shè)置為 position: fixed;,并記錄當前的滾動位置(scrollTop)。關(guān)閉模態(tài)框時,恢復 body 的定位,并設(shè)置回之前記錄的滾動位置。

  • 實現(xiàn):

    <template>
      <div v-if="showModal" class="modal" @touchmove.prevent>  </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          showModal: false,
          scrollTop: 0,
        };
      },
      watch: {
        showModal(newValue) {
          if (newValue) {
            this.scrollTop = window.pageYOffset || document.documentElement.scrollTop;
            document.body.style.position = 'fixed';
            document.body.style.top = `-${this.scrollTop}px`;
            document.body.style.width = '100%'; // 確保 body 寬度占滿
          } else {
            document.body.style.position = '';
            document.body.style.top = '';
            document.body.style.width = '';
            window.scrollTo(0, this.scrollTop);
          }
        },
      },
       beforeDestroy() { // 重要: 組件銷毀時也要移除
         document.body.style.position = '';
            document.body.style.top = '';
            document.body.style.width = '';
            window.scrollTo(0, this.scrollTop);
       }
    };
    </script>
    
  • 優(yōu)點:

    • 保留滾動位置: 關(guān)閉模態(tài)框后,body 的滾動位置可以恢復。
    • 避免頁面跳動: position: fixed; 不會隱藏滾動條,避免了跳動問題。
    • 相對較好地兼容 fixed 元素: 雖然fixed會脫離文檔流,但是因為設(shè)置了top屬性為負的滾動高度,整體頁面視覺上不會移動.
  • 缺點:

    • 代碼略復雜: 需要記錄和恢復滾動位置。
    • 兼容性問題: 在一些舊版本的 iOS Safari 中,position: fixed; 可能會導致一些布局問題(雖然現(xiàn)代瀏覽器基本已修復)。
    • 需要處理滾動條: 需要處理可能存在的滾動條,例如設(shè)置bodywidth:100%, 以防止出現(xiàn)水平滾動條。
  • 適用場景: 大多數(shù)情況下的模態(tài)框,需要保留底層頁面滾動位置,且對兼容性要求不高。

4. 使用第三方庫

  • 原理: 一些第三方庫(如 body-scroll-lock)封裝了更完善的滾動鎖定邏輯,處理了各種邊界情況和兼容性問題。

  • 實現(xiàn) (以 body-scroll-lock 為例):

    npm install body-scroll-lock
    
    <template>
      <div v-if="showModal" ref="modal" class="modal">
        <div class="modal-content">
           </div>
      </div>
    </template>
    
    <script>
    import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';
    
    export default {
      data() {
        return {
          showModal: false,
        };
      },
      watch: {
        showModal(newValue) {
          if (newValue) {
            disableBodyScroll(this.$refs.modal);
          } else {
            enableBodyScroll(this.$refs.modal);
          }
        },
      },
      beforeDestroy() {
        clearAllBodyScrollLocks(); // 清除所有鎖定
      },
    };
    </script>
    
  • 優(yōu)點:

    • 完善的解決方案: 處理了各種細節(jié)和兼容性問題。
    • 易于使用: API 簡單明了。
  • 缺點: 需要引入額外的庫,增加項目體積。

  • 適用場景: 對滾動鎖定有較高要求,需要處理各種復雜情況,且不介意引入第三方庫的項目。

5. 使用overscroll-behavior (CSS 屬性,較新)

***原理**: `overscroll-behavior` CSS 屬性控制當滾動到達元素邊界時發(fā)生的情況。  它可以防止?jié)L動鏈(即滾動穿透)。
* **實現(xiàn)**:
    ```css
    .modal-content {
       overscroll-behavior: contain; /* 或 overscroll-behavior-y: contain; */
       /* 其他樣式 */
    }
    ```

* **優(yōu)點**:
    * **原生 CSS 解決方案**: 無需 JavaScript。
    * **性能好**: 瀏覽器原生支持,性能通常優(yōu)于 JavaScript 解決方案。
* **缺點**:
    * **兼容性**: 比較新的屬性,一些舊瀏覽器可能不支持(需要檢查 Can I Use:[https://caniuse.com/?search=overscroll-behavior](https://caniuse.com/?search=overscroll-behavior))。 可以考慮回退方案。
* **適用場景**:  如果項目對瀏覽器兼容性要求不高,`overscroll-behavior` 是一個非常優(yōu)雅的解決方案。

總結(jié)和選擇建議:

  • 簡單場景,不需保留滾動位置: overflow: hidden;
  • 模態(tài)框內(nèi)只有一個滾動區(qū)域,且不需要鍵盤/滾動條滾動: 阻止事件冒泡
  • 大多數(shù)情況,需要保留滾動位置: position: fixed;
  • 需要處理復雜情況,不介意引入庫: body-scroll-lock
  • 瀏覽器兼容性允許: overscroll-behavior (首選,最優(yōu)雅)

最佳實踐是根據(jù)項目的具體需求和目標瀏覽器來選擇最合適的方法。通常,position: fixed; 或 body-scroll-lock 是比較穩(wěn)妥的選擇。如果對兼容性要求不高,強烈推薦 overscroll-behavior。 記得在開發(fā)過程中進行充分的測試,確保在各種設(shè)備和瀏覽器上都能正常工作。

總結(jié)

到此這篇關(guān)于前端如何解決滾動穿透問題的文章就介紹到這了,更多相關(guān)前端滾動穿透問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JS仿Base.js實現(xiàn)的繼承示例

    JS仿Base.js實現(xiàn)的繼承示例

    這篇文章主要介紹了JS仿Base.js實現(xiàn)的繼承,結(jié)合具體實例形式分析了javascript擴展操作及面向?qū)ο蟪绦蛟O(shè)計相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • 整理一下常見的IE錯誤

    整理一下常見的IE錯誤

    多年以來,IE一直都是最難于調(diào)試JavaScript 錯誤的瀏覽器。IE給出的錯誤消息一般很短又語焉不詳。而且上下文信息也很少,有時甚至一點都沒有。下面幾小節(jié)將分別探討一些在IE中難于調(diào)試的JavaScript 錯誤
    2016-11-11
  • javascript?Echart可視化學習

    javascript?Echart可視化學習

    這篇文章主要為大家介紹了Echart可視化學習的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 手動實現(xiàn)js短信驗證碼輸入框

    手動實現(xiàn)js短信驗證碼輸入框

    本文記錄一下自己手動實現(xiàn)的一個前端常見的短信驗證碼輸入組件,從需求到實現(xiàn)逐步優(yōu)化的過程。具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Knockout結(jié)合Bootstrap創(chuàng)建動態(tài)UI實現(xiàn)產(chǎn)品列表管理

    Knockout結(jié)合Bootstrap創(chuàng)建動態(tài)UI實現(xiàn)產(chǎn)品列表管理

    這篇文章主要為大家詳細介紹了Knockout結(jié)合Bootstrap創(chuàng)建動態(tài)UI實現(xiàn)產(chǎn)品列表管理,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 微信小程序 數(shù)據(jù)緩存實現(xiàn)方法詳解

    微信小程序 數(shù)據(jù)緩存實現(xiàn)方法詳解

    這篇文章主要介紹了微信小程序 數(shù)據(jù)緩存實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • 使用原生js封裝的ajax實例(兼容jsonp)

    使用原生js封裝的ajax實例(兼容jsonp)

    下面小編就為大家?guī)硪黄褂迷鷍s封裝的ajax實例(兼容jsonp)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • js繪制圓形和矩形的方法

    js繪制圓形和矩形的方法

    這篇文章主要介紹了js繪制圓形和矩形的方法,涉及javascript鼠標事件及頁面元素樣式的相關(guān)操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • JS文件上傳時如何使用MD5加密

    JS文件上傳時如何使用MD5加密

    這篇文章主要介紹了JS文件上傳時如何使用MD5加密,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • JavaScript SHA-256加密算法詳細代碼

    JavaScript SHA-256加密算法詳細代碼

    這篇文章主要為大家詳細介紹了JavaScript SHA-256加密算法代碼,具有一定的參考價值,感興趣的朋友可以參考一下
    2016-10-10

最新評論

兴文县| 嵊州市| 五大连池市| 临沂市| 长宁区| 通许县| 进贤县| 寻甸| 象州县| 永福县| 贡嘎县| 茶陵县| 荔波县| 南皮县| 唐河县| 威远县| 红安县| 洪洞县| 呼图壁县| 乌鲁木齐市| 花垣县| 承德市| 宝丰县| 定襄县| 通许县| 五家渠市| 盐边县| 丽江市| 江达县| 远安县| 伊吾县| 双柏县| 安远县| 景德镇市| 丰原市| 安西县| 沂南县| 彭州市| 天柱县| 北辰区| 民乐县|