今天获取到一个需求,其实就是吸顶的需求,页面下滑,某一块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)])

        <div className={styles.search}  ref={searchRef}>  </div>

此处代码应当注意以下几点

useScroll 是ahook的函数,需安装ahook依赖
使用定时器设置元素距离顶部的高度,是为了使得该渲染完的dom渲染完之后,获取真实的高度

解法三:react-sticky

SS 属性 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 吸顶实现的更多相关文章

  1. React制作吸顶功能总结

    总结一下最近用react写项目时,遇到的一些坑,恩,真的还蛮坑的,主要是设置状态的时候特别不好控制,下面我们一起来看下,这里自己做了几个demo,分别看下, 主页面代码如下: class Head e ...

  2. react.js中实现tab吸顶效果问题

    在react项目开发中有一个需求是,页面滚动到tab所在位置时,tab要固定在顶部. 实现的思路其实很简单,就是判断当滚动距离scrollTop大于tab距离页面顶部距离offsetTop时,将tab ...

  3. [RN] React Native 中使用 stickyHeaderIndices 实现 ScrollView 的吸顶效果

    React Native中,ScrollView组件可以使用 stickyHeaderIndices 轻松实现 sticky 效果. 例如下面代码中: <ScrollView showsVert ...

  4. [RN] React Native 头部 滑动吸顶效果的实现

    React Native 头部 滑动吸顶效果的实现 效果如下图所示: 实现方法: 一.吸顶组件封装 StickyHeader .js import * as React from 'react'; i ...

  5. 吸顶大法 -- UWP中的工具栏吸顶的实现方式之一

    如果一个页面中有很长的列表/内容,很多应用都会在用户向下滚动时隐藏页面的头,给用户留出更多的阅读空间,同时提供一个方便的吸顶工具栏,比如淘宝中的店铺页面. 下面是一个比较简单的实现,如果有同学有更好的 ...

  6. status bar、navigationBar、tableView吸顶view设置

    1. 隐藏navigationBar self.navigationController.navigationBar.hidden = YES; 2. status bar设置 -(void)view ...

  7. collectionview cell吸顶效果

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Hiragino Sans GB"; color: #cf8724 } ...

  8. 原生js实现吸顶导航和回到顶部特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. ECSTORE导航吸顶功能

    ecstore导航吸顶功能,在导航父元素中加入id,如: <div id="mainNav1"></div> 在footer.html中添加以下js代码: ...

随机推荐

  1. C# WPF后台动态添加控件(经典)

    概述 在Winform中从后台添加控件相对比较容易,但是在WPF中,我们知道界面是通过XAML编写的,如何把后台写好的控件动态添加到前台呢?本节举例介绍这个问题. 这里要用到UniformGrid布局 ...

  2. 637. Average of Levels in Binary Tree - LeetCode

    Question 637. Average of Levels in Binary Tree Solution 思路:定义一个map,层数作为key,value保存每层的元素个数和所有元素的和,遍历这 ...

  3. Vue2-组件通讯传值

    Vue2组件通讯传值 方法 Slot插槽--父向子内容分发,子组件只读 mixin混入--定义公共变量或方法,mixin数据不共享,组件中mixin实例互不影响 provide+inject--依赖注 ...

  4. FTPClient处理中文乱码问题,实测通过了

    使用FTPClient 操作FTP时,遇到路径或文件名中文乱码问题:   其中的一种处理方式:   在new FTPClient()后,可以设置编码, ftpClient=new FTPClient( ...

  5. Linux系统安装ActiveMQ

    下载安装包 https://activemq.apache.org/components/classic/download/ 上传至服务器并解压 [root@localhost activemq]# ...

  6. 测试平台系列(97) 完善执行case部分

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们讨论了怎么结束一个 ...

  7. 技术分享 | 一步一步学测试平台开发-Vue restful请求

    本文节选自霍格沃兹测试学院内部教材 一般在构建应用时需要访问后端的 API 接口获取后端数据并展示.做这件事的方法有很多种(比如 axios,vue-resource,fetch-jsonp),使用 ...

  8. 如何利用 RPA 实现自动化获客?

    大家好,我是二哥.前高级技术专家 & 增长黑客,现一枚爱折腾的小小创业者,专注于 RPA & SaaS 软件这块.这次给大家带来如何利用 RPA 实现自动化获客 一.RPA 是什么?难 ...

  9. JS:比较运算符

    比较运算符有如下: 1.== 等于: 值相等 var a = "0"; var b = 1; var c = 0; console.log(a==0); //true consol ...

  10. BUUCTF-N种方法解决

    N种方法解决 这题提供的是一个key.exe 运行一下发现没办法运行,老办法,放到16进制打开看看. 这个data:image/jpg很明显了,base64转图片. 编码完成得到了一张二维码,再将得到 ...