react 吸顶实现
今天获取到一个需求,其实就是吸顶的需求,页面下滑,某一块dom隐藏时发生吸顶现象。这种特效其实老生常谈了,但是在这次做的时候,突发奇想,能否将其做成一个 hook ,从而实现出传递ref即可使得 dom 产生吸顶。原理其实很简单,但移动至隐藏时,设置接收的 dom 元素或者 ref ,使其 style 附上 fixed 定位。在做的过程中,遇到了许多问题,接下来一一道来
首先先讨论下,一般大家常用的吸顶方法
由于本章主要针对于react的开发,因此若是使用别的框架,就当看个热闹吧
网上还有其他的,纯操作原生js实现吸顶特效,在此就不赘述这些原生的了
解法一:css解决
css解决吸顶,大家自然而然想到的是粘性定位:sticky
由于我页面的复杂程度较高,未能用 sticky 实现吸顶。但也去查了查 粘性定位的使用,发现限制不仅多,而且兼容性有待商榷。当然移动端不考虑这些,可以通过css实现的,自然是最好的,性能自然也是最好的。
position: sticky;
top: 0; /*top/right/bottom/left 任一有效值*/
使用 sticky 的时候,应当注意,别忘记 top (即吸顶的时候距离顶部距离为0) 等有效值设置
当你使用粘性定位失效的可能性如下:
一、只在 可滚动父元素内有效
用一个 div 把 div.sticky 包裹起来,发现 Sticky 效果失效,当使用 Sticky 时,其实需要确保包含Sticky 的父元素有可滑动的高度。
sticky的规则是:当页面滚动,父元素开始脱离视口时(即部分不可见),只要与sticky元素的距离达到生效门槛,relative定位自动切换为fixed定位;等到父元素完全脱离视口时(即完全不可见),fixed定位自动切换回relative定位。
当div.sticky移动至父元素顶部时,就会触发吸顶的效果。
二、兼容性问题
直接上图,最为方便

