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

JavaScript 實(shí)現(xiàn)頁面滾動(dòng)動(dòng)畫

 更新時(shí)間:2021年04月24日 15:07:11   作者:前端小蜜蜂  
這篇文章主要介紹了JavaScript 實(shí)現(xiàn)頁面滾動(dòng)動(dòng)畫的方法,幫助大家更好的理解和學(xué)習(xí)使用JavaScript,感興趣的朋友可以了解下

在做前端 UI 效果時(shí),讓元素根據(jù)滾動(dòng)位置實(shí)現(xiàn)動(dòng)畫效果是一個(gè)非常流行的設(shè)計(jì),通常我們會(huì)使用第三方插件或庫來實(shí)現(xiàn)。在本教程中,我將教大家使用純 JavaScript 和 CSS 來實(shí)現(xiàn)。

先預(yù)覽一下實(shí)現(xiàn)的效果:

我們使用 CSS 來實(shí)現(xiàn)動(dòng)畫,用 JavaScript 來處理觸發(fā)所需的樣式。我們先來創(chuàng)建布局。

創(chuàng)建布局

我們先使用 HTML 創(chuàng)建頁面布局,然后為需要實(shí)現(xiàn)動(dòng)畫的元素分配一個(gè)通用類名,后面的 JavaScript 通過此類名定位這些元素。這里我們給需要根據(jù)滾動(dòng)實(shí)現(xiàn)動(dòng)畫的元素指定為類名 js-scroll,HTML 代碼如下:

<section class="scroll-container">
  <div class="scroll-element js-scroll"></div>
  <div class="scroll-caption">This animation fades in from the top.</div>
</section>

添加 CSS 樣式

先來一個(gè)簡單的淡入動(dòng)畫效果:

.js-scroll {
  opacity: 0;
  transition: opacity 500ms;
}

.js-scroll.scrolled {
  opacity: 1;
}

頁面上的所有 js-scroll 元素都會(huì)被隱藏,不透明度為 0。當(dāng)滾動(dòng)到該元素區(qū)域時(shí),給它加上 .scrolled 類名讓它顯現(xiàn)出來。

用 JavaScript 操作元素

有了布局和樣式,現(xiàn)在我們需要編寫一個(gè) JavaScript 函數(shù),當(dāng)元素滾動(dòng)到視圖中時(shí),為它們分配類名。

我們來簡單分解一下邏輯:

  1. 獲取頁面上所有 js-scroll 元素
  2. 使這些元素默認(rèn)淡出不可見
  3. 檢測元素是否在視窗內(nèi)
  4. 如果元素在視窗內(nèi)則分配 scrolled 類名

獲取目標(biāo)元素

獲取頁面上所有 js-scroll 元素,使用 document.querySelectorAll() 即可:

const scrollElements = document.querySelectorAll('.js-scroll')

默認(rèn)淡出所有目標(biāo)元素

遍歷這些元素,使其全部淡出不可見:

scrollElements.forEach((el) => {
  el.style.opacity = 0
})

檢測元素是否在視窗內(nèi)

我們可以通過判斷元素距離頁面頂部的間距是否小于頁面可見部分的高度,來檢測元素是否在用戶視窗中。

在 JavaScript 中,我們使用 getBoundingClientRect().top 方法來獲取元素與頁面頂部的距離,使用 window.innerHeight document.documentElement.clientHeight 來獲取視窗的高度。

我們將使用上述邏輯創(chuàng)建一個(gè) elementInView 函數(shù):

const elementInView = (el) => {
  const elementTop = el.getBoundingClientRect().top

  return (
    elementTop <= (window.innerHeight || document.documentElement.clientHeight)
  )
}

我們可以修改這個(gè)函數(shù)來檢測元素是否向頁面滾動(dòng)了 x 個(gè)像素,或者檢測頁面滾動(dòng)的百分比。

const elementInView = (el, scrollOffset = 0) => {
  const elementTop = el.getBoundingClientRect().top

  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) - scrollOffset
  )
}

在這種情況下,如果元素已經(jīng)按 scrollOffset 的數(shù)量滾動(dòng)到頁面中,該函數(shù)返回 true。我們?cè)偕宰餍薷模褏?shù) scrollOffset 變成百分比:

const elementInView = (el, percentageScroll = 100) => {
  const elementTop = el.getBoundingClientRect().top

  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) *
      (percentageScroll / 100)
  )
}

這部分可以根據(jù)自己的特定需求來定義邏輯。

注意:可以使用 Intersection Observer API[2] 來實(shí)現(xiàn)同樣的效果,但它不支持 IE。

