布局结构

- wapper内外两层div包裹实际内容 第一层div=placeholder 占位有宽高的数据 无实际内容 另一层随窗口滚动计算位置fixed
- onResize重计算位置
- 开始渲染时 并未触发固钉效果,将正常渲染目标组件,后续计算可以拿到正常渲染时的宽高数据
- 留下来占位的一般需要不影响整体样式 比方说开始固钉效果后 原有展示没有很大缺陷
代码实现
// 第一层size监听 用于处理容器size变化<ResizeObserver onResize={() => { this.updatePosition(); }} > <div {...props} ref={this.savePlaceholderNode}> {affixStyle && <div style={placeholderStyle} aria-hidden="true" />} <div className={className} ref={this.saveFixedNode} style={affixStyle}> // 第二层size监听 用于处理内容size变化 有可能top或者bottom变化 <ResizeObserver onResize={() => { this.updatePosition(); }} > {children} </ResizeObserver> </div> </div>// 计算逻辑 // 固钉的样式数据 宽高等 const targetRect = getTargetRect(targetNode); // 占位的样式数据 宽高等 const placeholderReact = getTargetRect(this.placeholderNode); const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop); const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom); if (fixedTop !== undefined) { newState.affixStyle = { position: 'fixed', top: fixedTop, width: placeholderReact.width, // 固钉的宽高以原本正常渲染的内容宽高为基准 height: placeholderReact.height, }; newState.placeholderStyle = { width: placeholderReact.width, // 当固钉开始fixed的时候 placeholder需要拿到正常渲染时的宽高占位 height: placeholderReact.height, }; // 下方固定 } else if (fixedBottom !== undefined) { newState.affixStyle = { position: 'fixed', bottom: fixedBottom, width: placeholderReact.width, height: placeholderReact.height, }; newState.placeholderStyle = { width: placeholderReact.width, height: placeholderReact.height, };