这些天做一个网页,发现了js和css一些有趣的问题。
1.不同的标准,不同的效果
首先是css,原来一直用ie7和ff的浏览器,网页的效果也一直和想象中一样。然而新装系统后,ie的版本降为6的时候,问题出现了。
在网页中一个div元素的css如下:
.i-top-3btn-1{
background-color:#e8f2fc;
}
.i-top-3btn-1:hover{
background-color:#990000;
}
这两个类可以控制这个层在鼠标经过时显示不同的背景色,要达到这个效果当然也可以用js在div上做事件来实现,但是使用css中的伪类“:hover”则减轻了不少的编码量,也让代码看起来很清秀。
这个“:hover”伪类,在ie7和ff下正常的表现出了鼠标经过变化底色的效果,而在ie6下却没有反应。经过一番资料查找,才发现,ie7和ff实现的是css2标准,而ie6只实现了一部分的css1标准。
在css1中,伪类“:hover”只有“a”标记才能正确表现。而其他标记都不支持“:hover”伪类。在css2中,所有的标记都开始支持“:hover”这个伪类了。
我的项目中,div里本来就应该是一个链接,所以加上“a”标记并不会对我的布局以及效果产生太大的影响,然而如果只是淡出的想让div或其它元素产生背景色变化的话,最好的解决方法可能还是在元素上做事件吧。
2.for的陷阱
早在看js面向对象方式编程的一些书籍的时候,就看到了这样的写法:
for(var i in obj){
alert(i);
}
通过这样的方法,可以准确的获知对象obj的所有成员的名称。这也被称之为js的反射机制。
而这次做项目的时候由于在页面加载时要同时执行大量的函数,所以按照ajax in action 一书中的建议,使用Observer模式变现启动加载的代码:
//首先声明一个数组型变量,把要在启动时加载的函数全部存春在这个数组中。
var __SYS_Startup_Funcs = new Array();
//提供一个方法,让程序员可以把要在启动时加载的函数存放到先前声明的数组里。
function registerStartup(pFunction){
__SYS_Startup_Funcs.push(pFunction);
}
//替换系统的onload函数以达到加载启动的目的。
window.onload = function (){
for(var i in __SYS_Startup_Funcs){
i.call();
}
}
红色的这段代码是郁闷我很久的根源,按照常理,每次循环就从“__SYS_Startup_Funcs”中取出一个函数,并调用这个函数的call方法来执行它。
但是在执行时发生错误:“对象不支持此方法或属性”。
这是人很迷惑,因为call方法是属于Function这个对象的,而每一个函数都是继承自Function的。为什么产生这样的错误呢?
于是开始排错,首先用alert(i)来打印。对话框中显示的正好是我传进去的函数名。于是换另外一种方式alert(typeof(i))来打印。对话框中显示的是“string”。
这次的结果出乎我意料,但是却直接指出了这段代码的错误所在。
在查阅资料后,见到这样一段话:
Javascript 提供了一种特别的循环方式来遍历一个对象的所有用户定义的属性或者一个数组的所有元素。for...in 循环中的循环计数器 是一个字符串,而 不是数字 。它包含了当前属性的名称或者表示当前数组元素的下标。
根据这个特性,我们取出来的并不是集合中的一个元素,而是这个元素的名字!
这样的错误显然是受了c#和java这样面向对象语言的影响。