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 条评论
登录 后参与评论

相关文章

来自专栏james大数据架构

Android如何制作漂亮的自适布局的键盘

  最近做了个自定义键盘,但面对不同分辨率的机型其中数字键盘不能根据界面大小自已铺满,但又不能每种机型都做一套吧,所以要做成自适应,那这里主讲思路。   这里最...

227100
来自专栏CRPER折腾记

Vue 折腾记 - (6) 写一个不大靠谱的backToTop组件

返回顶部这个功能用jq实现,好容易实现,一个animate配合scrollTo就搞定了

10310
来自专栏吾爱乐享

php学习之html的标签属性(三)

14220
来自专栏HT

绘制SVG内容到Canvas的HTML5应用

SVG与Canvas是HTML5上绘制图形应用的两种完全不同模式的技术,两种绘制图形方式各有优缺点,但两者并非水火不容,尤其是SVG内容可直接绘制在Canvas...

31470
来自专栏小狼的世界

IE6下实现Width:auto

看了这个题目,很多人肯定觉得有点太老土了,IE6都快到末路了,不过这个方法确实非常经典,我觉得很有必要记下一笔。

8920
来自专栏C/C++基础

CSS3制作3D水晶糖果按钮

本人仿照20个漂亮 CSS3 按钮效果及优秀的制作教程中的BonBon(Candy)Button实现了其棒棒糖果按钮,如下图所示:

12710
来自专栏偏前端工程师的驿站

CSS魔法堂:Transition就这么好玩

 以前说起前端动画必须使用JS,而CSS3为我们带来transition和@keyframes,让我们可以以更简单(声明式代替命令式)和更高效的方式实现UI状态...

12830
来自专栏肖蕾的博客

解决安卓中XML文件声明高度 宽度无效的问题

11630
来自专栏HTML5学堂

关于其他选择器以及选择器优先级详解

上周我们讲解了页面浮动之后产生的问题,以及针对这个问题所采取的措施——清浮动,同时罗列了好几种清浮动的方法。那本周我们再来继续上次给大家分享的如何找标签的问题,...

29880
来自专栏hightopo

绘制SVG内容到Canvas的HTML5应用

25830

扫码关注云+社区

领取腾讯云代金券