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

vue實(shí)現(xiàn)吸頂、錨點(diǎn)和滾動(dòng)高亮按鈕效果

 更新時(shí)間:2019年10月21日 08:21:49   作者:lemonChen  
這篇文章主要介紹了vue實(shí)現(xiàn)一個(gè)簡(jiǎn)單的吸頂、錨點(diǎn)和滾動(dòng)高亮按鈕效果,需要的朋友可以參考下

因公司后臺(tái)管理系統(tǒng)很多功能技術(shù)老舊,最近在用vue重構(gòu)公司的后臺(tái)管理系統(tǒng),在做商品管理添加商品這一塊,借鑒淘寶的添加商品的交互,需要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的吸頂、錨點(diǎn)和滾動(dòng)高亮按鈕的效果。

需求

  1. 滾動(dòng)頁(yè)面到頂部,實(shí)現(xiàn)某元素固定到頂部效果
  2. 點(diǎn)擊某個(gè)按鈕,頁(yè)面滾動(dòng)到相應(yīng)的位置
  3. 滾動(dòng)頁(yè)面,當(dāng)?shù)竭_(dá)某個(gè)位置時(shí),高亮對(duì)應(yīng)的相關(guān)按鈕

元素吸頂實(shí)現(xiàn)方式

關(guān)于元素吸頂效果,通過查閱相關(guān)資料和相關(guān)測(cè)試,有三種方式(還有一種是jquery的方法,這里就不介紹了)

一、使用position:sticky

1. 什么是position:sticky?

粘性定位元素相當(dāng)于position:relative和position:sticky的結(jié)合體,受限于父級(jí)元素,在不同的條件下呈現(xiàn)出不同的頁(yè)面效果

2. 如何使用sticky?

sticky元素效果完全受限于父級(jí)元素,使用條件:

1.sticky元素的父元素的overflow只能設(shè)置為visible,否則會(huì)導(dǎo)致沒有粘滯效果

2.sticky元素的父元素不能設(shè)置固定的高度,否則會(huì)導(dǎo)致沒有粘滯效果

3.sticky滿足條件變成fixed定位時(shí),與標(biāo)準(zhǔn)fixed元素不一樣,不會(huì)脫離文檔流

4.sticky 定位的元素不能添加一個(gè)只包含自身的父元素,會(huì)導(dǎo)致沒有粘滯效果

5.同一個(gè)父級(jí)元素中的sticky元素,如果定位值相等,則會(huì)重疊,如果屬于不同父級(jí)元素中,則會(huì)擠掉之前的元素,形成依次占位的效果 具體實(shí)現(xiàn)效果如下:

.sticky-box{ 
 position: sticky; 
 position: -webkit-sticky;
 top: 60px; //可通過js動(dòng)態(tài)設(shè)置
}

3.兼容性

通過查看can i use 可以看到相關(guān)的兼容性:


可以看出這個(gè)屬性的兼容性不是那么好,如果項(xiàng)目需要兼容到ie11等的話,就不是那么適用了

二、使用offsetTop**

HTMLElement.offsetTop 為只讀屬性,它返回當(dāng)前元素相對(duì)于其 offsetParent 元素的頂部?jī)?nèi)邊距的距離。因此我們需要注意的是,在監(jiān)聽頁(yè)面滾動(dòng)的過程中,需要將定位父級(jí)元素的偏移量也計(jì)算在內(nèi),可以如下寫法:

//獲取當(dāng)前元素的offsetTop
  getOffsetTop(obj) {
   let offsetTop = 0;
   while (obj != window.document.body && obj != null) {
    offsetTop += obj.offsetTop;
    obj = obj.offsetParent;
   }
   return offsetTop;
  }

通過在vue的mounted生命周期函數(shù)中添加監(jiān)聽事件滾動(dòng)的事件:

