React实现底部footer针对页面进行自适应

3,532 阅读3分钟

前言

需求是要求底部footer在页面中相对也屏幕进行适配,就是说当屏幕的东西超出一屏幕的时候需要在页面最后一个元素后面,
不足一屏幕的时候需要定位在下面,其实分析一下这个需求只要判断好页面的高度和内容进行定位就可以

大概构思

1.我是这样判断的首先获取底部footer相对于顶部的高度
2.用页面整体的高度和底部footer相对于顶部的高度进行判断,
如果整体高度大于footer相对于顶部的高度证明没有超出屏幕需要加定位定位到屏幕下面,
相反小于的话就说明超出了内容超出屏幕移除定位
3.还需要判断一下底部footer相邻的元素对于底部的距离
4.如果大于一个footer的情况下证明正好贴近底部但是还没超出这时候会有问题
5.所以当相邻元素距离底部的高度大于一个footer的时候也加定位和第一个条件是并且关系

上代码

1.获取底部footer相对于顶部的高度

js

 componentDidMount() {
     //dom生成之后 可能是dom生成需要时间所以加一个延迟
     setTimeout(() => {
         let hei = document.querySelector('body').offsetHeight//整个窗口的高度
         let footerTop = this.footer.offsetTop //底部footer相对于顶部的距离
     })
 }

2.用页面整体的高度和底部footer相对于顶部的高度进行判断,

如果整体高度大于footer相对于顶部的高度证明没有超出屏幕需要加定位定位到屏幕下面,
相反小于的话就说明超出了内容超出屏幕移除定位

js

 componentDidMount() {
     //dom生成之后 可能是dom生成需要时间所以加一个延迟
     setTimeout(() => {
         let hei = document.querySelector('body').offsetHeight//整个窗口的高度
         let footerTop = this.footer.offsetTop //底部footer相对于顶部的距离
         if (hei > footerTop) {
             //没有超出一屏幕高度 需要加定位
             this.footer.classList.add("footerPosi")
         } else {
              this.footer.classList.remove("footerPosi")
         }
     })
 }

css

 .footerPosi{
     position: absolute;
     bottom: 0;
 }

3.还需要判断一下底部footer相邻的元素对于底部的距离

 componentDidMount() {
     //dom生成之后 可能是dom生成需要时间所以加一个延迟
     setTimeout(() => {
         let hei = document.querySelector('body').offsetHeight//整个窗口的高度
         let footerTop = this.footer.offsetTop //底部footer相对于顶部的距离
         let footerHei = this.footer.offsetHeight
         let broNode = this.footer.previousSibling //相邻footer的节点
         let broNodeHei = hei - (broNode.offsetHeight + broNode.offsetTop)//距离底部的距离 用整体的高度减去底部相邻元素的自身高度和相对于顶部高度之和就是相对于底部的距离
         if (hei > footerTop && broNodeHei > footerHei) {
             //没有超出一屏幕高度 需要加定位
             this.footer.classList.add("footerPosi")
         } else {
             this.footer.classList.remove("footerPosi")
         }
     })
 }

出现的Bug

1一旦请求接口当有接口数据的时候页面彻底就乱了😂😂😂(还天真的以为这样就好了呢)
2.需要在componentWillReceiveProps重新计算一下因为当接口请求完之后页面会触发footer的props更新
3.在页面之间切换的时候可能到下一个页面会保留上一个页面遗留的计算结果,所以到页面中要提前清楚一次定位

解决Bug

1.后来我封装了一个方法把需要更新的东西都放在一个里面在DidMount 和WillReceiveProps执行

  resetFooter() {
     this.footer.classList.remove("footerPosi") //
     let hei = document.querySelector('body').offsetHeight//整个窗口的高度
     let footerTop = this.footer.offsetTop //底部footer相对于顶部的距离
     let footerHei = this.footer.offsetHeight
     let broNode = this.footer.previousSibling //相邻footer的节点
     let broNodeHei = hei - (broNode.offsetHeight + broNode.offsetTop)//距离底部的距离
     if (hei > footerTop && broNodeHei > footerHei) {
         //没有滚动条 需要定位
         this.footer.classList.add("footerPosi")
     } else {
         this.footer.classList.remove("footerPosi")
     }
 }
 
  componentDidMount() {
     //dom生成之后
     setTimeout(() => {
         this.resetFooter()
     })
  }
  componentWillReceiveProps() {
     setTimeout(() => {
         this.resetFooter()
     })
  }

总结

1.在做之前想的有点简单做的时候才发现需要注意的地方有很多比如切换页面中需要清楚一次定位
2.还有当一个屏幕正好满但是没有超出的时候
3.这一次做个总结希望下次不再走重复的bug

最后

如果那里有问题请不吝赐教💪💪💪