給元素添加類名

現(xiàn)在我們已經(jīng)能夠檢測到元素是否已經(jīng)滾動(dòng)到頁面中,我們需要定義一個(gè)函數(shù)來處理該元素的顯示--本例中我們通過分配 scrolled 類名來顯示該元素。

const displayScrollElement = (element) => {
  element.classList.add('scrolled')
}

然后,再把我們前面的邏輯與 displayScrollElement 函數(shù)結(jié)合起來,并使用 forEach 方法在所有 js-scroll 元素上調(diào)用該函數(shù)。

const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 100)) {
      displayScrollElement(el)
    }
  })
}

另外,當(dāng)元素不再在視圖中時(shí),需要將其重置為默認(rèn)狀態(tài),我們可以通過定義一個(gè) hideScrollElement 來實(shí)現(xiàn):

const hideScrollElement = (element) => {
  element.classList.remove("scrolled");
};

const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 100)) {
      displayScrollElement(el);
    } else {
      hideScrollElement(el);
    }
  }

最后,我們將把上面的方法傳遞到窗口的滾動(dòng)事件監(jiān)聽中,這樣每當(dāng)用戶滾動(dòng)時(shí)它就會(huì)運(yùn)行。

window.addEventListener('scroll', () => {
  handleScrollAnimation()
})

我們已經(jīng)實(shí)現(xiàn)了滾動(dòng)動(dòng)畫的所有功能。

完善示例

請(qǐng)大家回到文章開頭看看效果圖??吹?,這些元素以不同的動(dòng)畫出現(xiàn)。這是通過給類名分配不同的 CSS 動(dòng)畫來實(shí)現(xiàn)的。這個(gè)示例的 HTML 是這樣的:

<section class="scroll-container">
  <div class="scroll-element js-scroll fade-in"></div>
  <div class="scroll-caption">淡入動(dòng)效</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll fade-in-bottom"></div>
  <div class="scroll-caption">切入頂部動(dòng)效</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll slide-left"></div>
  <div class="scroll-caption">從左邊切入動(dòng)效</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll slide-right"></div>
  <div class="scroll-caption">從右邊切入動(dòng)效</div>
</section>

這里我們給不同動(dòng)效的元素分配了不同的 CSS 類名,下面是這些類對(duì)應(yīng)的 CSS 代碼:

.scrolled.fade-in {
  animation: fade-in 1s ease-in-out both;
}

.scrolled.fade-in-bottom {
  animation: fade-in-bottom 1s ease-in-out both;
}

.scrolled.slide-left {
  animation: slide-in-left 1s ease-in-out both;
}

.scrolled.slide-right {
  animation: slide-in-right 1s ease-in-out both;
}

