关于移动端h5实现顶部吸附

今天的一点感悟:就是希望自己可以养成分享的思维方式。故记录下了这篇:
1.页面大致样式:
   
2.功能点:
  (1)当页面往上滑动时:最新和精华这一行的导航条吸附到搜索栏下面。
  (2)需要判断App版本,因为是新加的功能,所以之前的版本不用这个功能。
  (3)需要判断是网页,还是手机打开。网页打开也不需要这个功能,因为网页无法获取搜索栏高度。
3.实现当中出现的问题:
     (1)苹果手机是手指离开屏幕才触发事件,安卓手机支持的很好(scroll事件)
     (2)添加了一些样式之后,苹果手机就支持的很好,目前还不知道问题出在哪里
4.相关Js代码
	(1)UI渲染部分:
  super(props)
  this.state = {
    pullPosition: 1,  //用来判断导航的定位,1是relative,0是fixed
    fixTop: 0  //导航距离顶部高度
  }
  this.topBarVal = 0 //手机搜索栏的高度
  this.bannerHeight = 0 //banner高度
}
  <div className={styles.tabTitle}>
    <ul>
      <li className={this.state.selectType === 1 ? 'active' : ''} onClick={() => { this.onChangeType(1) }}>最新</li>
      <li className={this.state.selectType === 2 ? 'active' : ''} onClick={() => { this.onChangeType(2) }}>精华</li>
    </ul>
  </div>
</div>
	}
        (2)JS部分
onScrollPos() {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const bannerHeight = this.bannerHeight;
  const topBarVal = this.topBarVal;
  if (topBarVal !== 0) {
    if ((bannerHeight - topBarVal) <= scrollTop) {
      this.setState({
        pullPosition: 0,
        fixTop: topBarVal
      })
    } else {
      this.setState({
        pullPosition: 1,
        fixTop: 0
      })
    }
  }
}
         
  // BANNER和搜索栏高度值进行存储
  this.bannerHeight = findDOMNode(this.refs.sliderTop).offsetHeight
  if (window.****&& window.****.getTopBarHeight) {
    let topBarVal = window.****.getTopBarHeight()
    if (uaType() === 'ANDROID') {    //判断是否是安卓手机
      topBarVal = topBarVal / (window.devicePixelRatio || 1);
    }
    this.topBarVal = topBarVal
  }
  if (!lessThanVersion('1.4.2') && inApp()) {
    let supportsPassive = false;
    Object.defineProperty({}, 'passive', {
      get() {
        supportsPassive = true;
      }
    });
    this.onScroll = throttle(() => {
      this.onScrollPos()
    }, 100)
    let timer = null;
    let oldTop = document.documentElement.scrollTop || document.body.scrollTop;
    let newTop = oldTop
    this.startScroll = () => {
      if (timer) { clearTimeout(timer) }
      newTop = document.documentElement.scrollTop || document.body.scrollTop;
      if (newTop === oldTop) {
        this.onScrollPos()
      } else {
        oldTop = newTop;
        this.onScrollPos()
        timer = setTimeout(this.startScroll, 100);
      }
    }
    if (uaType() === 'ANDROID') {
      document.addEventListener('scroll', this.onScroll, supportsPassive ? { passive: true } : false);
    } else {
      document.addEventListener('touchmove', this.startScroll, supportsPassive ? { passive: true } : false);
    }
  }
  // 限制 onPageActive的调用
  this.pageActiveCalledTs = (new Date()).getTime();
  // 添加全局接口,APP回调
  window.onPageActive = () => {
    
  };
}
shouldComponentUpdate(nextProps) {
  return this.state.fixTop !== nextProps.fixTop || this.state.pullPosition !== nextProps.pullPosition;
}
componentWillUnmount() {
  if (this.onScroll) {
    document.removeEventListener('scroll', this.onScroll)
    document.removeEventListener('touchmove', this.startScroll)
  }
}
5.相关css代码
  box-shadow: 0 1px 4px 0 rgba(0,0,0,0.1);
  animation: changeOpacity .5s;
  -webkit-animation: changeOpacity .5s; /*Safari and Chrome*/
  -moz-animation: changeOpacity .5s;   /* Firefox */
  -o-animation: changeOpacity .5s; /* Opera */
}
:global(.fixPosition){
  position: fixed;
  height: .75rem;
  z-index: 99;
  width: 100%;
  box-shadow: 0 1px 4px 0 rgba(0,0,0,0.1);
}
@-webkit-keyframes changeOpacity{
  from{
    opacity: 0;
  }
  to{
    opacity: 100;
  }
}
@keyframes changeOpacity{
  from{
    opacity: 0;
  }
  to{
    opacity: 100;
  }
}
.occupy{
  height: .75rem;
  visibility: visible;
  box-shadow: 0 1px 4px 0 rgba(0,0,0,0.1);
}
.hidePos{
  display: none;
}
.showPos{
  display: block;
  position: fixed;
  height: .75rem;
  width: 100%;
  z-index: 99;
  left: 0;
  box-shadow: 0 1px 4px 0 rgba(0,0,0,0.1);
}
.hideOpa{
  visibility: hidden;
}
6.总结:
   在自己觉得有意义的东西,可以记录下来,对自己也是一种帮助。
   

constructor(props) {
render() {
//这里是轮播图
<Slideritems={props.recommendations}ref="sliderTop"/>
//这里是导航
<divclassName={showPosition}style={fixTop}>
//滚动触发定位
componentDidMount() {
:global(.relPosition){


猜你喜欢

转载自blog.csdn.net/dududu01/article/details/55057471