之前所写的《用js实现智能半固定不随滑动条移动的网页层》一文大致描述了此技术的一些代码和智能化考虑。
此后我又参考了其他一些网站的相关内容,发现可以加上一个对于最近是否有滑动的判断,以减少非滑动时的无谓js运行。所以整个重写了代码,并对代码的运行效率做了修改。
期间,使用FireFox2.0.0.9来浏览,总觉得Javascript脚本运行速度很卡,而用IE6.0就相对顺畅许多,不过在IE6之下会出现浮动层移动后所留下的区域的图片无法顺畅显示的状况(成为背景色,点击该区域或者重新滑动到该区域时才恢复),特别是在定义的运行速度比较快的时候。
最近换用了FireFox 3 Beta 1,明显感觉整个页面的载入(特别是javascript的运行)要迅速许多,而我页面上的浮动层比IE6都要迅速,整个的效果不再是卡了又卡,这一点对于网页所面向的广大不同机器配置和浏览器来说,是一件好事(FireFox自动更新,况且用Firefox的人大多会去更新)。
我更改了代码的运行结构,从原来用setInterval来设置一个自动隔一段时间自动运行的模式,改变为用setTimeout自动在一段时间后调用本身。并且判断:如果此刻进行了移动,则较短时间内进行下次判断;如果此刻没有移动,则较长时间后再次判断。这样可以为用户观看一个位置时节省js运行消耗,不仅为页面中其他内容争取到资源,也为其他网页节省了资源。
在一些配置上也做了更改,首先把每次移动的距离从 interval / 3 改为 interval / 5 ,这样能够增快一点速度,主要也是为了较低配置浏览者的需要,同时也对浏览效果的流畅性有所增强。此外,设置了滑动过程中的更新时间为10ms,非滑动时间的更新时间为100ms。
这也让我对Firefox3充满了兴趣,它如果能够解决原来版本占用过多资源和运行速度较慢的缺点,那么完全可以超越IE乃至Opera。
就最近几天的使用来看,首先在Google Reader里常有的点击一个新闻,过了许久才将其置于顶部的现象彻底消失了,各个方面都明显感觉到速度的提高,相应的各种因为页面分析复杂或脚本运行而造成假死现象也有很大减少。
ZDNet的一篇文章对比了Firefox 2.0.0.9、Firefox 3.0 b 1和IE7的内存占用。测试用电脑有2G内存,分成三种情况:载入5个页面;载入1个页面然后等待5分钟;载入12个页面等待10分钟。其中最后一项的结果是Firefox 2占用103,180KB内存,3.0 b 1占用62,312KB,IE7占用89,756KB。
Firefox3 让我觉得有信心~~
代码如下,使用方法同原来《用js实现智能半固定不随滑动条移动的网页层》一文所说,其中为了和之前的调用模式相继承,所以并没有改变调用函数的声明模式:
var obj;
var initTop;
var topLimit;
var interval;
var nowtop;
function Moving() {
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;
}
}
nowtop = obj.top;
pos = obj.getTop() + topLimit;
if(pos < = initTop)
pos = 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 - Math.round(interval/5);
}
if (Math.abs(interval) <= 1)
obj.top = pos;
if (obj.top != nowtop){
obj.style.top = obj.top + "px";
setTimeout("Moving()", 10);
}
else {
setTimeout("Moving()", 100);
}
}
function initMoving(target, its_initTop, its_topLimit) {
obj = target;
obj.style.position = "absolute";
initTop = its_initTop;
topLimit = its_topLimit;
obj.top = initTop;
Moving();
}