@keyframes slide-in-left {
  0% {
    transform: translateX(-100px);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slide-in-right {
  0% {
    transform: translateX(100px);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes fade-in-bottom {
  0% {
    transform: translateY(50px);
    opacity: 0;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

雖然加了不同動(dòng)畫元素,但我們不需要修改 JavaScript 代碼,因?yàn)檫壿嫳3植蛔儭_@意味著我們可以在頁面添加任何數(shù)量的不同動(dòng)畫,而無需編寫新的函數(shù)。

利用節(jié)流閥提高性能

每當(dāng)我們?cè)跐L動(dòng)監(jiān)聽器中綁定一個(gè)函數(shù)時(shí),每次用戶滾動(dòng)頁面,該函數(shù)都會(huì)被調(diào)用。滾動(dòng)一個(gè) 500px 的頁面會(huì)導(dǎo)致一個(gè)函數(shù)被調(diào)用至少 50 次。如果我們?cè)噲D在頁面上包含很多元素,這會(huì)導(dǎo)致我們的頁面速度明顯變慢。

我們可以通過使用“節(jié)流函數(shù)(Throttle Function)”來減少函數(shù)的調(diào)用次數(shù)。節(jié)流函數(shù)是一個(gè)高階函數(shù),它在指定的時(shí)間間隔內(nèi)只調(diào)用傳入的函數(shù)一次。

它對(duì)于滾動(dòng)事件特別有用,因?yàn)槲覀儾恍枰獧z測用戶滾動(dòng)的每個(gè)像素。例如,如果我們有一個(gè)定時(shí)器為 100ms 的節(jié)流函數(shù),那么用戶每滾動(dòng) 100ms,該函數(shù)將只被調(diào)用一次。

節(jié)流函數(shù)在 JavaScript 中可以這樣實(shí)現(xiàn):

let throttleTimer = false

const throttle = (callback, time) => {
  if (throttleTimer) return

  // 這里標(biāo)記一下,以使函數(shù)不會(huì)重復(fù)執(zhí)行
  throttleTimer = true

  setTimeout(() => {
    // 到了指定的時(shí)間,調(diào)用傳入的回調(diào)函數(shù)
    callback()
    throttleTimer = false
  }, time)
}

然后我們可以修改 window 對(duì)象上的 scroll 事件監(jiān)聽:

window.addEventListener('scroll', () => {
  throttle(handleScrollAnimation, 250)
})

現(xiàn)在我們的 handleScrollAnimation 函數(shù)在用戶滾動(dòng)時(shí)每隔 250ms 就會(huì)被調(diào)用一次:

以上就是JavaScript 實(shí)現(xiàn)頁面滾動(dòng)動(dòng)畫的詳細(xì)內(nèi)容,更多關(guān)于JavaScript 頁面滾動(dòng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Javascript中的Callback方法淺析

    Javascript中的Callback方法淺析

    這篇文章主要介紹了Javascript中的Callback方法淺析,本文講解了什么是callback、Javscript Callback、Callback是什么、Callback實(shí)例等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • js判斷undefined變量類型使用typeof

    js判斷undefined變量類型使用typeof

    js判斷undefined變量類型使用typeof可以輕松實(shí)現(xiàn),不了解的朋友可以參考下哈,希望對(duì)你有所幫助
    2013-06-06
  • JS實(shí)現(xiàn)圖片拖拽交換效果

    JS實(shí)現(xiàn)圖片拖拽交換效果

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)圖片拖拽交換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 使用JavaScript和MQTT開發(fā)物聯(lián)網(wǎng)應(yīng)用示例解析

    使用JavaScript和MQTT開發(fā)物聯(lián)網(wǎng)應(yīng)用示例解析

    這篇文章主要介紹了使用JavaScript和MQTT開發(fā)物聯(lián)網(wǎng)應(yīng)用示例解析,文章通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 微信小程序教程系列之設(shè)置標(biāo)題欄和導(dǎo)航欄(7)

    微信小程序教程系列之設(shè)置標(biāo)題欄和導(dǎo)航欄(7)

    這篇文章主要為大家詳細(xì)介紹了微信小程序教程系列之標(biāo)題欄和導(dǎo)航欄的設(shè)置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 探究Javascript模板引擎mustache.js使用方法

    探究Javascript模板引擎mustache.js使用方法

    這篇文章主要為大家介紹了Javascript模板引擎mustache.js使用方法,mustache.js是一個(gè)簡單強(qiáng)大的Javascript模板引擎,使用它可以簡化在js代碼中的html編寫,壓縮后只有9KB,非常值得在項(xiàng)目中使用,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 微信小程序?qū)崿F(xiàn)手指觸摸畫板

    微信小程序?qū)崿F(xiàn)手指觸摸畫板

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)手指觸摸畫板,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • swiperjs實(shí)現(xiàn)導(dǎo)航與tab頁的聯(lián)動(dòng)

    swiperjs實(shí)現(xiàn)導(dǎo)航與tab頁的聯(lián)動(dòng)

    這篇文章主要為大家詳細(xì)介紹了swiperjs實(shí)現(xiàn)導(dǎo)航與tab頁的聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 用JavaScript對(duì)JSON進(jìn)行模式匹配 (Part 2 - 實(shí)現(xiàn))

    用JavaScript對(duì)JSON進(jìn)行模式匹配 (Part 2 - 實(shí)現(xiàn))

    在上一篇文章里,我們完成了 Dispatcher 類的接口設(shè)計(jì),現(xiàn)在我們就來考慮一下如何實(shí)現(xiàn)這個(gè)類。
    2010-07-07
  • 詳解Webpack + ES6 最新環(huán)境搭建與配置

    詳解Webpack + ES6 最新環(huán)境搭建與配置

    這篇文章主要介紹了詳解Webpack + ES6 最新環(huán)境搭建與配置,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06

最新評(píng)論

柳州市| 高要市| 永胜县| 长沙县| 诸城市| 龙里县| 铅山县| 额敏县| 西乡县| 福建省| 义马市| 安多县| 时尚| 越西县| 炎陵县| 马山县| 黔西县| 南和县| 星子县| 卫辉市| 石渠县| 大埔区| 临西县| 子洲县| 浮梁县| 潢川县| 横峰县| 藁城市| 厦门市| 日土县| 玉溪市| 平舆县| 长春市| 尚志市| 且末县| 喀什市| 惠来县| 崇左市| 贵溪市| 榆中县| 志丹县|