做有态度的前端团队

网易FEG前端团队

sticky解决粘性交互在微信的问题

前言

粘性交互 指的是某个模块在页面滚动到指定位置时脱离页面不再顺页面滚动而滚动,而是处于屏幕某一固定位置,变成fixed状态,粘着屏幕某一边缘。这种交互经常用到一些导航,比如《大话西游》手游移动官网,效果请看下面动图示意:

dhxy.gif

这种交互的主要逻辑是:导航模块默认是普通流体布局,然后监听window的scroll事件,当页面滚动到导航模块的位置时把导航改成position:fixed状态并调整模块的显示位置即可。在大部分浏览器没什么问题,但是微信对scroll这高频事件做了处理,即使你绑定了scroll事件,在滑动屏幕时也要等页面滚动完后才会执行。所以在微信下这种粘性交互是不流畅的:

或者扫码体验:

dhxy.png

之前在做dhxy时有纠结过这个问题,后来其它项目也遇到,一直没找到方法解决。昨晚在微信浏览某个网站时,页面滚动到底部评论时发现有类似的交互,但是人家是很流畅的,顿时看到希望,通过研究别人的写法发现了position的另一个属性值sticky,css3新增的好东西!

具体实现

sticky写法很简单,但是因为是新属性值,前缀是少不了的:

.sticky {
    position: -webkit-sticky;
    position: -moz-sticky;
    position: -ms-sticky;
    position: -o-sticky;
    position: sticky;
    top: 15px;
} 

元素一开始以position:relative表现,但当用户滚动到距离top 15px时,元素就会变成position:fixed
看起来很好用啊,有了它实现粘性交互再也不用监听scroll了!但事实不是这样的。。。
新东西要先了解下兼容性:

sticky.png

很不乐观,chrome要56版本才默认支持,安卓更是惨~ 但自然有这个好东西,我们就不能因为兼容不好而弃用,最起码它能解决在ios微信的问题,所以结合监听scroll事件,我们来实现一个兼容写法:

核心css,其它前缀按需自行补上:

.nav{
    top: 0;
    left: 0;
    position:-webkit-sticky;
    position:sticky;
}
.nav-fixed{
    position: fixed;
}

核心js:

function isSupportSticky() {//检测是否支持sticky
    var prefixTestList = ['', '-webkit-', '-ms-', '-moz-', '-o-'];
    var stickyText = '';
    for (var i = 0; i < prefixTestList.length; i++ ) {
        stickyText += 'position:' + prefixTestList[i] + 'sticky;';
    }
    // 创建一个dom来检查
    var div = document.createElement('div');
    div.style.cssText = stickyText;
    document.body.appendChild(div);
    var isSupport = /sticky/i.test(window.getComputedStyle(div).position);
    document.body.removeChild(div);
    div = null;
    return isSupport;
}
var isSupportSticky = isSupportSticky();
var $ptxt = $('#Jp');
$ptxt.html('你的浏览器是否支持sticky:'+isSupportSticky);

var fixBottomBar = function(){//不支持的情况
    var $win = $(window),
        $fixtopbar = $('#Jnav'),
        topbar_top = $fixtopbar.offset().top,
        win_top = $win.scrollTop();
    addCla();
    $win.bind('scroll', addCla);
    function addCla(){
        win_top = $win.scrollTop();
        if(win_top > topbar_top){
            $fixtopbar.addClass('nav-fixed');
            !isSupportSticky && $ptxt.addClass('h1-fixed');
        }else{
            $fixtopbar.removeClass('nav-fixed');
          !isSupportSticky && $ptxt.removeClass('h1-fixed');
        }
    }
}
!isSupportSticky && fixBottomBar();

点击查看demo>>

或者扫码体验:

sticky-ewm.png

最后

上面的方案解决了ios下微信的粘性交互问题,但是安卓下不支持sticky,所以还是需要借助scroll来实现,故还是存在滚动停止后粘性模块跳动的问题。

手机阅读请扫描下方二维码:

已有 2 条评论

  1. 张33

    ali-53.gif 牛鼻

添加新评论

ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif