为了区别通常将两个单词翻译为 属性 和 特性
attribute:attribute类型节点,在JS中有专门处理attribute的函数(.getAttribute(name) 和 .setAttribute(name, value)
)。attribute不只是能够在HTML文档上看到的这几个,我们还可以自定义attribute加到DOM节点中。
通过方法 setAttribute 设置的attribute最终都会反映到元素的attribute类型的节点中。
property:DOM对象的字段,和平常使用的obj对象一样,包含很多字段,这些字段就是property,取值或者设置值和普通字段一样通过 对象.字段
的方式。
容易混淆的是因为:很多attribute节点还有一个相对应的property属性
另一种说法:有些例如id、class和title等常用的attribute已经被作为property附加在了DOM对象上,也可以取值和赋值,但是自定义的attribute或者自定义的property,两者就没有关系了
<div id="div1">demo</div>
<script>
var div = document.getElementById('div1')
console.log(div.getAttribute('id')) // div1
div.id = div2
console.log(div.getAttribute('id')) // div2
</script>
上面代码div的 id attribute可以用 div.id 取到,通过property更改id后,用getAttribute获取的id是更新后的id。
<div class="container"></div>
<script>
var ct = document.querySelector('.container')
ct.setAttribute("num", 1)
ct.num // undefined
ct.sum = "2"
ct.getAttribute("sum") //null
</script>
对于自定义的attribute和自定义的property,两者没有关系并不能相互取值和影响
区别:
- 去上面的例子,对一些常见的属性来说,attribute和property共享数据,而且attribute更改了会对property造成影响,反之亦然。但是两者的自定义属性是独立数据,即使属性名字一样,也互不影响。但是,IE 67没有作区分,依然共享自定义属性数据。
<input id="test" type="checkbox" checked="checked" sex="male" age="20">
<script>
var ipt = document.querySelector('#test')
ipt.getAttribute("sex") // "male"
ipt.getAttribute("SEX") // "male"
ipt.sex // undefined
ipt.getAttribute("age") // "20"
</script>
这里也说明:
1)在HTML里自定义的属性,node.property
的方式不能获取,node.getAttribute()
的方式可以
2)node.getAttribute()
获取自定义属性忽略属性的大小写
3)node.getAttribute()
获取自定义属性得到的值的类型总是字符串
- 并不是所有的attribute与对应的property名字都一致,比如attribute的class属性,使用property操作的时候应该是className。
ct.className // container
- 对于值是true/false的property,类似于input的checked attribute等,attribute取得值是HTML文档字面量值,property是取得计算结果,property改变并不影响attribute字面量,但attribute改变会影响property计算。
<input id="test" type="checkbox">
<script>
var ipt = document.querySelector('#test')
ipt.checked // false
ipt.setAttribute('checked', 'checked')
ipt.getAttribute('checked') // null
ipt.checked // true
ipt.checked = false
ipt.getAttribute('checked') // checked
ipt.checked // false
</script>
对于button来说,下面的例子,HTML中只要出现了disabled 属性,不管值是什么,对于 DOM property结果都是true, 而对于 attribute 获取的则是把 HTML 里对应属性的值拿到转换成字符串。
<button id="btn" disabled>点我</button>
<script>
var btn = document.querySelector('#btn');
console.log( btn.disabled ); // true
console.log( btn.getAttribute('disabled') ); // ""
</script>
<button id="btn" disabled=false>点我</button>
<script>
var btn = document.querySelector('#btn');
console.log( btn.disabled ); // true
console.log( btn.getAttribute('disabled') ); // "false"
</script>
- 对于一些和路径相关的属性,两者取得值也不尽相同,同样是attribute取得是字面量,就是从 HTML 里获取对应属性的值转化成字符串,而property取得是计算后的完整路径,获取有意义的真实地址。
<a id="test2" href="#">test2</a>
<script>
var a = document.getElementById('test2')
console.log(a.getAttribute('href')) // "#"
console.log(a.href) // "file:///C:/Users/.../demo.html#"
</script>
- 对于input 的 value, 改变 property 不会同步到 atttribute 上,改变 attribute也不会同步到 value上, attribute对应 HTML, property 对应 DOM。
<input id="test" type="text" sex="male" age="20" value="这是一个textInput">
<script>
var ipt = document.querySelector('#test')
ipt.value = "this is a textInput"
console.log(ipt.value) // "this is a textInput"
console.log(ipt.getAttribute('value')) // "这是一个textInput"
ipt.setAttribute('value', 'It is textInput')
console.log(ipt.value) // "this is a textInput"
console.log(ipt.getAttribute('value')) // "It is textInput"
console.log( document.body.innerHTML ) // <input id="test" type="text" sex="male" age="20" value="It is textInput">
</script>
如果你只是想获取非自定义的属性,比如 id、name、src、href 、checked... 用 property 的方式比较符合日常习惯,如果需要获取自定义属性那只能使用 getAttribute。
attr( )和prop( )区别
在一些特殊的情况下,attributes和properties的区别非常大。在jQuery1.6之前,.attr()方法在获取一些attributes的时候使用了property值,这样会导致一些不一致的行为。在jQuery1.6中,.prop()方法提供了一中明确的获取property值得方式,这样.attr()方法仅返回attributes。
比如,selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, 和defaultSelected应该使用.prop()方法获取/设置值。 在jQuery1.6之前这些不属于attribute的property需要用.attr()方法获取。这几个并没有相应的attibute,只有property。
然而关于checked 属性需要记住的最重要的一点是:它和checked property并不是一致的。实际上这个attribute和defaultChecked property一致,而且只应该用来设置checkbox的初始值。checked attribute并不随着checkedbox的状态而改变,但是checked property却跟着变。因此浏览器兼容的判断checkebox是否被选中应该使用property
if ( elem.checked )
if ( $( elem ).prop( "checked" ) )
if ( $( elem ).is( ":checked" ) )
这对其它一些类似于selected、value这样的动态attribute也适用。
在IE9之前版本中,如果property没有在DOM元素被移除之前删除,使用.prop()方法设置DOM元素property(简单类型除外:number、string、boolean)的值会导致内存泄露。为了安全的设置DOM对象的值,避免内存泄露,可以使用.data()方法。
附上使用场景如下:
参考:
若愚:button.disabled 和 button.getAttribute('disabled') 有什么区别?
谦行:jQuery的attr与prop