原文链接:http://web.jobbole.com/83129/
property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴。
- property是DOM中的属性,是JavaScript里的对象;
- attribute是HTML标签上的特性,它的值只能够是字符串;
基于JavaScript分析property 和 attribute
html中有这样一段代码:
1 | <input id="in_1" value="1" sth="whatever"> |
简单的在html页面上创建一个input输入栏(注意在这个标签中添加了一个DOM中不存在的属性“sth”),此时在JS执行如下语句
|
1
|
var
in1
=
document.getElementById('in_1');
|
执行语句
1 | console.log(in1); |
从console的打印结果,可以看到in1含有一个名为“attributes”的属性,它的类型是NamedNodeMap,同时还有“id”和“value”两个基本的属性,但没有“sth”这个自定义的属性。
|
1
2
3
|
attributes:
NamedNodeMap
value:
"1"
id:
"in_1"
|
有些console可能不会打印in1上的属性,那么可以执行以下命令打印要观察的属性:
1 2 3 | console.log(in1.id); // 'in_1' console.log(in1.value); // 1 console.log(in1.sth); // undefined |
可以发现,标签中的三个属性,只有“id”和“value”会在in1上创建,而“sth”不会被创建。这是由于,每一个DOM对象都会有它默认的基本属性,而在创建的时候,它只会创建这些基本属性,我们在TAG标签中自定义的属性是不会直接放到DOM中的。
我们做一个额外的测试,创建另一个input标签,并执行类似的操作:
html:
|
1
|
<input
id="in_2">
|
JS:
1 2 | var in2 = document.getElementById('in_2'); console.log(in2); |
从打印信息中可以看到:
|
1
2
|
id:
"in_2"
value:
null
|
尽管我们没有在TAG中定义“value”,但由于它是DOM默认的基本属性,在DOM初始化的时候它照样会被创建。由此我们可以得出结论:
- DOM有其默认的基本属性,而这些属性就是所谓的“property”,无论如何,它们都会在初始化的时候再DOM对象上创建。
- 如果在TAG对这些属性进行赋值,那么这些值就会作为初始值赋给DOM的同名property。
现在回到第一个input(“#in_1”),我们就会问,“sth”去哪里了?别急,我们把attributes这个属性打印出来看看
1 | console.log(in2); |
上面有几个属性:
|
1
2
3
4
5
|
0:
id
1:
value
2:
sth
length:
3
__proto__:
NamedNodeMap
|
原来“sth”被放到了attributes这个对象里面,这个对象按顺序记录了我们在TAG中定义的属性和属性的数量。此时,如果再将第二个input标签的attributes打印出来,就会发现只有一个“id”属性,“length”为1。
从这里就可以看出,attributes是属于property的一个子集,它保存了HTML标签上定义属性。如果再进一步探索attitudes中的每一个属性,会发现它们并不是简单的对象,它是一个Attr类型的对象,拥有NodeType、NodeName等属性。关于这一点,稍后再研究。注意,打印attribute属性不会直接得到对象的值,而是获取一个包含属性名和值的字符串,如:
1 | console.log(in1.attibutes.sth); // 'sth="whatever"' |
由此可以得出:
- HTML标签中定义的属性和值会保存该DOM对象的attributes属性里面;
- 这些attribute属性的JavaScript中的类型是Attr,而不仅仅是保存属性名和值这么简单;
那么,如果我们更改property和attribute的值会出现什么效果呢?执行如下语句:
|
1
2
3
|
in1.value
=
'new value of prop';
console.log(in1.value);
//
'new value of prop'
console.log(in1.attributes.value);
//
'value="1"'
|
此时,页面中的输入栏的值变成了“new value of prop”,而propety中的value也变成了新的值,但attributes却仍然是“1”。从这里可以推断,property和attribute的同名属性的值并不是双向绑定的。
如果反过来,设置attitudes中的值,效果会怎样呢?
1 2 3 | in1.attributes.value.value = 'new value of attr'; console.log(in1.value); // 'new value of attr' console.log(in1.attributes.value); // 'new value of attr' |
此时,页面中的输入栏得到更新,property中的value也发生了变化。此外,执行下面语句也会得到一样的结果
|
1
|
in1.attributes.value.nodeValue
=
'new value of attr';
|
由此,可得出结论:
- property能够从attribute中得到同步;
- attribute不会同步property上的值;
- attribute和property之间的数据绑定是单向的,attribute->property;
- 更改property和attribute上的任意值,都会将更新反映到HTML页面中;
本文解析了DOM中的property与HTML标签上的attribute的区别,通过实例演示了两者如何在JavaScript中体现及交互。
652

被折叠的 条评论
为什么被折叠?



