文档章节

前端技术之导航栏浮动最佳实践

hosser
 hosser
发布于 2016/05/17 14:04
字数 1319
阅读 168
收藏 3

前端技术之导航栏浮动最佳实践技术

maybe yes 发表于2015-05-29 00:28

原文链接 : http://blog.lmlphp.com/archives/120/The_floating_navigation_bar_of_front-end_technology_the_best_practices 来自 : LMLPHP后院

关于网页的导航菜单,特别是后台,最古老的做法就是使用 FrameSet。到现在 FrameSet 的这种做法已经过时,并且会带来很多安全问题。于是很多网站在前台都使用浮动的方式来解决这个问题,当页面向上滚动时,到了一定的位置,DIV 导航栏会固定住,这样用户在页面任何位置都能看到重要的导航区域。另外有一种做法用户体验也比较好,比如在腾讯网,当用户稍微向上滚动的时候会出现横向的导航栏,向下滚动导航栏不会出现,这样用户也能很方便的找到导航栏,只是很多人不知道,或者不习惯这样的方式。

我开始在做 LMLPHP 官方网站的文档的时候,也遇到了这样的问题,如何用更好的方式来展示左侧菜单导航区域。LMLPHP 官方文档的做法是计算导航左侧和右侧主体内容的高度,结合浏览器窗口可见区域 viewport 的高度,最后得出左侧 DIV 的最佳高度,采用悬停展示滚动条(如果菜单被展开,高度超出范围)的方式和页面向下滚动固定左侧导航的方式来提升用户体验。这样的做法还算能够接受,唯一的不好就是会鼠标悬停时会出现滚动条,并且高度计算很难做到合适,兼容性比较麻烦,为了兼容大部分浏览器也是花费了很大的精力,偶尔会发现导航消失的问题。

前段时间在逛 Facebook 的动态的时候,发现他们做的很好。FaceBook 的左侧内容区域的做法是随着页面运动的,左侧导航区域的上下两端都会根据相对右侧主体内容的位置来判断是否应该固定,当顶部内容不够,向上滚动时则固定,底部内容不够,向下滚动时则固定,固定的位置范围和右侧主体内容的高度范围一致。于是将本博客右侧也做了相同的改动,由于精力和能力都不够,暂时是根据改变 Margin-Top 来实现的,或许通过改变 position 为 fixed 效果会更好,除 FireFox 外的浏览器都会出现滚动时不够稳定,会有轻微的颤抖,目前测试支持 IE6 及以上浏览器、Firefox、Chrome。在测试的过程中,发现本博客在 IE6 中样式出现问题,有图片的列表页内容被图片撑坏了,发现 IE6 是不支持 max-height 和 max-width 属性的。看了同行的博客 IE6 访问直接 403 ,并显示 Fuck IE 6,看最近几个月的访问统计,IE6 的流量几乎没有,Window 7 占据了一大半的市场份额。

下面给出具体实现技术上的部分 JavaScript 代码,代码来自 LMLJS 框架,需要的朋友可以在 LMLJS 上获取,目前代码没有合到主分支,在 develop 分支上。

计算元素左上角相对页面顶部的距离,代码如下:

<script>
function getElementOffsetTop(element){
    var actualTop = element.offsetTop
        ,offsetParentElement = element.offsetParent;
    if( offsetParentElement == null && element.parentNode ){
        /* when style display is none */
        var parentNode = element.parentNode;
        while( offsetParentElement == null ){
            offsetParentElement = parentNode.offsetParent;
            parentNode = parentNode.parentNode;
            if( !parentNode ){
                break;
            }
        }
    }
    while ( offsetParentElement !== null /* document.body */ ){
        actualTop += (offsetParentElement.offsetTop+offsetParentElement.clientTop);
        offsetParentElement = offsetParentElement.offsetParent;
    }
    return actualTop;
}
</script>

计算页面当前被滚动后页面隐藏部分的高度,代码如下:

<script>
function getPageScrollOffset() {
    var doc = document, w = window;
    var x, y, docEl;

    if ( typeof w.pageYOffset === 'number' ) {
        x = w.pageXOffset;
        y = w.pageYOffset;
    } else {
        docEl = (doc.compatMode && doc.compatMode === 'CSS1Compat') ?
            doc.documentElement : doc.body;
        x = docEl.scrollLeft;
        y = docEl.scrollTop;
    }
    return {x : x, y : y};
}
</script>

计算当前窗口可见区域大小,代码如下:

