attribute 和 property

2019-07-19  本文已影响0人  饥人谷1904_陈俊锋

为了区别通常将两个单词翻译为 属性 和 特性

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,两者没有关系并不能相互取值和影响

区别:

  1. 去上面的例子,对一些常见的属性来说,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() 获取自定义属性得到的值的类型总是字符串

  1. 并不是所有的attribute与对应的property名字都一致,比如attribute的class属性,使用property操作的时候应该是className。 ct.className // container
  2. 对于值是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>
  1. 对于一些和路径相关的属性,两者取得值也不尽相同,同样是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>
  1. 对于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

上一篇下一篇

猜你喜欢

热点阅读