一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

js中滚动定位在移动端的详解

时间:2015-10-05 编辑:简简单单 来源:一聚教程网

前言

什么是滚动定位,我认为是指滚动行为触发的某些定位展现就是滚动定们,比如觉见的一些nav,在默认的时候是显示在页面某个区域,而当滚动到这个区域的时候该元素会"吸附"在浏览器上。

这种技术大量的应用于我们身边,比如jd的商品介绍页里的内容导航,点击查看

实现的思路

一般为判断页面目标元素距离顶部的距离(offset+top),绑定滚动事件,当滚动条距离顶部距离(scroll_top)大于等于(offset_top)时让目标元素处于fixed定位即可实现。代码如:

var $elem = $('.test').eq(0);
var offset_top = $elem.offset().top;
var $window = $(window);
$window.on('scroll resize', function(){
    if($window.scrollTop() >= offset_top){
        $elem.addClass('fixed');
    } else {
        $elem.removeClass('fixed');
    }
}).trigger('scroll');

 

 

需要注意的是,你得明白你这个滚动定位目标元素是否会存在滚动超出底边问题,比如上面jd的页面,当目标导航滚动超出内容的区域,则滚动定位导致消失。比如 这个页面 当你把浏览器窗口调"低"时滚动页面到底部,你会发现滚动定位的元素"跑偏"了,这就是超出底边了,当然你会不会问谁这么奇葩的去这么"玩"啊,但我想说的是既然做这个就尽量做好~

移动端的问题

就上面的demo在移动端的体验不佳额,因为移动端有个滚动的缓冲,如:

 

 

本来我想做个scrollEvent的hack,就是在手指触摸屏幕开始就setInterval下这个回调,以来模拟scroll,但就demo的情况看是没有行通,发现只要在手指触摸屏幕开始到手指离开屏幕的期间居然不触发scroll,就连setInterval也会暂停,看来行不通了。

解决移动端的体验问题

就在刚刚无意期间浏览了jd的一个商品页,发现他的滚动定位元素在移动端体验相当完美,于是我就研究下吧,看他的源码里有:


...
this.isUseSticky = this.supportSticky();
...
ItemDet.prototype.supportSticky = function () {
    var t;
    var n = '-webkit-sticky';
    var e = document.createElement('i');
    e.style.position = n;
    t = e.style.position;
    e = null;
    return t === n;
};
...
if (!this.isUseSticky) {
    this.detTabH = $('#detailBaseLine').offset().top;
    if (st > this.detTabH) {
        if (!this.detTabFloatShow) {
            $('#detailTab').addClass('mod_tab_fixed');
        }
        this.detTabFloatShow = true;
    }
    else {
        if (this.detTabFloatShow) {
            $('#detailTab').removeClass('mod_tab_fixed');
        }
        this.detTabFloatShow = false;
    }
}
...
看代码意思是判断是否兼容sticky,然后这是什么鬼?于是查手册,有个惊奇的发现:

sticky: 对象在常态时遵循常规流。它就像是 relative 和 fixed 的合体,当在屏幕中时按常规流排版,当卷动到屏幕外时则表现如fixed。该属性的表现是现实中你见到的吸附效果。(CSS3)

语法:

position:static | relative | absolute | fixed | center | page | sticky
默认值:static
适用于:除 <' display '> 属性定义为「table-column-group | table-column」之外的所有元素
继承性:无
动画性:否
计算值:指定值
媒体:视觉
取值:

static:
对象遵循常规流。 <' top '>,<' right '>,<' bottom '>,<' left '>等属性不会被应用。
relative:
对象遵循常规流,并且参照自身在常规流中的位置通过 <' top '>,<' right '>,<' bottom '>,<' left '>属性进行偏移时不影响常规流中的任何元素。
absolute:
对象脱离常规流,使用 <' top '>,<' right '>,<' bottom '>,<' left '>等属性进行绝对定位,盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠。
fixed:
对象脱离常规流,使用 <' top '>,<' right '>,<' bottom '>,<' left '>等属性以窗口为参考点进行定位,当出现滚动条时,对象不会随着滚动。
center:
对象脱离常规流,使用 <' top '>,<' right '>,<' bottom '>,<' left '>等属性指定盒子的位置或尺寸大小。盒子在其包含容器垂直水平居中。盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠。(CSS3)
page:
盒子的位置计算参照「absolute」。盒子在分页媒体或者区域块内,盒子的包含块始终是初始包含块,否则取决于每个「absolute」模式。(CSS3)
sticky:
对象在常态时遵循常规流。它就像是「relative」和「fixed」的合体,当在屏幕中时按常规流排版,当卷动到屏幕外时则表现如「fixed」。该属性的表现是现实中你见到的吸附效果。(CSS3)
* CSS3新增属性可能存在描述错误及变更,仅供参考,持续更新
说明:
检索对象的定位方式。
当 <' position '> 的值为非「static」时,其层叠级别通过 <' z-index '> 属性定义。
绝对定位的元素,在 <' top '>,<' right '>,<' bottom '>,<' left '>属性未设置时,会紧随在其前面的兄弟元素之后,但在位置上不影响常规流中的任何元素。用这个特性你或许会干这样的事:demo
对应的脚本特性为position。


然后移动端也可以使用jd的思路,如果支持css3的sticky则使用她,否则用js兼容。

热门栏目