<script>
function getWindowViewport() {
    var doc = document, w = window;
    var docEl = (doc.compatMode && doc.compatMode === 'CSS1Compat') ?
            doc.documentElement: doc.body;

    var width = docEl.clientWidth;
    var height = docEl.clientHeight;

    if ( w.innerWidth && width > w.innerWidth ) {
        width = w.innerWidth;
        height = w.innerHeight;
    }

    return {width : width, height : height};
}
</script>

除去上面的代码提供的功能外,剩下的就是逻辑上和一些细节上的东西。比如我们不能为了节省性能,没有在每次滚动触发的时候计算相对主体 DIV 区域的高度,因为页面的内容可能在滚动的时候会发生变化,所以必须每次都得重新计算窗口大小和相对滚动范围的高度;当然,如果站点的前端 JS 代码够牛逼,模块之间的变化能够时刻发出通知,也可以不必这样做了。

这次,在做这个功能的时候,发现通用的获取 CSS 的方法(如:window.getComputedStyle 和 element.currentStyle)并不能很好的获取元素的高度属性。比如在 IE 8,获取到的高度值是 auto,而通过元素的 offsetHeight 属性是可以的,这也或许就是为什么 JQuery 会专门有个 height() 和 width() 方法了。

阅(367)评(0)查看评论

本文转载自:http://blog.lmlphp.com/archives/120/The_floating_navigation_bar_of_front-end_technology_the_best_...

hosser
粉丝 192
博文 78
码字总数 4614
作品 3
徐汇
私信 提问
前端重构范式之 float layout

本文由 Rhyme、Captain 发表在 ScalaCool 团队博客。 如果让我用一句话来总结浮动布局,就是浮动布局是一种排队的艺术。你可以向左排队、向右排队,关键在于你如何去组织他们。如果你去看的属...

ScalaCool
2018/08/13
0
0
CSS——把“可以动的盒子”更优雅地展示:③ 常用的“布局”

前言: 拿到一张设计稿,我们首要的就是从宏观上考虑这整个页面的“布局”。随着前端技术的不断更替,以前很多老的布局方式现在也慢慢淡化了,那哪些是我们最基本最常用的布局方式呢? 本篇给...

itsOli
05/09
0
0
CSS 布局:40个教程、技巧、例子和最佳实践

前言: 布局是WEB开发一个重要的课题,进入XHTML/CSS后,使用TABLE布局的方式逐渐淡出,CSS布局以众多优点成为主流,本文将介绍40个基于CSS的web布局的资源和教程。文章的出处在http://www....

望志东
2012/05/03
244
0
CSS 布局:40个教程、技巧、例子和最佳实践

前言: 布局是WEB开发一个重要的课题,进入XHTML/CSS后,使用TABLE布局的方式逐渐淡出,CSS布局以众多优点成为主流,本文将介绍40个基于CSS的web布局的资源和教程。文章的出处在http://www....

aoniao
2012/03/19
12.8K
7
一些有趣的 CSS 魔法和布局(上)

前言 布局和样式,是每个前端的必修课。在日常的工作中,也会碰到一些特定场景的布局需求,配合上样式,就能实现一些神奇的效果。我搜罗了一些日常开发中遇到的布局,以及浏览各大网站时碰巧...

Micherwa
03/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

总结:TCP/IP协议

一、介绍 TCP协议属于OSI七层模型中的传输层协议,提供处于网络连接中的两台计算机之间的数据 传输。   在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议...

浮躁的码农
19分钟前
2
0
一言不合就删库跑路?万名贡献者和阿里巴巴开源的二三事

9 月 27 日云栖大会,阿里巴巴宣布贾扬清担任开源技术委员会负责人。 有人问:开源是为了什么? 从个人视角看,可以证明自己的专业能力,获得行业认可; 从企业视角看,可以建立技术影响力,...

大涛学弟
30分钟前
4
0
JAVA编程注意事项(性能篇)

1. 尽量在合适的场合使用单例 使用单例可以缩短加载的时间,提高加载的效率,单例主要适用于以下三个方面: 第一,控制资源的使用,通过线程同步来控制资源的并发访问; 第二,控制实例的产生...

你好夜故事
31分钟前
5
0
List 前端 AngularJS JS 对IP排序

数据格式 $scope.dataList=[ {"ip":"192.168.10.10", "port":"8080",...}, { "ip":"192.168.10.12", "port":"8080",... } ,.....] 调用 $scope.ipSortForward($scope.dataList,"ip") 核心代码......

最菜最菜之小菜鸟
31分钟前
4
0
浅析Cassandra LeveledCompactionStrategy

前言 Cassandra是基于LSM架构的分布式数据库。LSM中有一个很重要的过程,就是压缩(Compaction)。默认的压缩策略是SizeTieredCompactionStrategy,今天主要说一下另一种压缩策略LeveledComp...

阿里云官方博客
36分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部