javascript中的property和attribute虽然都被翻译为“属性”,但是他们还是有区别的。

前两天写网页时用到checkbox,就被property和attribute弄晕了好久。后来看了javascript tutorial中的解释就清楚了许多,周末有空,把原文的主要内容翻译一下。

原帖链接在这里:http://javascript.info/tutorial/attributes-and-custom-properties

一个dom节点可能包含有attributes和properties。它们有联系和区别,很多人经常混淆。

Properties

Dom节点是对象,因此可以存储自定义properties和methods。

下面这个例子将一个对象myData赋值为document.body中的一个property

document.body.myData = {
name: 'John'
}
alert(document.body.myData.name) // John document.body.sayHi = function() {
alert(this.nodeName)
} document.body.sayHi() // BODY

自定义的properties和methods只在javascript中可见,不影响html。

另外,自定义的properties是可以在for..in中与原生properties一起被遍历的到的。

document.body.custom = 5

var list = []
for(var key in document.body) {
list.push(key)
} alert(list.join('\n'))

总结一下自定义DOM properties:

  • 可能是任何类型的的值,Property名称是大小写敏感的;
  • 不影响html。

Attributes

DOM节点提供以下几个标准方法来访问HTML的attributes:

  • elem.hasAttribute(name) - checks if the attribute exists
  • elem.getAttribute(name) - gets an attribute value
  • elem.setAttribute(name, value) - sets an attribute
  • elem.removeAttribute(name) - removes an attribute

与properties对比,attributes有以下不同:

  • 只可以是string;
  • 名称大小写不敏感,因为HTML的attributes是大小写不敏感的;
  • 不在innerHTML中显示(老版本IE除外);
  • 你可以通过使用元素的array-like attributes property来列举所有的attributes。

例如下面的例子,设置了attributes:

<body>
<div about="Elephant" class="smiling"></div> <script>
var div = document.body.children[0]
alert( div.getAttribute('ABOUT') ) // (1) div.setAttribute('Test', 123) // (2)
alert( document.body.innerHTML ) // (3)
</script>
</body>

运行上述代码,要注意到:

  1. getAttribute('ABOUT')使用了大写,但是同样可以访问到小写的about属性;
  2. 可以尝试给attribute赋值一个string或者其它的原生类型,那么就会变成一个string,object类型会被自动转换,但这个转换在IE中存在问题,所以最好只用原生类型;
  3. 运行完后新的innerHTML会出现新的名为test的attribute

Properties和Attributes的同步

所有类型的DOM节点都有标准Properties。

例如a标签:Interface HTMLAnchorElement

它有href和accessKey等自有的attributes。另外也从HTMLElement中继承了如id等attributes。

标准的DOM properties和attributes是同步的。

id

举个例子,浏览器会自动同步id这个attribute和propertie:

<script>
document.body.setAttribute('id','la-la-la')
alert(document.body.id) // la-la-la
</script>

href

但是,自动同步不代表同步的值是完全一样的。看下面这个例子:

<a href="#"></a>
<script>
var a = document.body.children[0] a.href = '/'
alert( 'attribute:' + a.getAttribute('href') ) // '/'
alert( 'property:' + a.href ) // IE: '/', others: full URL </script>

这是因为根据w3c标准W3C specification,href必须是一个完整的链接。

还有其它的一些attributes是同步但值不统一的,例如input.checked:

<input type="checkbox" checked>

<script>
var input = document.body.children[0] alert( input.checked ) // true
alert( input.getAttribute('checked') ) // empty string
</script>

input.checked这个property的值只能是true或者false,但是attribute可以是你想要的任何值。

value

此外,有一些内置的properties是值单向同步的。

举例,input.value可以从其attribute同步过来:

<body>
<input type="text" value="markup">
<script>
var input = document.body.children[0] input.setAttribute('value', 'new') alert( input.value ) // 'new', input.value changed
</script>
</body>

但是,它的attribute却不能由property同步过来:

<body>
<input type="text" value="markup">
<script>
var input = document.body.children[0] input.value = 'new' alert(input.getAttribute('value')) // 'markup', not changed!
</script>
</body>

在value这个property更新之后,其attribute仍然为原本的值,比如一个访客在输入框中输入了一些东西。这个原本的值可以用来检查input框是否有改变,也可以用来重置框内的内容。

class/className

还有一个命名的例外,就是class这个attribute是和className这个property对应的。

因为class是一个javascript保留字,那么class这个attribute对应的property是className。

<body>
<script>
document.body.setAttribute('class', 'big red bloom') alert( document.body.className ) // 'big red bloom'
</script>
</body>

注意,这个例子在IE<9是不成立的,因为它们用一种奇怪的方式来组织attributes和properties。

好的实践是,总是用className这个property来操作class,而不要用attribute。

对于IE,要谨慎对待attributes。换句话说,除非你真的需要用到attributes,否则的话尽量用properties。而真正需要用到attributes的只有以下情况:

  1. 需要获取自定义的HTML attribute,因为自定义的attributes不和properties同步;
  2. 需要获取HTML attributes的原始值,就像<INPUT value="...">。

Attributes作为DOM节点

Attributes也可以通过elem.attributes集合来获取。

在attributes集合中,每个attribute都作为一个特殊的DOM节点a special kind of DOM node,有name,value,和其它properties。

例如:

<span style="color:blue" id="my">text</span>

