专栏首页程序员的诗和远方Tips-移动端滑动固顶效果(position: sticky)

Tips-移动端滑动固顶效果(position: sticky)

先放个图看看滑动固顶是啥效果:

中间那个 tab 条,平常的时候是固定的,等到页面滑上去的时候,又像 fixed 一样贴在顶部。 position: sticky 就是用来实现这个效果的,元素不脱离文档流,仍然保留高度,所以这个属性真是人畜无害啊,而且效果如丝般润滑,堪比原生。

事实上,很多看起来人畜无害的东西,其背后都有一个大坑。

我们的 html 结构是这样的:

<body ontouchstart="">
    <div class="page-wrapper">
      <div id="contentA" class="content-a">
        A
      </div>
      <div class="sticky-wrap ">
        <ul class="ui-tab-nav ui-border-b frown ">
          <li class="current">推荐</li>
          <li>分类</li>
        </ul>
      </div>
      <div id="contentB" class="content-b">
        B
      </div>
    </div>
</body>

主要的 css 如下:

.sticky-wrap {
  top: 0;
  width: 100%;
  z-index: 999;
}
.sticky-wrap {
  position: relative;
  position: -webkit-sticky;
}
.page-wrapper.sticky .sticky-wrap {
  position: fixed;
}
.content-a {
  height: 200px;
  background-color: #12b7f5;
  color: #fff;
  font-size: 48px;
  text-align: center;
  line-height: 200px;
}
.content-b {
  height: 800px;
  font-size: 48px;
  text-align: center;
  line-height: 200px;
}

这里需要注意几点,这里 sticky-wrap 是我们设置了position: -webkit-sticky;的元素,这个元素的位置比较重要,不是随便放哪都可以实现那个效果的,sticky 效果是按照父元素的高度来的,如果你的父元素高度很小,会出现滑完父元素就不再固顶的奇怪情况。

然后我们设置了 top 值,sticky 的元素必须有 top 或者 bottom 属性,不然不会生效。

除了一些要设置的东西之外,还有一个不能设置的东西。 sticky 元素的父元素或者祖先元素不能含有 overflow:hidden 或者 overflow:auto

基本上小坑就这些,还有一个大坑叫做『只有 iOS 支持这个属性』。

Android 上实现类似效果

这里我们不得不借助 js 和 positon:fixed

添加一段 js:

        var isStopTimer = null;
        var offsetTop = $('.content-a').offset().height;

        //置顶效果
        if ($('.sticky-wrap').css("position").indexOf("-webkit-sticky") == -1) {
            $('.page-wrapper').on('touchend', function() {
                clearInterval(isStopTimer);
                isStopTimer = setInterval(function() {
                    document.body.scrollTop >= offsetTop ? $('.page-wrapper').addClass('sticky') : $('.page-wrapper').removeClass('sticky');
                }, 200)

            });

            $('.page-wrapper').on('touchmove', function() {
                document.body.scrollTop >= offsetTop ? $('.page-wrapper').addClass('sticky') : $('.page-wrapper').removeClass('sticky');
            });
        }

这里通过计算 $('.sticky-wrap').css("position").indexOf("-webkit-sticky") 是否有效来判断浏览器是否支持 sticky 属性,然后通过监听 touchmove 和 touchend 事件,在合适的时候添加一个叫 sticky 的类,这个类设置带了些样式:

.page-wrapper.sticky .sticky-wrap {
  position: fixed;
}

在需要固顶的时候我们将元素的 positon 改为 fixed,但是这里又有个坑,设置元素为 fixed 的时候,相应元素是脱离文档流的,也就是没有高度了,仔细看滑动的时候,底下的元素有一个跳动。

为了解决这个跳动,我们可以让原本在下面那个元素加点高度,然后和 sticky 元素重合,为了以后改动页面的时候不影响这个逻辑,用 js 去算高度会比较好。

加入如下代码:

        var tabContentTop = $('.ui-tab-nav').offset().height;
        var orgPaddingTop = parseInt($('.content-b').css('padding-top'));
        $('.content-b').css('padding-top', tabContentTop+orgPaddingTop);
        $('.sticky-wrap').css('margin-bottom', -tabContentTop);

这里用 padding-top 来给 content-b 增加高度,给 sticky-wrap 添加负的 margin-bottom 值来让 content-b 上来和 sticky-wrap 重合。未免覆盖原来 content-b 的 padding-top 值,最好获取一下再加,记得用 parseInt 转一下。

到这里基本坑都踩完了,虽然 Android 效果没有 iOS 那么丝滑舒服,也勉强能接受了。

最后说下调试 sticky 效果,既然是 iOS 才支持的东西,首先你要有 safari,但是平常打开是没用的,要在开发菜单那里选择 进入响应式设计模式

源码地址: https://github.com/bob-chen/demos/blob/master/sticky/html/index.html

结语

好久没发文章了,最近实在太忙,不知道是不是加班多了,还生病了,身体是革命的本钱啊,2017 祝大家身体健康。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 20180728_ARTS_week05

    这题有点犯难,上面是 Discuss 中的一个解法,看了之后挺好理解的,要找回环字符串,就从 a 和 aa 一阶和二阶这两种形式往两边找,感觉特别巧妙。

    Bob.Chen
  • Python安装mysqldb模块

    今天在阿里云一台新的服务器部署程序后台,发现上面的python缺少MySQLDB 模块,记录安装过程。 因为用的django框架,运行 python manag...

    Bob.Chen
  • 设置 git/npm/bower/pip/gem镜像或代理

    有时候因为墙或者速度的原因使用git/npm/bower/pip/gem等工具的时候需要设置镜像或者代理,记录一下,不用到处找。 git 设置: $ ...

    Bob.Chen
  • position:sticky的兼容性尝试

    开篇 笔者刚刚结束淘宝的工作,现在加入了一家有青春活力的垂直电商公司,正对着阿里巴巴的西溪园区,最近一直在熟悉新的工作环境和规范,因此博客有好些时间没有更新了,...

    欲休
  • 探究 position-sticky 失效问题

    CSS 的 position 值中,有一个非常有用的值 -- position: sticky,通常会被用于各种吸顶,吸底,吸边的效果中。

    Sb_Coco
  • 韩国SM上线腾讯音乐,音乐平台在细分领域的发力

    在节前2月1日,腾讯音乐宣布与韩国SM公司达成版权合作,韩国的大量头牌艺人诸如Super Junior、少女时代、EXO、Wonder Girls、TWICE、...

    罗超频道
  • 【腾讯云的1001种玩法】在腾讯云上创建您的 SQL Server 故障转移集群(5)

    https://cloud.tencent.com/document/product/215/18025

    李斯达
  • 音乐产业发展报告

    ?   引言   文化产业是通往大国之路的重要软实力。而作为文化软实力的主要组成部分,音乐产业一直是我国发展比较薄弱的环节。本文首先从音乐产业链分析入手,...

    腾讯研究院
  • 一款全网音乐神器推荐给大家

    突然发现自己很久没有听音乐了,之前对纯音乐和泰勒歌曲喜欢入迷的我,由于工作忙的原因,都很少打开网易云音乐静静品味音乐带来的美感。

    我的小碗汤
  • 宋宝华:那些年你误会的Linux DMA(关于Linux DMA ZONE和API最透彻的一篇)

    互联网、Linux内核书籍上充满了各种关于Linux DMA ZONE和dma_alloc_coherent、dma_map_single等的各种讲解,由于很多...

    Linux阅码场

扫码关注云+社区

领取腾讯云代金券