1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      怎么在Vue中實現(xiàn)一個吸頂錨點組件

      這篇文章將為大家詳細講解有關(guān)怎么在 Vue中實現(xiàn)一個吸頂錨點組件,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

      創(chuàng)新互聯(lián)公司一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個客戶多一個朋友!為您提供網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計、成都網(wǎng)頁設(shè)計、重慶小程序開發(fā)、成都網(wǎng)站開發(fā)、成都網(wǎng)站制作、成都軟件開發(fā)、App定制開發(fā)是成都本地專業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計公司,等你一起來見證!

      拆分功能點

      現(xiàn)在我們已經(jīng)明確需求了,接下來我們總結(jié)一下這個需求有哪些功能點:

      • 按鈕組要有吸頂效果

      • 點擊按鈕要有錨點定位功能

      • 滾動內(nèi)容區(qū)需要找到對應(yīng)的按鈕并高亮

      吸頂組件

      要做一個吸頂效果最簡單的方式是將 css 的 position 屬性設(shè)置為 sticky, 這樣就實現(xiàn)粘性布局。

      .sticky-container {
       position: sticky;
       top: 0px;
      }

      上面的示例僅僅用了兩行 css 的代碼就實現(xiàn)了粘性布局,但由于 IE 瀏覽器完全不支持粘性布局,而我的項目又需要支持一部分的 IE 瀏覽器,所以就需要手動去實現(xiàn)這樣一個功能。

      MDN 官方對粘性布局的解釋是這樣的,粘性布局元素默認是相對定位的,當(dāng)粘性元素超出父元素的指定值(如 `top` 、`left` 等),例如上面的示例,當(dāng)元素粘性元素改為固定定位。關(guān)于父級元素 MDN 描述的不是很精確,這里的父級元素指的是父級滾動元素,如果沒有父級滾動元素則將 `body` 元素作為父級元素。

      既然需要自己實現(xiàn)一個吸頂?shù)男Ч伎嫉狡渌撁婵赡芤矔褂玫奈數(shù)墓δ埽詻Q定將其單獨抽離成一個通用組件。首先我們知道粘性布局是對父級滾動元素定位,所以我們要先找到父級滾動元素,這個功能我們可以通過兩種方式實現(xiàn),一種是向上查找,一種是通過 props 傳遞一個唯一標(biāo)識的 css 選擇器。

      我覺得其他項目可能也會遇到這個功能,所以我定義組件 盡量向著開源靠攏,所以我這里同時支持兩種方案。首先我們要實現(xiàn)一個查找父級滾動元素的功能,如何判斷一個元素是滾動元素呢?很簡單判斷其 `overflow` 是否是 `auto` 或者 `scroll`。

      // util.js 文件
      // 判斷一個元素是否是滾動元素
      const scrollList = ['auto', 'scroll']
      
      export function hasScrollElement(el, direction = 'vertical') {
       if (!el) return
       const style = window.getComputedStyle(el)
       if (direction === 'vertical') {
       return scrollList.includes(style.overflowY)
       } else if (direction === 'horizontal') {
       return scrollList.includes(style.overflowX)
       }
      }
      
      // 獲取第一個滾動元素
      export function getFirstScrollElement(el, direction = 'vertical') {
       if (!el) return
       if (hasScrollElement(el, direction)) {
       return el
       } else {
       return getFirstScrollElement(el && el.parentElement, direction)
       }
      }

      這里說下實現(xiàn)吸頂效果所需要的一些基礎(chǔ)知識:

      • fixed 定位是相對于瀏覽器的可視區(qū)進行定位,這意味著即使頁面滾動,它還是會固定在相同的位置

      • offsetTop 是一個只讀的屬性,它返回當(dāng)前元素相對于距離它最近的父級定位元素頂部的距離。

      • scrollTop 屬性可以獲取或設(shè)置一個元素的內(nèi)容垂直滾動的像素值,`scrollTop` 表示這個元素達到父級滾動元素頂部的距離。

      
      
      
      
      
      .cpt-sticky {
       .top-fixed {
       position: fixed;
       width: 100%;
       background: #fff;
       }
      }
      

      就像上面的示例代碼一樣,短短幾十行就實現(xiàn)了一個吸頂組件,不過它實現(xiàn)了吸頂?shù)墓δ埽沁€有一些缺陷。

      1. 在慢速滾動頁面,吸頂組件在固定與非固定的時候有明顯的卡頓現(xiàn)象。

      2. 由于我的需求有一些是需要做錨點定位功能,但是直接用錨點定位會改變路由所以改為了滾動定位(后面會細說)。但是由于吸頂組件在 `fixed` 之后會脫離文檔流,導(dǎo)致定位的元素會有一部分(吸頂組件高度 )被卡在吸頂組件下方。就像下面這張圖的效果,右邊的錨點定位2區(qū)域的標(biāo)題被隱藏了。

      怎么在 Vue中實現(xiàn)一個吸頂錨點組件

      這些問題也很好解決,使用一個和吸頂組件相同大小的占位元素,當(dāng)吸頂組件脫離文檔流之后,占位元素插入吸頂組件原來的 DOM 位置中,然后順便帶上一些小優(yōu)化。由于占位元素需要和組件高度一致,所以必須要保證 `slot` 插槽中的 DOM 元素已經(jīng)被加載完成,另外放在 slot 元素中可能發(fā)生變更,所以我在吸頂狀態(tài)變更之前獲取其高度。

      
      
      
      
      
      .cpt-sticky {
       .top-fixed {
       position: fixed;
       width: 100%;
       background: #fff;
       }
      }
      

      錨點定位

      網(wǎng)頁中經(jīng)常會有用到錨點定位的場景,例如百度知道的目錄,我目前知道有三種方式可以實現(xiàn)這種功能。

      1. 使用 a 標(biāo)簽定位

      2. 使用 js 定位

      使用 a 標(biāo)簽定位

      先說說 a 標(biāo)簽定位,這是一種最常用的定位方式。它有兩種實現(xiàn)方式,一種是通過 herf 屬性鏈接的指定元素的 id。另一種是添加一個 a 標(biāo)簽,再將 href 屬性鏈接到這個 a 標(biāo)簽的 name 屬性。

      按鈕1
      按鈕1
      ...
      視圖1
      視圖2

      這種定位方式很簡單,它支持任意標(biāo)簽定位。不過它也存在一些問題,例如如果滾動區(qū)內(nèi)有固定或絕對定位,會出現(xiàn)遮罩問題,還有瞬間滾動到頂部,交互不是很好,當(dāng)然這些都可以通過 css 解決。但最主要問題是,a 標(biāo)簽定位會改變路由的 hash,如果有相應(yīng)的路由的話會進行路由跳轉(zhuǎn)。

      怎么在 Vue中實現(xiàn)一個吸頂錨點組件 怎么在 Vue中實現(xiàn)一個吸頂錨點組件

      通過 js 模擬錨點定位

      通過 js 去操作元素的 `scrollTop` 等屬性,使其滾動到父級滾動元素指定的位置,就能實現(xiàn)定位效果。這里簡單提一下 `scrollIntoView()` 這個方法,根據(jù)MDN 的描述,`Element.scrollIntoView()` 方法讓當(dāng)前的元素滾動到瀏覽器窗口的可視區(qū)域內(nèi)。`scrollIntoView()` 還支持動畫的選項,通過 `behavior` 設(shè)置,不過遺憾的是它遇到固定定位也會出現(xiàn)遮蓋的問題,所以最終選擇手動去擼碼,不過 `scrollIntoView()` 倒是很適合做回到頂部這種功能。

      首先我們需要讓按鈕和滾動區(qū)內(nèi)容元素建立對應(yīng)關(guān)系,在按鈕的值中放入對應(yīng)的內(nèi)容區(qū)元素的 css 選擇器,根據(jù)點擊按鈕的值找到對應(yīng)的元素。所以計算規(guī)則是這個元素距離滾動區(qū)的高度加上這個元素上邊距的高度(我在內(nèi)容區(qū)加了外邊距,我希望顯示它),減去滾動區(qū)距離可視區(qū)的高度(我的頁面沒有定位,所以 offsetTop 對應(yīng)可視區(qū)),再減去按鈕組件的高度,就可以得出需要滾動的位置。

      
      
      

      錨點與視圖聯(lián)動

      接下來我們來看看最后一個功能,當(dāng)用戶滾動內(nèi)容區(qū)時,高亮距離按鈕組件最近的那個元素所對應(yīng)的按鈕。這個功能我可以看成是目錄導(dǎo)航,當(dāng)我們查看不同內(nèi)容時高亮對應(yīng)的目錄。

      這個功能如何實現(xiàn)呢,我們來分析一下,當(dāng)查看不同內(nèi)容時會滾動屏幕,所以我們要給按鈕的父級滾動元素綁定 `scroll` 事件。判斷當(dāng)前滾動區(qū)距離按鈕最近的元素,我們需要在這個元素上添加與按鈕中的值對應(yīng)的 css 選擇器。當(dāng)內(nèi)容區(qū)發(fā)生滾動時根據(jù)按鈕獲取內(nèi)容區(qū)中所有的元素,然后將滾動區(qū)元素的 `scrollTop` 減去按鈕元素的高度,即得出按鈕下方的滾動高度,然后再遍歷這些元素頭部和尾部是否包含了這個滾動高度,然后找到這個元素對應(yīng)的按鈕。

      上面的結(jié)論已經(jīng)可以完成,但存在一些問題,先說第一個問題導(dǎo)致按鈕導(dǎo)航失效,只導(dǎo)航到下一個按鈕邊結(jié)束。這個問題不一定會所有人都遇到,之所以我會遇到這個問題,是因為我用了 `Element` 的 `Radio` 組件,要高亮的時候變更了 v-model 的值導(dǎo)致。而點擊按鈕時會觸發(fā)滾動,就會和聯(lián)動高亮的事件沖突了,所以用一個 `isScroll` 變量標(biāo)記當(dāng)前是否是錨點定位狀態(tài),定位狀態(tài)不觸發(fā)滾動操作。

      
      
      
      
      
      .cpt-anchor {
       padding-top: 4px;
       .cpt-tab-menus {
       margin: 0;
       .el-radio-button {
        margin-left: 10px;
        .el-radio-button__inner {
        border: none;
        border-radius: 5px 5px 0 0;
        border-bottom: 2px solid #e4e7ed;
        background-color: #f6f6f8;
        font-size: 16px;
      
        &:hover {
         border-bottom: 2px solid #409eff;
        }
        }
      
        &.is-active {
        .el-radio-button__inner {
         color: #fff;
         border: none;
         border-radius: 5px 5px 0 0;
         background-color: #409eff;
         border-bottom: 2px solid #409eff;
         box-shadow: none;
        }
        }
       }
       }
      }
      

      吸頂錨點組件

      最后將上面兩個組件合并到一起就是我們所需要的吸頂錨點組件了。

      
      
      

      使用示例

      
      
      

      Vue的優(yōu)點

      Vue具體輕量級框架、簡單易學(xué)、雙向數(shù)據(jù)綁定、組件化、數(shù)據(jù)和結(jié)構(gòu)的分離、虛擬DOM、運行速度快等優(yōu)勢,Vue中頁面使用的是局部刷新,不用每次跳轉(zhuǎn)頁面都要請求所有數(shù)據(jù)和dom,可以大大提升訪問速度和用戶體驗。

      關(guān)于怎么在 Vue中實現(xiàn)一個吸頂錨點組件就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


      本文名稱:怎么在Vue中實現(xiàn)一個吸頂錨點組件
      瀏覽路徑:http://www.ef60e0e.cn/article/pjjggi.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        永川市| 安康市| 朝阳市| 河津市| 河西区| 勐海县| 平乐县| 桐城市| 海淀区| 封开县| 富锦市| 涞源县| 禄丰县| 巴中市| 象山县| 德钦县| 吉首市| 南召县| 罗田县| 阿鲁科尔沁旗| 凌海市| 嵊州市| 任丘市| 普安县| 临朐县| 左云县| 无棣县| 达孜县| 巧家县| 富源县| 德钦县| 五华县| 遂川县| 增城市| 平乡县| 巴林右旗| 从化市| 社旗县| 德化县| 望江县| 南城县|