由于早期外行人的翻译问题,property与attribute都笼统地译作“属性”,这留下了不少隐患。那什么是属性呢?什么是特性呢?特性其实是一种内建的属性,因此它们大多数拥有默认值。举个特例,微软的IE6,IE7就是对于属性与特性的概念非常含糊,可能getAttribute那套东西是人家的,破坏了其原来的COM体系*,因此造成许多问题。群里就讨论过了,在IE6与IE7中如果不reset CSS,页面渲染速度远远不如reset CSS的快,或者说很慢很慢。因为它内部还要能过非常复杂的机制判定那些东西是用户自定义还要CSS本来就有的属性(令我想起IE全局变量的DID问题*及window与window.window的不等问题*,微软是把问题搞复杂的高手!!!)。另一个著名的例子是class与tabindex与for,在IE8之前,要取得其值或设值,都需要用el.className或el.htmlFor,tabindex的情况更为严重些,详见我这一篇博文《tabIndex属性》。但这些都是题外话,那具体如何识别它们呢?看下面实验:
假如现在我们有如下一个段落:
<p ><strong id="aaa">司徒正美</strong></p>
我们把它里面的strong取出来,需要其id属性,不是,是id属性,看,改不了口吧。用javascript修改一下,然后用其outerHTML查看一下,忘了,火狐死活不支持这个特性。我们改用其父元素的innerHTML吧。
<p ><strong id="aaa">司徒正美</strong></p>
var a = document.getElementById("aaa"); a.title ="title" a.setAttribute("title2", "title2") alert(a.parentNode.innerHTML)
var a = document.getElementById("aaa"); a.title ="title" a.title2 = "title2" alert(a.parentNode.innerHTML)
能过观察,IE下内建的特性,如title,id是不带引号的,自定义的属性是带引号的,并且属性与特性是不可转换的,内部已经规定了哪些属性是特性,不能再通过其他方式添加。在标准浏览器下,只要用setAttribute设置的属性皆可以成为特性,只有特性才出现innerHTML的返回字段内。当然本身是内建的那些属性无论用何种方式设置都会出现在innerHTML中。
好了,我们看一下著名的className问题。这个请在IE下测试。
var a = document.getElementById("aaa"); a.className ="test" alert(a.parentNode.innerHTML)
弹出的class的值是不带引号的,说明其是一个内建的特性。
var a = document.getElementById("aaa"); a.setAttribute("className","test") alert(a.parentNode.innerHTML)
注意,上面运行框的页面我已强制运行于IE7模式下。弹出的情况如下图所示:
说明其还十分智能的,能自动影映这两个属性。不过,其实问题在标准浏览器过早地暴露出来了。我建议还不是不要看,已经知道的就算了。
我们在IE8并且是运行于IE8模式下进行如下设置:
var a = document.getElementById("aaa"); a.setAttribute("className","test") a.setAttribute("class","test2") a.className = "test3" alert(a.parentNode.innerHTML)
IE8威武,这时不向前兼容了,你可以对比一下IE6与IE8的效果,在IE6中还能出现两个class。类似的情况还有for,在IE8要使用setAttribute("for","idXXX")。有关getAttribute("style")的问题也修复了,以前会错误地返回一个 CSSStyleDeclaration 对象,相当于调用了el.style。值得一提的是,HTML5建议把所有特性都小写,像tabIndex这样的特性,于是有三种取法了,el.tabIndex,el.getAttribute("tabindex")与el.getAttribute("tabIndex")。
2010年3月8日补充,a.href与a.getAttribute("href")的问题,按标准浏览器的做法,a.href肯定会被绝对路径化,a.getAttribute("href")会原样输出,如果本来是相对路径,就输出相对路径,如果本来是绝对路径,就输出绝对路径。但IE则会自动补全路径,一律绝对路径化,要想原样输出需要动用getAttribute第二个参数。受影响的路径特性有a[href],input[src],img[src]与area[href]。此bug在IE8被修复。
注1:好像在哪里听说过ie的页面元素其实就是COM组件的马甲,因此才需要hasLayout。
注2:详见这里。
注3:在IE中,全局变量对象是用JScript对象实现的,而全局对象是用宿主对象实现的( in IE “The global variable object is implemented as a JScript object, and the global object is implemented by the host),详见这里。