用js实现智能半固定不随滑动条移动的网页层

对于此技术,又做了新的大幅改进,并对不同浏览器(特别是最新的FireFox3)效果进行了分析,参见文章智能不随滑动条移动的网页层的改进与FireFox3

用过WordPress的K2模板最近版本的人应当都对它那“高级导航条”记忆犹新,除却一些Ajax的高级导航功能外,这导航栏可以固定在屏幕最上方而不随滑动条移动,但是不会超过content而覆盖header。

在一个韩国网站http://www.ggw.or.kr/(yskin查到它是韩国某个地方的妇女交流组织~~),除了主页外的大多数页面的右边都有一个可以浮动的“工具条”,它的特点也是可以固定在页面旁边而不随滑动条移动,同时如果浏览最上面的时候也不会超出范围。

似乎国内也有人用了相应的技术,但是主要还是只实现固定在页面一个位置(多数的用途是显示广告~),这一点本来可以通过对div对象的position定义为fixed来轻松实现,但是遗憾的是IE6对此不支持(K2模板的高级导航栏的滑动功能也会在IE6里失效)。

查询了一下,这种效果在韩国的网站中很常见,也大多是一种模式来实现(代码其实都差不多)。但是在国内似乎还没有相应的介绍。

hyeonseok.com的SmoothMovingLayer里给了相应的代码。不过还需要做一些修改才能让它运行起来更适合作为侧边工具栏。首先我把它一些并不是很需要的设置去掉,然后简化为只对上距离Top进行处理(如果需要,可以同理添加判断左距离Left的处理)。此外,根据实际使用时可能一次性拖动较长距离的情况,这里又加入了一个自动判断的跨越式跳转,具体内容见后文说明。

其javascript部分如下:

function initMoving(target, initTop, topLimit) {
	if (!target)
		return false;   
   	var obj = target;
	obj.initTop = initTop;
	obj.topLimit = topLimit;
	obj.style.position = "absolute";
	obj.top = obj.initTop;   
   	obj.getTop = function() {
		if (typeof(document.documentElement.scrollTop) == "number") {
			return document.documentElement.scrollTop;
		} else if (typeof(window.pageYOffset) == "number") {
			return window.pageYOffset;
		} else {
			return 0;
		}
	}
   	obj.move = setInterval(function() {
		pos = obj.getTop() + topLimit;
		if(pos < obj.initTop)
			pos = obj.initTop;
		interval = obj.top - pos;
		if (interval > 1000) {
			obj.top = pos + 700;
		} else if (interval < -1000) {
			obj.top = pos - 700;
		} else  {
			obj.top = obj.top - interval / 3;
		}
		obj.style.top = obj.top + "px";
	}, 30)
}

可以在给这段代码加上一个


的外框,然后放入页面的head部分。或者单独作为一个js文件,再用下面代码来加入到head部分。

调用的时候,一般是使用类似如下的代码事例:



其中的div(可以换成需要的ID)内可以写各种需要放入的东西,然后调用initMoving()函数时,第一个参数是document.getElementById("***"),其中的***部分写入刚才的ID;第二个参数initTop是该部分离上方的初始距离,最后一个参数 topLimit 是任意情况下该部分离浏览器显示区域顶部的最小距离。

当然,这里我只对该部分离浏览器显示区域顶部的最小距离进行了处理,如果需要,也可以通过修改js代码来实现对显示器区域其他方向的位置固定。

效果可以看我的右边栏。

需要说明的是,当一个div所属的div的position为relative时,这个div会以这个更大的div为参考设置top、left、bottom、right。而如果这个div所属的div的positon为static或者absolute,那么它会以更外面的position为relative的div为参考来设置那四个参数,直至以整个body来设置。这一点需要特别注意。

如果注意的话,可以发现js代码里有一个interval / 3,这里为什么要除以3呢?

javascript延续了java的实现效率较弱的问题,所以速度上不是很好,即使我们对setInterval函数设置一个更短的刷新时间,有时候也会“卡”,造成的效果就是设置的网页层从一个地方跳跃到另一个地方(在IE6里,如果资源不是很充足,甚至会造成背景色的杂乱),而这里并不是直接把网页层直接定位到新地方,而是每一次只让它移动需要移动距离的1/3,这样不仅可以实现越接近越慢的动感效果,而且可以在较长刷新速度下实现比较完美的效果,另外也可以使频繁滑动时的网页层的那种跳动被一个“阻尼”化移动抵消。

(这一点在IE6里实现非常流畅,但是在Firefox2.0.0.9 + 512M内存 + 若干其他进程 下就还是有些迟钝,不知firefox3会如何?)

这种表现出色而速度出色的设计,值得我们学习。

另外,有时候可能直接滑动滑动条很多,或者用Home、End,再或者在这个“智能”工具栏里加入到达最顶、最底功能。这时,需要移动的距离可能是几千、几万甚至几十万像素的移动,依然使用interval / 3的移动就有些迟缓。所以我加入了一个判断,如果移动的距离超过1000px,就自动从距目标位置700px处开始移动。

据网页上所称,该技术可展示于IE6, IE7, FF2, Opera9, Safari3。我只测试了FF和IE6,还算完美。

One Comment:

  1. Pingback: 智能不随滑动条移动的网页层的改进与FireFox3 | 泊客Myheimu

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据