JavaScript에서 onScroll 이벤트를 트리거하는 함수 조절에 대한 자세한 설명

高洛峰
풀어 주다: 2016-12-29 10:19:26
원래의
1524명이 탐색했습니다.

문제 설명

일반적인 웹사이트 레이아웃, 상단에 탐색 모음, 이 페이지에 A, B, C, D의 4개 열이 있다고 가정하고 A를 클릭하면 앵커가 이동합니다. A 열로 이동하고 상단의 A 버튼이 강조 표시되면 B를 클릭하면 앵커가 B 열로 이동하고 상단의 B 버튼이 강조 표시됩니다. 메인 구성 요소에서 스크롤하면 B 모듈로 스크롤됩니다. , B 버튼이 강조 표시됩니다. 위의 내용은 우리가 개발 중에 자주 접하게 되는 모델입니다. 과거에 프론트엔드 개발에 jQuery를 사용해 본 적이 있다면 매우 익숙할 것입니다.

솔루션

주로 React 컴포넌트 개발에 있어 성능 최적화 방법에 대해 이야기하고 싶습니다.

페이지 구조는 이렇습니다

<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 />
로그인 후 복사

메인 컴포넌트에서 onScroll 이벤트를 설정했습니다. 이 이벤트에서는 redux를 통해 액션을 트리거하고 상태를 변경했습니다. 하위 구성 요소.

내 스크롤 이벤트 트리거 기능은 다음과 같습니다(if else의 긴 목록을 무시하면 이것이 오후 버그에 대한 궁극적인 해결책이므로 이 기사에서는 자세히 설명하지 않겠습니다)

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;
 }
}
로그인 후 복사

그 중 ChangeScrollFlag() 함수는 액션 처리 함수입니다.

제한 기능

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);
 }
 };
}
로그인 후 복사

제한 기능은 타임스탬프 간의 차이가 작을 경우 어떻게 해야 합니까? 둘 중 하나이지만 타임스탬프 간의 차이가 크므로 타이머를 지우고 스크롤 기능을 트리거하십시오. 이것은 매우 간단한 것 같습니다. 그렇습니다. 실제로는 매우 간단합니다.

그럼 하위 구성 요소에서는 또 무엇을 해야 할까요?

액션 수신

2차 레벨 컨테이너 구성요소는 액션을 수신하고 2차 레벨 컨테이너 구성요소를 통해 3차 디스플레이 구성요소에 props를 전달합니다.

이 prop을 componentWillReceiveProps에서 받아야 합니다.

commentWillReceiveProps에서 this.props를 사용하면 props의 변경 사항이 수신되지 않는다는 점을 기억하세요! ! ! 구성 요소 수명 주기 함수에는 자체 매개변수가 포함되어 있습니다.

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

상태는 강조 표시할 버튼을 제어하며 이는 숫자입니다.

탐색 모음 스타일 변경

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

여기서 최상위 구성 요소에서 이벤트 트리거를 한 번 완료하고 기능 조절 및 계층화를 달성했습니다. 이벤트 레이어가 기본 프리젠테이션 구성 요소로 전달되는 프로세스입니다.
프론트엔드 개발에 대한 최근 생각

컴포넌트 내에서 함수를 반복적으로 호출하지 마세요. 이렇게 하면 엄청난 소비가 발생합니다! 삼항 연산자와 템플릿 문자열을 사용하여 수행할 수 있는 작업에 대해 새 함수를 작성하지 마세요.

jsx를 너무 중복하지 마세요. 변수 형태로 작성하려고 합니다. 그렇지 않으면 페이지 구조가 복잡해지고 버그를 잡기가 어렵습니다.

백엔드 요청을 줄입니다. 쿠키가 저장되면 쿠키가 저장됩니다. localStorge가 저장되면 localStorge가 저장됩니다.

다른 사람의 컴포넌트를 사용하지 마세요. 그렇지 않으면 요구 사항을 변경하고 스타일을 조정하는 데 큰 어려움을 겪게 되며 의미 없는 일을 하게 됩니다.

요약

이 글의 내용이 모두의 공부나 업무에 조금이나마 도움이 되었으면 좋겠습니다. 소통하라는 메시지.


JavaScript에서 onScroll 이벤트를 발생시키는 함수 조절에 대한 자세한 설명은 PHP 중국어 홈페이지를 참고해주세요!


원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