mounted() {
  /**通過給變成固定定位的元素添加一個(gè)同等高度的父元素,防止該元素變成固定定位時(shí),脫離文檔流導(dǎo)致的頁(yè)面抖動(dòng) */
  this.tabsHeight = this.$refs.elTabs.offsetHeight;
  window.addEventListener("scroll", this.handleScroll);
 },
 destroyed() {
  //離開該頁(yè)面需要移除這個(gè)監(jiān)聽的事件
  window.removeEventListener("scroll", this.handleScroll);
 },
  methods: {
  /**滾動(dòng)事件 */
  handleScroll() {
    //獲取頁(yè)面滾動(dòng)條的高度
    let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
    let offsetTop = this.getOffsetTop(this.$refs.elTabs);
    this.isFixed = scrollTop > offsetTop;
  }
 }

同時(shí)如果這種吸頂方式在項(xiàng)目中會(huì)多次用到,就可以封裝成組件的形式

三、使用getBoundingClientRect().top**

還有一種更為直接的方式,可以實(shí)現(xiàn)吸頂效果,就是使用getBoundingClientRect().top來獲取元素相對(duì)于視口(瀏覽器窗口)的位置,相對(duì)于offsetTop,該方法不用考慮到吸頂元素的父級(jí)元素和頁(yè)面滾動(dòng)條的高度,直接對(duì)該元素進(jìn)行處理即可,實(shí)現(xiàn)如下: /* 滾動(dòng)事件 / handleScroll() { / * getBoundingClientRect().top 獲取某元素距離瀏覽器頂部的高度,不包含滾動(dòng)的距離 */ let tabOffsetTop = this.$refs.stickyBox.getBoundingClientRect().top; this.isFixed = tabOffsetTop < this.offsetTop }

/**滾動(dòng)事件 */
  handleScroll() {
   /**
    * getBoundingClientRect().top 獲取某元素距離瀏覽器頂部的高度,不包含滾動(dòng)的距離
    this.offsetTop 表示的是吸頂元素距離頂部的條件值(一般項(xiàng)目需求是0)
    */
   let tabOffsetTop = this.$refs.stickyBox.getBoundingClientRect().top;
   this.isFixed = tabOffsetTop < this.offsetTop
  }

錨點(diǎn)定位

點(diǎn)擊相應(yīng)的按鈕,頁(yè)面滾動(dòng)到相應(yīng)的位置,目前我知道實(shí)現(xiàn)該功能的方式有兩種:

1. 使用a標(biāo)簽定位 2. 使用js模擬錨點(diǎn)定位

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

這是一種常見的定位方式,它有兩種實(shí)現(xiàn)方式:

1. 通過href屬性鏈接到指定元素的id

2.另一種是添加一個(gè) a 標(biāo)簽,再將 href 屬性鏈接到這個(gè) a 標(biāo)簽的 name 屬性

<a href="#view1">按鈕1</a> 
 <a href="#view2">按鈕1</a> 
 <div id="view1">視圖1</div> 
 <div><a name="view2">視圖2</a></div> 

這種定位方式很簡(jiǎn)單,支持任意標(biāo)簽的定位,但是a標(biāo)簽的定位會(huì)改變路由的hash,如果有相關(guān)路由會(huì)進(jìn)行路由跳轉(zhuǎn)

使用js模擬錨點(diǎn)定位

通過js獲取元素的scrollTop值,使其滾動(dòng)到指定的位置,就能實(shí)現(xiàn)錨點(diǎn)定位效果,這里的tab切換選項(xiàng),用到是的element-ui的el-tabs組件,具體實(shí)現(xiàn)如下:

<!-- html -->
 <el-tabs v-model="activeName" type="card" @tab-click="tabClick">
  <el-tab-pane :label="item.name" :name="item.key" v-for="item in tabList" :key="item.key"></el-tab-pane>
