遇到一个小模块需要实现吸顶效果,在此简单总结一下:主要有2种思路:1.通过js代码监控需要吸顶的部分距离顶部的位置来设置固定定位;2.通过css的粘性定位属性来实现。

思路一详解:

1.div初始居普通文档流中

2. 给window添加scroll事件(可事件节流),获取div的offset的top值,滚动时scrollTop值和top比较,当到达top时给div添加一个fixed的class使其固定

3. 向上滚动时当到达div初始top时则删除fixed的class,此时div又回到普通文档流中

4. fixed样式非IE6浏览器使用position:fixed,IE6使用position:absolute和IE expression

代码实现:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>吸顶测试</title>
    <style>
        .top{
            height: 1000px;
            background-color: salmon;
        }
        .bottom{
            height: 1000px;
            background-color: seagreen;
        }
        #xidTop {
            width: 100%;
            height: 50px;
            background: skyblue;
        }
    </style>

    <script>
        window.onload = function () {
            var oDiv = document.getElementById('xidTop');
            var divT = oDiv.offsetTop;

            window.onscroll = function () {
                // 获取当前页面的滚动条纵坐标位置 (依次为火狐谷歌、safari、IE678)
                var scrollT = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
                if (scrollT >= divT) {
                    if (window.navigator.userAgent.indexOf('MSIE 6.0') != -1) {
                        // 兼容IE6代码
                        oDiv.style.position = 'absolute';
                        oDiv.style.top = scrollT + 'px';
                        oDiv.style.left = 0 + 'px';
                    } else {
                        // 正常浏览器代码
                        oDiv.style.position = 'fixed';
                        oDiv.style.top = 0;
                        oDiv.style.left = 0;
                    }
                } else
                    oDiv.style.position = '';
            }
        }
    </script>
</head>
<body>
    <div>
        <div class="top"></div>
        <div id="xidTop">吸顶:主要实现当位置将要超过div初始top时,让其置顶。</div>
        <div class="bottom"></div>
    </div>
</body>
</html>

思路二详解:

使用 position:sticky 实现

1、粘性定位是什么?

粘性定位 sticky 相当于相对定位 relative 和固定定位 fixed 的结合;在页面元素滚动过程中,某个元素距离其父元素的距离达到 sticky 粘性定位的要求时;元素的相对定位 relative 效果变成固定定位 fixed 的效果。

MDN 传送门

2、如何使用?

使用条件:

  1. 父元素不能 overflow:hidden 或者 overflow:auto 属性
  2. 必须指定 top、bottom、left、right 4 个值之一,否则只会处于相对定位
  3. 父元素的高度不能低于 sticky 元素的高度
  4. sticky 元素仅在其父元素内生效

在需要滚动吸顶的元素加上以下样式便可以实现这个效果:

.sticky {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
}
复制代码

3、这个属性好用吗?

我们先看下在 Can I use 中看看这个属性的兼容性:

Android 2次吸顶效果_html

可以看出这个属性的兼容性并不是很好,因为这个 API 还只是实验性的属性。不过这个 API 在 IOS 系统的兼容性还是比较好的。

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .main{
            position: relative;
        }
        .bottom{
            width:100%;
            height: 1000px;
            background-color: yellow;
        }
        .head{
            position: sticky;
            top: 110px;
            width: 100%;
            height: 50px;
            background-color: #2aabd2;
        }
        .top{
            height: 1000px;
            width:100%;
            background-color: red;
        }
    </style>
</head>
<body>
    <div class="main">
        <div class="top"></div>
        <div class="head">
            吸顶部分
        </div>
        <div class="bottom"></div>
    </div>

</body>
</html>

总结:

方式一

优点:避免兼容问题

缺点:高频触发引起的性能问题(可以通过防抖来优化一下下)

方式二:

缺点:新属性属于实验性阶段,兼容问题

优点:代码比较简洁(非要说的话)