解法二:react 配合ahook使用
此法仅在react框架中使用,且需安装ahook依赖
我们使用ahook中的useScroll监听页面的滚动,在页面滚动的过程中,判断需吸顶的元素是否处于可视区域,若不处于可视区域,则直接吸顶
const [searchHidden, setSearchHidden] = useState<boolean>(false); // 设置是否吸顶的标识
const [height, setHeight] = useState<number>(0);// 获取吸顶元素距离顶部的高度
const searchRef = useRef(null);// 吸顶ref
const scroll = useScroll(document);
useEffect(() => {
setTimeout(() => {
setHeight(searchRef?.current?.getBoundingClientRect().top)// 设置元素距离顶部的高度
}, 0);
}, [])
useEffect(() => {
// 监听滚动,超出高度则吸顶
if (scroll.top <= height) {
if (searchHidden && searchRef.current) {
searchRef.current.style = '{}'
setSearchHidden(false)
}
} else {
if (!searchHidden && searchRef.current) {
setSearchHidden(true)
searchRef.current.style.position = 'fixed';
searchRef.current.style.top = '0';
searchRef.current.style.zIndex = '999';
}
}
}, [JSON.stringify(scroll)])
此处代码应当注意以下几点
useScroll 是ahook的函数,需安装ahook依赖
使用定时器设置元素距离顶部的高度,是为了使得该渲染完的dom渲染完之后,获取真实的高度
解法三:react-sticky
position: sticky 可以替代 react-sticky,但是它(position: sticky)的浏览器兼容不是很好,尤其是不支持 IE11 和 table 元素的一些 bug,在使用 react-sticky 之前,检查一下如果浏览器支持和限制阻止你使用 position: sticky,因为 CSS 总是比 JS 更快和耐用<StickyContainer>
<Sticky>{({ style }) => <h1 style={style}>Sticky element</h1>}</Sticky>
</StickyContainer>
需要使用StickyContainer对需要吸顶的元素进行包裹,后续有时间,想试着阅读下rsticky 的源码,将此进行包裹就可实现吸顶,但是对于UI较为复杂的页面来说,js 的代码控制最为方便。
react 吸顶实现的更多相关文章
- React制作吸顶功能总结
总结一下最近用react写项目时,遇到的一些坑,恩,真的还蛮坑的,主要是设置状态的时候特别不好控制,下面我们一起来看下,这里自己做了几个demo,分别看下, 主页面代码如下: class Head e ...
- react.js中实现tab吸顶效果问题
在react项目开发中有一个需求是,页面滚动到tab所在位置时,tab要固定在顶部. 实现的思路其实很简单,就是判断当滚动距离scrollTop大于tab距离页面顶部距离offsetTop时,将tab ...
- [RN] React Native 中使用 stickyHeaderIndices 实现 ScrollView 的吸顶效果
React Native中,ScrollView组件可以使用 stickyHeaderIndices 轻松实现 sticky 效果. 例如下面代码中: <ScrollView showsVert ...
- [RN] React Native 头部 滑动吸顶效果的实现
React Native 头部 滑动吸顶效果的实现 效果如下图所示: 实现方法: 一.吸顶组件封装 StickyHeader .js import * as React from 'react'; i ...
- 吸顶大法 -- UWP中的工具栏吸顶的实现方式之一
如果一个页面中有很长的列表/内容,很多应用都会在用户向下滚动时隐藏页面的头,给用户留出更多的阅读空间,同时提供一个方便的吸顶工具栏,比如淘宝中的店铺页面. 下面是一个比较简单的实现,如果有同学有更好的 ...
- status bar、navigationBar、tableView吸顶view设置
1. 隐藏navigationBar self.navigationController.navigationBar.hidden = YES; 2. status bar设置 -(void)view ...
- collectionview cell吸顶效果
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Hiragino Sans GB"; color: #cf8724 } ...
- 原生js实现吸顶导航和回到顶部特效
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ECSTORE导航吸顶功能
ecstore导航吸顶功能,在导航父元素中加入id,如: <div id="mainNav1"></div> 在footer.html中添加以下js代码: ...
随机推荐
- WPF全局异常处理
private void RegisterEvents() { //Task线程内未捕获异常处理事件 TaskScheduler.UnobservedTaskException += TaskSche ...
- 【NodeJS】替换模糊查询字符里包含的正则关键字
问题:正则匹配时字符串中包含了一些特殊字符,导致查询失败 例如,下面的字符包含了( 和 ),这在正则中属于特殊字符 (-)-magnocurarine 正则中的特殊字符如下图 思路: 1.映射查询字符 ...
- 个人冲刺(五)——体温上报app(二阶段)
冲刺任务:完成用户登录和随机验证码功能 loginActivity.java package com.example.helloworld; /** * 纯粹实现登录注册功能,其它功能都被注释掉了 * ...
- vuex+Es6语法补充-Promise
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,采用 集中式存储管理 单页面的状态管理/多页面状态管理 使用步骤: // 1.导入 import Vuex from 'vuex' // ...
- bintree
Python实现二叉树的建立与遍历 创建(二叉)树节点类 class Node: def __init__(self,data,l=None,r=None): self.val = data self ...
- B 树的简单认识
理解 B 树的概念 B 树是一种自平衡的查找树,能够保持数据有序.这种数据结构能够让查找数据.顺序访问.插入数据及删除数据的动作,都能在对数时间内完成. 同一般的二叉查找树不同,B 树是一棵多路平衡查 ...
- 【Spring】AOP实现原理(二):Advisor获取
@EnableAspectJAutoProxy @EnableAspectJAutoProxy注解可以用来开启AOP,那么就从@EnableAspectJAutoProxy入手学习一下Spring A ...
- spring boot用ide新建项目遇到的restcontroller不能导入的问题
才开始学习spring boot,第一个程序helloworld就碰到@RestController和@RequestMapping(/hello)的注解都会报错的问题. 我个人的解决方法: 1.sp ...
- idea运行Tomcat出现 Address localhost:8080 is already in useAddress localhost:8080 is already in use
使用IDEA运行 tomcat时出现 Address localhost:8080 is already in use,就很奇怪,我明明只有这一个程序呀,怎么还会被占用.后来想想可能就是被其他进程占用 ...
- Maven的安装 和idea的配置
Maven的安装 和idea的配置 工欲善其事 必先利其器 1 下载maven 官网 下滑 找到Files tar.gz 是linux系统的 .zip window系统 2 maven安装和配置到环境 ...