</el-tabs>
<!-- js -->
methods:{
 //獲取當(dāng)前元素的offsetTop
 getOffsetTop(obj) {
  let offsetTop = 0;
  while (obj != window.document.body && obj != null) {
  offsetTop += obj.offsetTop;
  obj = obj.offsetParent;
 }
  return offsetTop;
 },
 <!--錨點(diǎn)點(diǎn)擊事件-->
 <!--fixedHeight 滾動(dòng)的位置上方固定的高度-->
 tabClick(e) {
  let _this = this;
  //獲取當(dāng)前選中的index以便后面滾動(dòng)高亮
  this.index = parseInt(e.index);
  //給定一個(gè)標(biāo)識(shí),錨點(diǎn)事件不觸發(fā)滾動(dòng)
  this.isScroll = false;
  this.isChange = false;
  //獲取當(dāng)前選中元素的top值(給元素綁定對(duì)應(yīng)的ref值)
  let offsetTop = this.getOffsetTop(this.$refs[this.activeName]);
  let scrollTop = offsetTop - this.fixedHeight;
  window.scrollTo({
    top: scrollTop
  });
}

不得不提的一個(gè)方法就是scrollIntoView,Element.scrollIntoView() 方法讓當(dāng)前的元素滾動(dòng)到瀏覽器窗口的可視區(qū)域內(nèi),同時(shí)還支持動(dòng)態(tài)效果,但是不支持配置滾動(dòng)到距離頂部的距離,會(huì)出現(xiàn)遮罩現(xiàn)象,但是很適合做會(huì)到頂部的功能

滾動(dòng)高亮按鈕

當(dāng)用戶滾動(dòng)內(nèi)容區(qū)時(shí),高亮距離按鈕組件最近的那個(gè)元素所對(duì)應(yīng)的按鈕。 通過監(jiān)聽滾動(dòng)事件,獲取當(dāng)前選中的tab的offsetTop值和當(dāng)前頁(yè)面的scrollTop值,判斷向上或者向下滾動(dòng),做出不同的處理,具體如下:

//頁(yè)面滾動(dòng)要做的事情
handleScroll() {
  let scrollTop =
    window.pageYOffset ||
    document.documentElement.scrollTop ||
    document.body.scrollTop;
   this.scrollTop = scrollTop;
   <!--isScroll 用于避免錨點(diǎn)事件觸發(fā)頁(yè)面滾動(dòng)-->
   if (!this.isScroll) return;
   /**
    * scrollTop 頁(yè)面的滾動(dòng)條的高度
    * offsetTop 當(dāng)前選中的tab元素的offsetTop
    * offsetHeight 當(dāng)前選中元素的高度
    */
   let offsetTop = this.getOffsetTop(this.$refs[this.activeName]);
   let offsetHeight = this.$refs[this.activeName].offsetHeight;
   let actuaTop = scrollTop + this.fixedHeight;
   let length = this.tabList.length;
   /**
    * 頁(yè)面滾動(dòng)中根據(jù)相應(yīng)位置變換選中tab
    */
   if (actuaTop < offsetTop && this.index > 0) {
    this.index = this.index - 1;
    this.activeName = this.tabList[this.index].key;
   } else if (this.index < length && actuaTop > offsetTop + offsetHeight) {
    this.index = this.index + 1;
    this.activeName = this.tabList[this.index].key;
 }
}

性能優(yōu)化

頁(yè)面中讀取屬性會(huì)導(dǎo)致頁(yè)面reflow(下次會(huì)對(duì)導(dǎo)致頁(yè)面reflow和repaint 的操作做一個(gè)總結(jié)),過度的reflow會(huì)導(dǎo)致頁(yè)面性能下降,所以我們應(yīng)該盡量減少reflow的次數(shù),以便給用戶更好的體驗(yàn)。 如果產(chǎn)品可以接受效果有延遲,就可以使用節(jié)流函數(shù)控制在一定時(shí)間內(nèi)只執(zhí)行一次函數(shù)(節(jié)流函數(shù)可以使用lodash.js 封裝好的 throttle 方法)

總結(jié)

寫到這里,需求中的三個(gè)功能都已經(jīng)實(shí)現(xiàn),也許還存在更好的方案,但是通過這次實(shí)現(xiàn)這三個(gè)需求,如果大家有其他更好的方法,歡迎留言補(bǔ)充,但我也從中學(xué)習(xí)到了一些東西 1.position:sticky的用法和使用條件

2.scrollTop、offsetTop等元素的相關(guān)屬性、getBoundingClientRect()用法和 scrollTo、scrollIntoView的用法 3.錨點(diǎn)時(shí)間和滾動(dòng)高亮事件導(dǎo)致的沖突處理等

以上所述是小編給大家介紹的vue實(shí)現(xiàn)吸頂、錨點(diǎn)和滾動(dòng)高亮按鈕效果,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • 一文秒懂Vue3的v-model

    一文秒懂Vue3的v-model

    v-model 是 Vue 內(nèi)置的指令作為屬性接收一個(gè)變量(不能是常量)綁定到普通組件和自定義組件中,本文給大家介紹Vue3的v-model示例代碼,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • vue 彈框產(chǎn)生的滾動(dòng)穿透問題的解決

    vue 彈框產(chǎn)生的滾動(dòng)穿透問題的解決

    這篇文章主要介紹了vue 彈框產(chǎn)生的滾動(dòng)穿透問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue中watch如何同時(shí)監(jiān)聽多個(gè)屬性

    vue中watch如何同時(shí)監(jiān)聽多個(gè)屬性

    這篇文章主要介紹了vue中watch如何同時(shí)監(jiān)聽多個(gè)屬性,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 基于vue實(shí)現(xiàn)頁(yè)面滾動(dòng)加載的示例詳解

    基于vue實(shí)現(xiàn)頁(yè)面滾動(dòng)加載的示例詳解

    頁(yè)面內(nèi)容太多會(huì)導(dǎo)致加載速度過慢,這時(shí)可考慮使用滾動(dòng)加載即還沒有出現(xiàn)在可視范圍內(nèi)的內(nèi)容塊先不加載,出現(xiàn)后再加載,所以本文給大家介紹了基于vue實(shí)現(xiàn)頁(yè)面滾動(dòng)加載的示例,需要的朋友可以參考下
    2024-01-01
  • vue在install時(shí)node-sass@4.14.1?postinstall:node?scripts/build.js錯(cuò)誤解決

    vue在install時(shí)node-sass@4.14.1?postinstall:node?scripts/buil

    最近在npm install 的時(shí)候遇到了個(gè)問題,所以給大家總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于vue在install時(shí)node-sass@4.14.1?postinstall:node?scripts/build.js錯(cuò)誤的解決方法,需要的朋友可以參考下
    2023-05-05
  • vue實(shí)現(xiàn)拍照或錄像的示例代碼

    vue實(shí)現(xiàn)拍照或錄像的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用vue實(shí)現(xiàn)拍照或錄像的功能,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • Vue中的計(jì)算屬性與監(jiān)聽屬性

    Vue中的計(jì)算屬性與監(jiān)聽屬性

    這篇文章介紹了Vue中的計(jì)算屬性與監(jiān)聽屬性,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • vue中的 $slot 獲取插槽的節(jié)點(diǎn)實(shí)例

    vue中的 $slot 獲取插槽的節(jié)點(diǎn)實(shí)例

    今天小編就為大家分享一篇vue中的 $slot 獲取插槽的節(jié)點(diǎn)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 詳解Vue+elementUI build打包部署后字體圖標(biāo)丟失問題

    詳解Vue+elementUI build打包部署后字體圖標(biāo)丟失問題

    這篇文章主要介紹了詳解Vue+elementUI build打包部署后字體圖標(biāo)丟失問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • vue實(shí)現(xiàn)全屏滾動(dòng)效果(非fullpage.js)

    vue實(shí)現(xiàn)全屏滾動(dòng)效果(非fullpage.js)

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)全屏滾動(dòng)效果,非fullpage.js,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03

最新評(píng)論

肥东县| 封开县| 巴彦淖尔市| 栖霞市| 定州市| 青川县| 绿春县| 界首市| 海淀区| 隆化县| 黑龙江省| 高邑县| 葫芦岛市| 大荔县| 且末县| 扶风县| 安远县| 岳阳市| 巴马| 民县| 界首市| 惠州市| 台南县| 监利县| 平南县| 育儿| 如东县| 新津县| 溧阳市| 廉江市| 迭部县| 彰化市| 梅河口市| 永嘉县| 遂昌县| 株洲县| 科尔| 河东区| 天镇县| 泽普县| 曲阳县|