滚动悬浮固定功能非常实用,特别是网站导航栏,以及文章目录等,用户体验超级棒。
网上有很多方法可以实现,不过大部分比较复杂(当然可配置的功能也很多),而且同时包含了 js+css 文件。但是,我们的需求往往很简单,希望尽量轻量。比较了数个方法后,觉得SF上的一个方法非常好,经过一番修改,更加灵活、好用了。原文网址放在文章最后。主要分为两部分代码,HTML 和 JS 部分。
HTML代码
<div style="height: 200px; background: #999"></div> <!-- 固定元素悬浮后,原来所在的位置会被空缺(height变成0), 导致页面闪跳且计算不准,所以必须设置一个确定高度的div框住 --> <div style="height:300px;"> <div class="fixed" style="height: 300px; background: green; text-align: center;">滚动悬浮块</div> </div> <div style="height:400px;background: #999"></div> <div class="bottom" style="height: 500px; background: red; text-align: center;">结束滚动块</div> <div style="height:800px; background: #999"></div>
HTML代码中主要定义了两个DIV,它们 class 分别为 fixed 和 bottom。fixed是滚动的时候要悬浮固定块,滚动到 bottom 时停止浮动。
JS代码
<script type="text/javascript"> $(function() { var fix = $('.fixed'); //滚动悬浮块 var end = $('.bottom'); //滚动到这个元素后结束固定 var fixTop = fix.offset().top, //滚动悬浮块与顶部的距离 fixHeight = fix.height(); //滚动悬浮块高度 var endTop, miss; //结束元素与顶部的距离 $(window).scroll(function() { //页面与顶部高度 var docTop = Math.max(document.body.scrollTop, document.documentElement.scrollTop); //如果有结束块 if (end.length > 0) { endTop = end.offset().top; miss = endTop - docTop - fixHeight; } if (fixTop < docTop) { fix.css({'position': 'fixed'}); if ((end.length > 0) && (endTop < (docTop + fixHeight))) { fix.css({top: miss}); //滚动悬浮块滑到结束块上时,top值为负,即慢慢隐藏出浏览器 } else{ fix.css({top: 0}); //滚动悬浮块未到结束块上时,top为0 } } else { fix.css({'position': 'static'}); } }) }); </script>
如果不需要结束块,直接不设置bottom,或者删掉这个class就可以了。
如果需要更加复杂的样式,可以把:
fix.css({'position': 'fixed'}); fix.css({'position': 'static'});
分别换成:
fix.addClass('scrollfix'); fix.removeClass('scrollfix');
其中,scrollfix 样式需要在 CSS 中定义。
原理分析
如下,蓝色方框是浏览器的范围,灰色是页面的高度,绿色是要悬浮固定块,滑动到结束块的时候停止悬浮。
滑动鼠标时,如果悬浮固定块与页顶距离 fixTop 大于页顶与浏览器顶部距离 docTop ,不悬浮固定。也就是执行最后一个 else 的内容,fix 的 position 为 static。如下图。
如果滚动固定方块与页顶距离 fixTop 小于页顶与浏览器顶部距离 docTop 时,开始悬浮固定。即 fix 的 position 为 fixed,而且固定块的 top 为 0,即保持固定在浏览器顶端。如下图。
悬浮过程中,如果到达结束块,而且结束块与页顶距离 endTop 小于 docTop+fixHeight,那么固定块的 top 就是他们之间的差,这个差是一个负值,所以悬浮块多余部分会向上超出浏览器,那部分看不到。如果继续滑动鼠标,固定块就会慢慢退出浏览器。如下。
了解了它的工作原理,就很容易把这部分代码嵌入到其他功能之中,实现更加复杂的应用。
参考资料:
- segmentfault,jQuery滚动页面当DIV到达顶部时固定在顶部,到底部是固定在底部