今天获取到一个需求,其实就是吸顶的需求,页面下滑,某一块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. WPF全局异常处理

    private void RegisterEvents() { //Task线程内未捕获异常处理事件 TaskScheduler.UnobservedTaskException += TaskSche ...

  2. 【NodeJS】替换模糊查询字符里包含的正则关键字

    问题:正则匹配时字符串中包含了一些特殊字符,导致查询失败 例如,下面的字符包含了( 和 ),这在正则中属于特殊字符 (-)-magnocurarine 正则中的特殊字符如下图 思路: 1.映射查询字符 ...

  3. 个人冲刺(五)——体温上报app(二阶段)

    冲刺任务:完成用户登录和随机验证码功能 loginActivity.java package com.example.helloworld; /** * 纯粹实现登录注册功能,其它功能都被注释掉了 * ...

  4. vuex+Es6语法补充-Promise

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,采用 集中式存储管理 单页面的状态管理/多页面状态管理 使用步骤: // 1.导入 import Vuex from 'vuex' // ...

  5. bintree

    Python实现二叉树的建立与遍历 创建(二叉)树节点类 class Node: def __init__(self,data,l=None,r=None): self.val = data self ...

  6. B 树的简单认识

    理解 B 树的概念 B 树是一种自平衡的查找树,能够保持数据有序.这种数据结构能够让查找数据.顺序访问.插入数据及删除数据的动作,都能在对数时间内完成. 同一般的二叉查找树不同,B 树是一棵多路平衡查 ...

  7. 【Spring】AOP实现原理(二):Advisor获取

    @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解可以用来开启AOP,那么就从@EnableAspectJAutoProxy入手学习一下Spring A ...

  8. spring boot用ide新建项目遇到的restcontroller不能导入的问题

    才开始学习spring boot,第一个程序helloworld就碰到@RestController和@RequestMapping(/hello)的注解都会报错的问题. 我个人的解决方法: 1.sp ...

  9. idea运行Tomcat出现 Address localhost:8080 is already in useAddress localhost:8080 is already in use

    使用IDEA运行 tomcat时出现 Address localhost:8080 is already in use,就很奇怪,我明明只有这一个程序呀,怎么还会被占用.后来想想可能就是被其他进程占用 ...

  10. Maven的安装 和idea的配置

    Maven的安装 和idea的配置 工欲善其事 必先利其器 1 下载maven 官网 下滑 找到Files tar.gz 是linux系统的 .zip window系统 2 maven安装和配置到环境 ...