<script>
var span = document.body.children[0]
alert( span.attributes['style'].value ) // "color:blue;"
alert( span.attributes['id'].value ) // "my"
</script>

另外,IE<8以及IE8兼容模式对于style这个attribute的支持非常的奇怪。

Attribute DOM节点不属于文档树的一部分,它们只可以由他们的元素来访问。

总结

attributes和properties都是DOM模型的核心特性。

下表表示了他们的区别和联系:

Properties Attributes
任何类型的值 String
大小写敏感 大小写不敏感
不在innerHTML中可见 在innerHTML中可见
标准的DOM properties和attributes是同步的,而自定义的不是
attributes和properties在IE<8以及IE8兼容模式中是混杂的

如果你向要自定义HTML中的attributes,那么请请记住HTML 5中的data-* attributes。可以查看这里Custom data attributes来获取HTML5中这部分内容。

在实际中,98%的情况下用的的是properties。

attributes只应被用于两种情况下:

  1. 需要获取自定义的HTML attribute,因为自定义的attributes不和properties同步;
  2. 需要获取内置HTML attributes,它不和properties同步,并且你确切的知道你确实需要用到attributes,例如input中的value

js中的property和attribute的更多相关文章

  1. JavaScript中的property和attribute

    property,attribute都作“属性”解,但是attribute更强调区别于其他事物的特质/特性. 而在JavaScript中,property和attribute更是有明显的区别.众所周知 ...

  2. 详解JS中DOM 元素的 attribute 和 property 属性

    一.'表亲戚':attribute和property 为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点. attribute 是 dom 元素在文档中作为 h ...

  3. js中__proto__, property, prototype, 对象自身属性方法和原型中的属性方法的区别

    __proto__: 这个属性是实例对象的属性,每个实例对象都有一个__proto__属性,这个属性指向实例化该实例的构造函数的原型对象(prototype). proterty:这个方法是对象的属性 ...

  4. js中的attributes和Attribute的用法和区别。

    一:Attribute的几种用法和含义(attributes和Attribute都是用来操作属性的) getAttribute:获取某一个属性的值: setAttribute:建立一个属性,并同时给属 ...

  5. js中Attribute和property的区别与联系

    相信大多数的初学者对js中的property和attribute的关系很容易搞混, Attribute大多用于DOM的操作中,比如ele.attributes指的是一个元素的特性集合,是一个nodel ...

  6. JS中property与attribute的区别

    property与attirbute都是属性的意思,在JS中很容易混淆,但实际上二者有很大的区别.简单来说, property:是DOM中的属性,是JavaScript中的对像 attribute:是 ...

  7. DOM中 property 和 attribute 详解

    被问到 property 和 attribute 的区别,想来也是要好好看一下. 一.基本概念区别 其实Attribute和Property这两个单词,翻译出来都是“属性”,<js高级程序设计& ...

  8. DOM 中 Property 和 Attribute 的区别

    原文地址:http://web.jobbole.com/83129/ property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute: ...

  9. [转]DOM 中 Property 和 Attribute 的区别

    angular的文档: https://angular.io/guide/template-syntax#property-binding https://blog.csdn.net/sunq1982 ...

随机推荐

  1. 外观模式(Facde)【设计模式】

    定义:为子系统中的一组接口提供一个一致的界面,Fcade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. “外观模式(Facade pattern),是软件工程中常用的一种软件设计模式,它 ...

  2. bzoj 4034: [HAOI2015]树上操作——树链剖分

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...

  3. [Unity]游戏Inside中的Chromatic Aberration效果学习

    Chromatic Aberration效果指的是模拟摄像机的拍摄瑕疵导致rgb三个通道的颜色发生了偏移,如 传统的Chromatic Aberration实现往往是基于一个后处理,将rgb采样的坐标 ...

  4. python进行机器学习(一)之数据预处理

    一.加载数据 houseprice=pd.read_csv('../input/train.csv') #加载后放入dataframe里 all_data=pd.read_csv('a.csv', h ...

  5. linux irq 自动探测

    前言 编写驱动的时候,经常会用到中断,这时候我们在驱动初始化时就得申请中断,那么问题来了,中断号是多少呢?以前的中断号在板级相关的头文件里面已经静态定义好了,bsp的代码在内核启动过程也会根据那个帮我 ...

  6. java===java基础学习(16)---final

    final-----概念 1.当不希望父类的某个方法被子类覆盖(override)时,可以用final关键字修饰. 2.当不希望类的某个变量的值被修改时,可以用final修饰.如果要用final,则必 ...

  7. 天气api接口

    python调用天气api接口: http://www.sojson.com/open/api/weather/json.shtml?city=北京 http://www.sojson.com/blo ...

  8. 64_l6

    lightdm-qt5-devel-1.22.0-1.fc26.i686.rpm 19-May-2017 11:11 22854 lightdm-qt5-devel-1.22.0-1.fc26.x86 ...

  9. [session篇]看源码学习session(一)

    假如你是使用过或学习过PHP,你一定觉得很简单.session只不过是$_SESSION就可以搞得,这还不简单只是对一个key-value就能工作了.我觉得可以大多数的phper都是这样的,这是语言本 ...

  10. IE中部分版本的浏览器对Select标签设置innerHTML无效的问题

    这样写的代码:document.getElementById('data_list').innerHTML = data;//data是ajax返回的数据 结果发现在ie10的兼容模式下面下拉框没有内 ...