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

JavaScript觸發(fā)onScroll事件的函數(shù)節(jié)流詳解

 更新時間:2016年12月14日 10:52:21   作者:Encounter  
這篇文章的內(nèi)容是說說最近在工作中遇到過的常見的問題。主要是關(guān)于JavaScript觸發(fā)onScroll事件的函數(shù)節(jié)流,文中由一個常見的問題開始展開,一步步的介紹解決的方法,有需要的朋友們下面來跟著小編一起看看吧。

問題描述

常見的網(wǎng)站布局,頂部一個導(dǎo)航欄,我們假設(shè)本頁面共有四個欄目:分別為A、B、C、D,我們點(diǎn)擊A,錨點(diǎn)跳轉(zhuǎn)至A欄目,同時頂部的A按鈕高亮;點(diǎn)擊B,錨點(diǎn)跳轉(zhuǎn)至B欄目,同時頂部的B按鈕高亮;我們在Main組件里面滾動,滾動到B模塊時,B按鈕高亮。以上是我們經(jīng)常會在開發(fā)中遇到的一個模型。如果是在以前,用jQuery作前端開發(fā)的話,實(shí)在是太熟悉不過了。

解決方案

主要想談?wù)勗赗eact組件化開發(fā)中的性能優(yōu)化方法。

我們的頁面結(jié)構(gòu)是這樣的

<div
 className={style.main}
 id="main"
 ref={(main) => { this.main = main; }}
 onScroll={
 ((/detail/.test(this.props.location.pathname))) ? (() => this.throttle()()) : null
 }
>
 {this.props.children}
 <Footer />

我們在main組件里設(shè)定onScroll事件,在這個事件中,我們觸發(fā)action,通過redux將狀態(tài)的變化傳遞到子組件。

我的scroll事件觸發(fā)函數(shù)是這樣的(忽略一長串的if else,這是一個解決了一下午的bug的終極解決方案,此文不做累述)

 handleScroll() {
 const { changeScrollFlag } = this.props.actions;
 // 根據(jù)滾動距離修改TitleBox的樣式
 const { basicinformation, holderinformation, mainpeople, changerecord } = {
 basicinformation: document.getElementById('basicinformation').offsetTop - 121,
 holderinformation: document.getElementById('holderinformation').offsetTop - 121,
 mainpeople: document.getElementById('mainpeople').offsetTop - 121,
 changerecord: document.getElementById('changerecord').offsetTop - 121,
 };
 if (window.screen.availHeight > this.main.scrollTop) {
 document.getElementById('gototop').style.display = 'none';
 } else {
 document.getElementById('gototop').style.display = 'block';
 }
 // 得到基礎(chǔ)信息區(qū)域、股東信息區(qū)域、主要人員區(qū)域、變更記錄區(qū)域的offsetTop,我們把它用來跟main的scrollTop比較
 // 比較的結(jié)果觸發(fā)action,改變TitleBox組件樣式
 if (this.main.scrollTop < holderinformation) {
 // 基礎(chǔ)信息區(qū)域
 if (basicinformation === -121) {
 // 如果基礎(chǔ)信息模塊不存在,我們什么也不做(當(dāng)然理論上基礎(chǔ)信息模塊應(yīng)該是會有的)
 return;
 }
 changeScrollFlag(1);
 return;
 } else if (this.main.scrollTop < mainpeople) {
 // 股東信息區(qū)域
 changeScrollFlag(2);
 if (holderinformation === -121) {
 // 如果股東信息欄目不存在,在滾動的時候我們不應(yīng)該強(qiáng)行把TileBox的高亮按鈕設(shè)置為holderinformation
 // 因?yàn)閔oldinformation并不存在,我們跳到前一個按鈕,讓基礎(chǔ)信息按鈕高亮
 changeScrollFlag(1);
 return;
 }
 return;
 } else if (this.main.scrollTop < changerecord) {
 // 主要人員區(qū)域
 changeScrollFlag(3);
 if (mainpeople === -121) {
 // 如果主要人員欄目不存在,在滾動的時候我們不應(yīng)該強(qiáng)行把TileBox的高亮按鈕設(shè)置為mainpeople
 // mainpeople并不存在,我們跳到前一個按鈕,讓基礎(chǔ)信息按鈕高亮
 changeScrollFlag(2);
 if (holderinformation === -121) {
 // 如果主要人員欄目不存在,而且連股東信息欄目也沒有,我們跳到高亮基礎(chǔ)信息欄目
 changeScrollFlag(1);
 return;
 }
 return;
 }
 return;
 } else if (this.main.scrollTop > changerecord) {
 // 與上面同理
 // 變更記錄區(qū)域
 changeScrollFlag(4);
 if (changerecord === -121) {
 changeScrollFlag(3);
 if (mainpeople === -121) {
 changeScrollFlag(2);
 if (holderinformation === -121) {
  changeScrollFlag(1);
  return;
 }
 return;
 }
 return;
 }
 return;
 }
}

