Maison  >  Article  >  interface Web  >  Explication détaillée de la limitation des fonctions qui déclenche l'événement onScroll en JavaScript

Explication détaillée de la limitation des fonctions qui déclenche l'événement onScroll en JavaScript

高洛峰
高洛峰original
2016-12-29 10:19:261518parcourir

Description du problème

Mise en page commune du site Web, une barre de navigation en haut, on suppose que cette page a quatre colonnes : A, B, C, D, on clique sur A, l'ancre saute Go à la colonne A, et le bouton A en haut est mis en surbrillance ; cliquez sur B, et l'ancre passe à la colonne B, et le bouton B en haut est mis en surbrillance ; nous faisons défiler le composant principal, et lorsque nous faisons défiler jusqu'au module B ; , le bouton B est mis en surbrillance. Ce qui précède est un modèle que nous rencontrons souvent en développement. Si vous avez utilisé jQuery pour le développement front-end dans le passé, vous le connaissez très bien.

Solution

Je souhaite principalement parler des méthodes d'optimisation des performances dans le développement de composants React.

La structure de notre page est comme ceci

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

Nous définissons l'événement onScroll dans le composant principal. Dans cet événement, nous déclenchons l'action et modifions le statut via redux Passé à. composants enfants.

Ma fonction de déclenchement d'événements de défilement est comme ça (en ignorant la longue liste de if else, c'est la solution ultime à un bug d'un après-midi, et je n'entrerai pas dans les détails dans cet article)

handleScroll() {
 const { changeScrollFlag } = this.props.actions;
 // 根据滚动距离修改TitleBox的样式
 const { basicinformation, holderinformation, mainpeople, changerecord } = {
 basicinformation: document.getElementById(&#39;basicinformation&#39;).offsetTop - 121,
 holderinformation: document.getElementById(&#39;holderinformation&#39;).offsetTop - 121,
 mainpeople: document.getElementById(&#39;mainpeople&#39;).offsetTop - 121,
 changerecord: document.getElementById(&#39;changerecord&#39;).offsetTop - 121,
 };
 if (window.screen.availHeight > this.main.scrollTop) {
 document.getElementById(&#39;gototop&#39;).style.display = &#39;none&#39;;
 } else {
 document.getElementById(&#39;gototop&#39;).style.display = &#39;block&#39;;
 }
 // 得到基础信息区域、股东信息区域、主要人员区域、变更记录区域的offsetTop,我们把它用来跟main的scrollTop比较
 // 比较的结果触发action,改变TitleBox组件样式
 if (this.main.scrollTop < holderinformation) {
 // 基础信息区域
 if (basicinformation === -121) {
 // 如果基础信息模块不存在,我们什么也不做(当然理论上基础信息模块应该是会有的)
 return;
 }
 changeScrollFlag(1);
 return;
 } else if (this.main.scrollTop < mainpeople) {
 // 股东信息区域
 changeScrollFlag(2);
 if (holderinformation === -121) {
 // 如果股东信息栏目不存在,在滚动的时候我们不应该强行把TileBox的高亮按钮设置为holderinformation
 // 因为holdinformation并不存在,我们跳到前一个按钮,让基础信息按钮高亮
 changeScrollFlag(1);
 return;
 }
 return;
 } else if (this.main.scrollTop < changerecord) {
 // 主要人员区域
 changeScrollFlag(3);
 if (mainpeople === -121) {
 // 如果主要人员栏目不存在,在滚动的时候我们不应该强行把TileBox的高亮按钮设置为mainpeople
 // mainpeople并不存在,我们跳到前一个按钮,让基础信息按钮高亮
 changeScrollFlag(2);
 if (holderinformation === -121) {
 // 如果主要人员栏目不存在,而且连股东信息栏目也没有,我们跳到高亮基础信息栏目
 changeScrollFlag(1);
 return;
 }
 return;
 }
 return;
 } else if (this.main.scrollTop > changerecord) {
 // 与上面同理
 // 变更记录区域
 changeScrollFlag(4);
 if (changerecord === -121) {
 changeScrollFlag(3);
 if (mainpeople === -121) {
 changeScrollFlag(2);
 if (holderinformation === -121) {
  changeScrollFlag(1);
  return;
 }
 return;
 }
 return;
 }
 return;
 }
}

Parmi elles, la fonction changeScrollFlag() est notre fonction de traitement des actions.

Notre fonction de limitation

throttle() {
 // onScroll函数节流
 let previous = 0;
 // previous初始设置上一次调用 onScroll 函数时间点为 0。
 let timeout;
 const wait = 250;
 // 250毫秒触发一次
 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);
 }
 };
}

Notre fonction de limitation renvoie une fonction qui définit un horodatage Si la différence entre nos horodatages est petite, que faisons-nous ? non plus, mais la différence entre nos horodatages est grande, effacez la minuterie et déclenchez la fonction de défilement. Cela semble assez simple, oui, c'est effectivement assez simple.

Alors, que devons-nous faire d'autre dans la sous-composante ?

Recevoir l'action

Le composant conteneur de deuxième niveau reçoit l'action et transmet les accessoires au composant d'affichage de troisième niveau via le composant conteneur de deuxième niveau.

Nous devons recevoir ces accessoires dans composantWillReceiveProps.

N'oubliez pas que l'utilisation de this.props dans composantWillReceiveProps ne recevra pas de modifications dans les accessoires ! ! ! La fonction de cycle de vie des composants contient son propre paramètre.

componentWillReceiveProps(nextProps) {
 // 在compoWillReceiveProps里接收到Main组件里所触发onScroll事件的改变activebtn样式的index
 // 并且设置为本组件的state
 this.setState({
 activebtn: nextProps.scrollFlag.scrollIndex,
 });
}

Notre état contrôle quel bouton nous mettons en surbrillance, c'est un nombre.

Changer le style de la barre de navigation

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

Ici, nous avons terminé le déclenchement d'un événement à partir du composant de niveau supérieur, implémenté la limitation des fonctions et superposé l'événement Processus par lequel une couche est transmise à un composant de présentation sous-jacent.
Quelques réflexions récentes sur le développement front-end

N'appelez pas une fonction à plusieurs reprises dans un composant, car cela entraînerait une consommation énorme ! N'écrivez pas une nouvelle fonction pour ce que nous pouvons faire avec l'opérateur ternaire et les chaînes de modèle.

Ne soyez pas trop redondant en jsx. Nous essayons de l'écrire sous forme de variables, sinon la structure de la page sera compliquée et il nous sera difficile d'attraper des bugs.

Réduisez les requêtes back-end. Si les cookies peuvent être stockés, les cookies seront stockés. Si localStorge peut être stocké, localStorge sera stocké.

Essayez d'écrire des composants simples par vous-même. N'utilisez pas les composants d'autres personnes, sinon vous aurez d'énormes difficultés à modifier les exigences et à ajuster les styles, et vous ferez des choses dénuées de sens.

Résumé

Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article pourra être utile aux études ou au travail de chacun. Si vous avez des questions, vous pouvez partir. un message à communiquer.


Pour des explications plus détaillées sur la limitation des fonctions qui déclenche l'événement onScroll en JavaScript, veuillez faire attention au site Web chinois de PHP !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn