这篇文章的内容就是说说最近工作中遇到的常见问题。主要是关于JavaScript触发onScroll事件的函数节流。本文从一个常见问题入手,逐步介绍解决方案。有需要的朋友可以和边肖一起看看。
问题描述
常见的网站布局,顶部有一个导航栏。我们假设这个页面有四列:分别是A、B、C和D。我们点击A,锚点跳转到A列,顶部的A按钮高亮显示;点击B,锚点跳转到B列,最上方的B按钮高亮显示;我们在主组件中滚动,当我们滚动到B模块时,B按钮被突出显示。以上是我们在开发中经常遇到的一个模型。以前如果用jQuery做前端开发,那就太熟悉了。
解决方案
主要想说一下React的组件开发中的性能优化方法。
我们的页面结构如下
差异
className={style.main}
id='main '
ref={(main)={ this . main=main;}}
onScroll={
((/detail/。test(this . props . location . pathname)))?(()=this.throttle()()) : null
}
{this.props.children}
页脚/
我们在主组件中设置onScroll事件。在这个事件中,我们触发动作,并通过redux将状态的改变传递给子组件。
我的滚动事件触发函数是这样的(忽略一长串if else,这是一下午bug的终极解决方案,本文不再赘述)
handleScroll() {
const { changescrollfag }=this . props . actions;
//根据滚动距离修改标题栏的样式
const { basicinformation,holderinformation,mainpeople,changerecord }={
basic information:document . getelementbyid(' basic information ')。偏移量- 121,
holder information:document . getelementbyid(' holder information ')。偏移量- 121,
main people:document . getelementbyid(' main people ')。偏移量- 121,
change record:document . getelementbyid(' change record ')。偏移量- 121,
};
if(window . screen . avail height this . main . scroll top){
document . getelementbyid(' goto top '). style . display=' none ';
}否则{
document . getelementbyid(' goto top '). style . display=' block ';
}
//获取基本信息区、股东信息区、关键人员区、变更记录区的offsetTop,与main的scrollTop进行比较。
//比较的结果触发动作,改变TitleBox组件的样式。
if(this . main . scroll top holder information){
//基本信息区
if (basicinformation===-121) {
//如果基本信息模块不存在,我们就什么都不做(当然理论上基本信息模块应该存在)
返回;
}
changes croll flag(1);
返回;
} else if(this . main . scroll top main people){
//股东信息区
changes croll flag(2);
if (holderinformation===-121) {
//如果股东信息栏不存在,我们就不要在滚动时强行将TileBox的高亮按钮设置为holder information。
//因为holdinformation不存在,所以让我们跳到上一个按钮,突出显示基本信息按钮。
changes croll flag(1);
返回;
}
返回;
} else if(this . main . scroll top changerecord){
//主要人事领域
changes croll flag(3);
if (mainpeople===-121) {
//如果主人员栏不存在,我们就不要在滚动时强行将TileBox的高亮按钮设置为mainpeople。
//mainpeople不存在。让我们跳到上一个按钮,突出显示“基本信息”按钮。
changes croll flag(2);
if (holderinformation===-121) {
//如果主要人员栏不存在,甚至连股东信息栏也没有,我们就跳转到突出显示基本信息栏。
changes croll flag(1);
返回;
}
返回;
}
返回;
} else if(this . main . scroll top change record){
//同上
//更改记录区域
changes croll flag(4);
if (changerecord===-121) {
changes croll flag(3);
if (mainpeople===-121) {
changes croll flag(2);
if (holderinformation===-121) {
changes croll flag(1);
返回;
}
返回;
}
返回;
}
返回;
}
}
其中,changeScrollFlag()函数是我们的动作处理函数。
我们的函数节流
节流(){
//onroll函数节流
设previous=0;
//previous最初将最后一次调用onScroll函数的时间点设置为0。
let超时;
const wait=250
//每250毫秒触发一次
return ()={
const now=date . now();
const remaining=wait -(现在-以前);
如果(剩余=0) {
如果(超时){
window.clearTimeout(超时);
}
以前=现在;
超时=空;
this . handle scroll();
} else if(!超时){
time out=window . settimeout(this . handle scroll,wait);
}
};
}
我们的throttle函数返回一个函数并设置一个时间戳。如果我们的时间戳之间的差异很小,我们什么都不做,但是我们的时间戳之间的差异很大。清除定时器并触发滚动功能。这看起来很简单,是的,很简单。
那么在子组件中我们还需要做些什么呢?
接收action
第二级容器组件接收动作,并通过第二级容器组件将道具传送给第三级显示组件。
我们必须在componentWillReceiveProps收到此道具。
记住,在componentWillReceiveProps中使用this.props无法接收道具的改动!组件生命周期函数包含自己的参数。
componentWillReceiveProps(next props){
//在compoWillReceiveProps中,接收主组件中触发的onScroll事件的activebtn样式的索引。
//并设置为此组件的状态
this.setState({
active BTN:nextprops . scroll flag . scroll index,
});
}
我们的状态控制我们高亮显示哪个按钮。这是一个数字。
更改导航条的样式
在这里,我使用React周围的库:类名。详见其api。
跨度
className={classnames({
[style . information active]:(this . state . active BTN===1),
})}
onClick={()=this.handleClick(1,' basicinformation')}
在这里,我们完成了一个从顶层组件触发事件,对功能进行节流,将事件逐层传递到底层显示组件的过程。
最近对前端开发的一些感受
不要在一个组件中重复调用一个函数,这样会造成巨大的消耗!我们能用三元运算符和模板字符串做什么,请不要写新的函数。
Jsx不要太多余。我们尽量用变量的形式来写,否则页面结构复杂,我们不容易抓到bug。
减少后端请求。如果你能储存饼干,你就能储存饼干。如果你能存储本地存储,你就能存储本地存储。
尽量自己写简单的组件,不要用别人的组件,否则改变需求和调整风格会有很大困难,还会做一些无意义的事情。
总结
这就是本文的全部内容。希望这篇文章的内容能给你的学习或者工作带来一些帮助。有问题可以留言交流。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。