其中,changeScrollFlag()函數(shù)是我們的action處理函數(shù)。

我們的函數(shù)節(jié)流

throttle() {
 // onScroll函數(shù)節(jié)流
 let previous = 0;
 // previous初始設(shè)置上一次調(diào)用 onScroll 函數(shù)時間點(diǎn)為 0。
 let timeout;
 const wait = 250;
 // 250毫秒觸發(fā)一次
 return () => {
 const now = Date.now();
 const remaining = wait - (now - previous);
 if (remaining <= 0) {
 if (timeout) {
 window.clearTimeout(timeout);
 }
 previous = now;
 timeout = null;
 this.handleScroll();
 } else if (!timeout) {
 timeout = window.setTimeout(this.handleScroll, wait);
 }
 };
}

我們的節(jié)流函數(shù)返回一個函數(shù),設(shè)定一個時間戳,如果我們時間戳的差值較小,我們什么也不做,但我們的時間戳的差值較大,清除定時器,觸發(fā)scroll函數(shù)。這樣看起來似乎挺簡單,對,確實(shí)是挺簡單的。

那么在子組件我們還需要怎么做呢?

接收action

二級容器型組件接收action,通過二級容器型組件傳遞props至三級展示型組件。

我們一定要在componentWillReceiveProps接收到這個props。

記住,在componentWillReceiveProps里使用this.props是并不能夠接收到props的變化的?。?!組件生命周期函數(shù)含有一個自己的參數(shù)。

 componentWillReceiveProps(nextProps) {
 // 在compoWillReceiveProps里接收到Main組件里所觸發(fā)onScroll事件的改變activebtn樣式的index
 // 并且設(shè)置為本組件的state
 this.setState({
 activebtn: nextProps.scrollFlag.scrollIndex,
 });
}

我們的state控制我們高亮的按鈕是第幾個,它是一個數(shù)字。

更改導(dǎo)航條的樣式

在這里,我使用了React周邊的庫:classnames,詳情參見其api。

<span
 className={classnames({
 [style.informationactive]: (this.state.activebtn === 1),
 })}
 onClick={() => this.handleClick(1, 'basicinformation')}
>

