两行代码搞定导航吸顶(position:sticky)

我们在开发页面时 最常见的功能之一 就是导航吸顶 或 tab 吸顶,这两天用react和vue写这个功能时 遇到了个坑
当页面只有一个滚动条时 还好,不会出现什么大坑,可以用原生滚动条监听事件处理,但是用原生的话 就还需要考虑上事件卸载问题,我们使用SPA模式开发,内部页面都是组件,若是不卸载的话 后患无穷。 react中也有合成事件 onScroll 但是不知为何 我这个事件注册后始终无法监听到滚动条位置, 希望有大佬能帮忙解决 。。。
当页面 不止一个滚动条出现时,坑就深了
页面滚动时 我们的导航已经 定位到顶部,但是到下面 还有两个滚动条 一旦滚动条滚动 ,就会触发导航的事件,造成页面混乱。。。。
经过多番考虑,突然发现了救星,那就是position :sticy
css后新增了一个粘性定位:这使 的原本需要js 至少十行的代码功能 可用 css两行实现 (开心到起飞)
下面了解下 这个属性

初识 position:sticky sticky 英文字面意思是粘,粘贴,所以姑且称之为粘性定位。下面就来了解下这个处于实验性的取值的具体功能及实用场景。
这是一个结合了 position:relative 和 position:fixed 两种定位功能于一体的特殊定位,适用于一些特殊场景。
什么是结合两种定位功能于一体呢?
元素先按照普通文档流定位,然后相对于该元素在流中的 flow root(BFC)和 containing
block(最近的块级祖先元素)定位。
而后,元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或
left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同
但是他的兼容性不容乐观
两行代码搞定导航吸顶(position:sticky)
文章图片

IOS 家族(SAFARI && IOS SAFARI)和 Firefox 很早开始就支持 position:sticky 了。而
Chrome53~55 则需要启用实验性网络平台功能才行。其中 webkit 内核的要添加上私有前缀 -webkit-。
举个栗子
运用 position:sticky 实现头部导航栏固定
.container { background: #eee; width: 600px; height: 1000px; margin: 0 auto; }nav { position: -webkit-sticky; position: sticky; top:0; }nav { height: 50px; background: #999; color: #fff; font-size: 30px; line-height: 50px; }.content { margin-top: 30px; background: #ddd; }p { line-height: 40px; font-size: 20px; }

生效规则
  • 须指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
  • 并且 top 和 bottom 同时设置时,top 生效的优先级高,left 和 right 同时设置时,left 的优先级高。
  • 设定为 position:sticky 元素的任意父节点的 overflow 属性必须是 visible,否则 position:sticky 不会生效。这里需要解释一下:
  • 【两行代码搞定导航吸顶(position:sticky)】如果 position:sticky 元素的任意父节点定位设置为 overflow:hidden,则父容器无法进行滚动,所以 position:sticky 元素也不会有滚动然后固定的情况。 如果 position:sticky 元素的任意父节点定位设置为
    position:relative | absolute | fixed,则元素相对父元素进行定位,而不会相对 viewprot 定位。
    达到设定的阀值。这个还算好理解,也就是设定了 position:sticky 的元素表现为 relative 还是 fixed
    是根据元素是否达到设定了的阈值决定的。

    推荐阅读