<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>

          web頁面彈出遮罩層,通過js或css禁止蒙層底部頁面跟隨滾動

          時間:?2017-12-07閱讀:?4677標簽:?web

          場景概述

          彈窗是一種常見的交互方式,而蒙層是彈窗必不可少的元素,用于隔斷頁面與彈窗區塊,暫時阻斷頁面的交互。但是,在蒙層元素中滑動的時候,滑到內容的盡頭時,再繼續滑動,蒙層底部的頁面會開始滾動,顯然這不是我們想要的效果,因此需要阻止這種行為。

          那么,如何阻止呢?請看以下分析:


          方案分析

          方案一

          • 打開蒙層時,給body添加樣式:
          overflow: hidden;
          height: 100%;

          在某些機型下,你可能還需要給根節點添加樣式:

          overflow: hidden;
          • 關閉蒙層時,移除以上樣式。

          優點:
          簡單方便,只需添加css樣式,沒有復雜的邏輯。

          缺點:
          兼容性不好,適用于pc,移動端就尷尬了。
          部分安卓機型以及safari中,無法無法阻止底部頁面滾動。

          如果需要應用于移動端,那么你可能需要方案二。


          方案二

          就是利用移動端的touch事件,來阻止默認行為(這里可以理解為頁面滾動就是默認行為)。

          // node為蒙層容器dom節點
          node.addEventListener('touchstart', e => {
            e.preventDefault()
          }, false)

          簡單粗暴,滾動時底部頁面也無法動彈了。假如你的蒙層內容不會有滾動條,那么上述方法prefect。

          但是,最怕空氣突然安靜,假如蒙層內容有滾動條的話,那么它再也無法動彈了。因此我們需要寫一些js邏輯來判斷要不要阻止默認行為,復雜程度明顯增加。

          具體思路:判定蒙層內容是否滾動到盡頭,是則阻止默認行為,反之任它橫行。


          Tip:這里我發現了一個小技巧,可以省略不少代碼。在一次滑動中,若蒙層內容可以滾動,則蒙層內容滾動,過程中即使蒙層內容已滾至盡頭,只要不松手(可以理解為
          touchend事件觸發前),繼續滑動時頁面內容不會滾動,此時若松手再繼續滾動,則頁面內容會滾動。利用這一個小技巧,我們可以精簡優化我們的代碼邏輯。

          示例代碼如下:

          <body>
            <div class="page">
              <!-- 這里多添加一些,直至出現滾動條 -->
              <p>頁面</p>
              <p>頁面</p>
              <button class="btn">打開蒙層</button>
              <p>頁面</p>
            </div>
            <div class="container">
              <div class="layer"></div>
              <div class="content">
                <!-- 這里多添加一些,直至出現滾動條 -->
                <p>蒙層</p>
                <p>蒙層</p>
                <p>蒙層</p>
              </div>
            </div>
          </body>
          body {
            margin: 0;
            padding: 20px;
          }
          
          .btn {
            border: none;
            outline: none;
            font-size: inherit;
            border-radius: 4px;
            padding: 1em;
            width: 100%;
            margin: 1em 0;
            color: #fff;
            background-color: #ff5777;
          }
          
          .container {
            position: fixed;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            z-index: 1001;
            display: none;
          }
          
          .layer {
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            z-index: 1;
            background-color: rgba(0, 0, 0, .3);
          }
          
          .content {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            height: 50%;
            z-index: 2;
            background-color: #f6f6f6;
            overflow-y: auto;
          }
          const btnNode = document.querySelector('.btn')
          const containerNode = document.querySelector('.container')
          const layerNode = document.querySelector('.layer')
          const contentNode = document.querySelector('.content')
          let startY = 0 // 記錄開始滑動的坐標,用于判斷滑動方向
          let status = 0 // 0:未開始,1:已開始,2:滑動中
          
          // 打開蒙層
          btnNode.addEventListener('click', () => {
            containerNode.style.display = 'block'
          }, false)
          
          // 蒙層部分始終阻止默認行為
          layerNode.addEventListener('touchstart', e => {
            e.preventDefault()
          }, false)
          
          // 核心部分
          contentNode.addEventListener('touchstart', e => {
            status = 1
            startY = e.targetTouches[0].pageY
          }, false)
          
          contentNode.addEventListener('touchmove', e => {
            // 判定一次就夠了
            if (status !== 1) return
          
            status = 2
          
            let t = e.target || e.srcElement
            let py = e.targetTouches[0].pageY
            let ch = t.clientHeight // 內容可視高度
            let sh = t.scrollHeight // 內容滾動高度
            let st = t.scrollTop // 當前滾動高度
          
            // 已經到頭部盡頭了還要向上滑動,阻止它
            if (st === 0 && startY < py) {
              e.preventDefault()
            }
          
            // 已經到低部盡頭了還要向下滑動,阻止它
            if ((st === sh - ch) && startY > py) {
              e.preventDefault()
            }
          }, false)
          
          contentNode.addEventListener('touchend', e => {
            status = 0
          }, false)

          問題雖然是解決了,但是回頭來看,復雜程度和代碼量明顯增加了一個梯度。
          本著簡單方便的原則,我們是不是還可以探索其他的方案呢?

          既然touch事件判定比較復雜,何不跳出這個框框,另辟蹊徑,探索更加合適的方案。
          于是,便有了我們的方案三。


          方案三

          來講講我的思路,既然我們要阻止頁面滾動,那么何不將其固定在視窗(即position: fixed),這樣它就無法滾動了,當蒙層關閉時再釋放。

          當然還有一些細節要考慮,將頁面固定視窗后,內容會回頭最頂端,這里我們需要記錄一下,同步top值。

          示例代碼:

          let bodyEl = document.body
          let top = 0
          
          function stopBodyScroll (isFixed) {
            if (isFixed) {
              top = window.scrollY
          
              bodyEl.style.position = 'fixed'
              bodyEl.style.top = -top + 'px'
            } else {
              bodyEl.style.position = ''
              bodyEl.style.top = ''
          
              window.scrollTo(0, top) // 回到原先的top
            }
          }

          思考總結

          • 若應用場景是pc,推薦方案一,真的是不要太方便
          • 若應用場景是h5,你可以采用方案二,但是我建議你采用方案三
          • 若應用場景是全平臺,那么方案三你不容錯過

          本文到這里也即將結束了,在這里我強烈推薦一下方案三,原因在于簡單、方便、兼容性好,一次封裝,永久受用。

          來源:https://segmentfault.com/a/1190000012313337
          站長推薦

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

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

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

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

          WebAR 如何改變增強現實的未來

          增強現實技術在開發人員和智能手機用戶中越來越受歡迎,但它還是沒有在無所不在的技術中占據一席之地。要體驗 AR,用戶必須安裝專用的程序,但經常會在用過幾次后就將其刪除,甚至根本去下載它

          Web服務常用的幾種開發方法

          Web服務,即通過程序實現網頁服務,服務啟動后,一般用戶可通過訪問URL獲取到網站提供的網頁服務,如網頁瀏覽、留言、商品購買等。開發Web服務的技術有很多,有Java、Python、ASP.NET、腳本語言等

          5 張圖描繪Web3 堆棧全景

          Web3 堆棧最令人難以置信的一點是,它們不需要任何集中協調就可以組合在一起。開發本身是去中心化的。沒有主架構師。這與地球上幾乎所有其他的開發堆棧項目形成了鮮明的對比。在 Linux 基金會,少數人設定整個 Linux 的方向

          web開發新手應該知曉的20件事

          在我當初剛從事 web 開發的時候,有很多重要的事我并沒有事先了解。現在看來,我的很多期望都和現實有很大的差距。在這篇文章里,我會告訴你 20 件事情,這些都是在你準備開始或者剛開始 web 開發不久的時候就應該知曉的

          Web前端開發的應用和前景:web 1.0到web 3.0

          web3.0時代,前端做著前端的工作,盡自己可能去在多端的世界去為用戶體驗努力,后端去做著后端的工作,去更好的處理數據,利用人工智能?利用爬蟲?將數據充分的使用,為用戶分析數據,給予用戶最想要的數據。

          函數式 UI:Web開發終于擺脫了框架的束縛

          用戶界面都是響應式系統,因此可以使用一個純響應函數,將用戶界面接受的事件映射到接口系統上的動作來定義用戶界面。利用函數式編程的實現技術可以讓實現更接近規范,更易推理和測試。函數式 UI 可以讓開發人員擺脫不兼容的 UI 和測試框架帶來的麻煩

          W3C是什么?IETF是什么?

          無規矩不成方圓,軟件開發當然不能例外。Web開發涉及的廠商和技術非常多,所以必須要有參考的標準,而且需要一系列的標準。Web程序都是通過瀏覽器來解析執行的,通過頁面的展示內容與用戶互動,所以Web標準不僅要求各個瀏覽器都要遵循

          如何遷移Flutter項目到Flutter Web?

          這篇簡單介紹下怎么將一個現有的 Flutter 項目轉成 Flutter Web 項目。開始之前先澆一盆冷水,我們理想中的一套代碼、多端運行的愿望是要破滅了,至少目前版本的 Flutter Web SDK 是沒法做到的

          Gavin Wood:創造一個web3.0的加密世界

          我最早是以太坊的聯合創始人,也是CTO,黃皮書的作者。當開啟以太坊時,我們是局外人,關注的焦點更多的是BTC。當時,人們將投身以太坊視為浪費時間和精力。但現在以太坊已經成長起來,進入了完整循環。但與此同時

          web頁面的回流和重繪

          什么是回流? 回流也叫重排(reflow),當頁面中的元素發生影響布局的變化,比如:改變寬高,修改顯示影藏。頁面需要重新布局,就會觸發重排。 簡單的說就是,頁面布局改變,就會觸發重排。

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

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

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

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