在此,我們完成了一次從頂層組件觸發(fā)事件,并做到函數(shù)節(jié)流,將事件一層層傳遞至底層展示型組件的一個過程。
最近一些關(guān)于前端開發(fā)的感慨

  1. 不要在組件中反復(fù)調(diào)用一個函數(shù),這樣會造成巨大的消耗!我們可以通過三元運(yùn)算符、模板字符串做到的事情,請勿寫一個新的函數(shù)。
  2. jsx不要太過于冗余。我們盡量寫成變量的形式,不然頁面結(jié)構(gòu)復(fù)雜,不易于我們捕捉bug。
  3. 減少后端請求,能存cookie則存cookie,能存localStorge則存localStorge。
  4. 簡單的組件盡量自己寫,請勿使用別人的組件,否則在需求更改、樣式調(diào)整上會出現(xiàn)巨大困難并做一些無意義的事兒。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關(guān)文章

  • OpenLayers3加載常用控件使用方法詳解

    OpenLayers3加載常用控件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了OpenLayers3加載常用控件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • 微信小程序?qū)崿F(xiàn)簡單Tab切換效果

    微信小程序?qū)崿F(xiàn)簡單Tab切換效果

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)簡單Tab切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • JavaScript數(shù)組Array對象增加和刪除元素方法總結(jié)

    JavaScript數(shù)組Array對象增加和刪除元素方法總結(jié)

    這篇文章主要介紹了JavaScript數(shù)組Array對象增加和刪除元素方法,實(shí)例總結(jié)了pop方法、push方法、splice方法、concat方法等的使用技巧,需要的朋友可以參考下
    2015-01-01
  • JS的replace方法詳細(xì)介紹

    JS的replace方法詳細(xì)介紹

    replace() 方法的參數(shù) replacement 可以是函數(shù)而不是字符串。在這種情況下,每個匹配都調(diào)用該函數(shù),它返回的字符串將作為替換文本使用
    2012-11-11
  • 純JS實(shí)現(xiàn)旋轉(zhuǎn)圖片3D展示效果

    純JS實(shí)現(xiàn)旋轉(zhuǎn)圖片3D展示效果

    本文給大家分享的是純js實(shí)現(xiàn)的類似flash里的圖片環(huán)繞旋轉(zhuǎn)效果,非常炫酷,有需要的小伙伴可以參考下。
    2015-04-04
  • 最短的IE判斷代碼

    最短的IE判斷代碼

    以前最短的IE判定借助于IE不支持垂直制表符的特性搞出來的。
    2011-03-03
  • 教你用Js寫一個簡單的五子棋小游戲

    教你用Js寫一個簡單的五子棋小游戲

    聽說這是一道騰訊的面試題,可能網(wǎng)上已經(jīng)有不少答案了,晚上沒事看到這道題就自己做了下,下面這篇文章主要給大家介紹了關(guān)于如何用Js寫一個簡單的五子棋小游戲的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • 簡單談?wù)刼ffsetleft、offsetTop和offsetParent

    簡單談?wù)刼ffsetleft、offsetTop和offsetParent

    這篇文章主要給大家介紹了offsetleft、offsetTop和offsetParent的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • JavaScript解決浮點(diǎn)數(shù)計算不準(zhǔn)確問題的方法分析

    JavaScript解決浮點(diǎn)數(shù)計算不準(zhǔn)確問題的方法分析

    這篇文章主要介紹了JavaScript解決浮點(diǎn)數(shù)計算不準(zhǔn)確問題的方法,結(jié)合實(shí)例形式分析了javascript浮點(diǎn)數(shù)運(yùn)算精度誤差的原因以及相關(guān)的解決方法與具體操作技巧,需要的朋友可以參考下
    2018-07-07
  • 用js格式化金額可設(shè)置保留的小數(shù)位數(shù)

    用js格式化金額可設(shè)置保留的小數(shù)位數(shù)

    這篇文章主要介紹了如何用js格式化金額并設(shè)置保留的小數(shù)位數(shù),需要的朋友可以參考下
    2014-05-05

最新評論

新郑市| 漳平市| 政和县| 扬州市| 昆明市| 思南县| 阳城县| 遵义市| 腾冲县| 米脂县| 乌什县| 和田县| 宁陵县| 寿宁县| 卢龙县| 贞丰县| 巩义市| 宝坻区| 丹寨县| 政和县| 紫云| 榆中县| 嘉祥县| 镇赉县| 兴义市| 齐齐哈尔市| 庐江县| 淮安市| 同德县| 镇赉县| 郯城县| 恭城| 鹰潭市| 伊宁市| 兴城市| 海丰县| 岚皋县| 武邑县| 瑞昌市| 蒲江县| 临洮县|