从图中可以看到attributes这个对象是NamedNodeMap这个构造函数的实例,具有length属性,该属性值是由自己添加的属性(这个叫法其实是错误的) 的个数来决定的,div.attributes会返回一个类数组对象,所以也可以通过下标来获取属性值。
为什么上面说到“属性”这个叫法是错误的呢?看图1,我在div上设置了一个自定义属性abc,按照属性的说法,div的私有属性上应该会添加一个abc的属性,但是实际上并没有(看图2),它是被添加到了attributes这个属性上了,其实attributes的正确叫法叫特性,我们在标签内添加的属性其实都是往attributes这个对象里添加属性,倘若在私有属性property上也有同样的属性(前提是可编辑属性,例如id,class,title,name,type,src,alt等);则同样也会影响到该属性。如果property上没有该属性名,也不会在私有属性property上添加该属性,因为div(爸爸)不允许attributes(儿子)随意添加自己没有的东西。
属性和特性的区别:
1.属性能存储任意类型的值,而特性只能存储字符串类型的值
2.属性用“.”或者[]来获取或设置属性值,特性建议用getAttribute()和setAtttibute()来获取和设置属性值,这两个方法的参数必须是字符串,不建议使用下标的方式来获取,因为这种方式有兼容性问题,没错,就是万恶之源IE,在IE下属性是根据26个字母顺序来排序的,而在Chrome下则是按照书写顺序来排序(看上图),其它浏览器没测过不知道;比如IE下div.attributes[0]获取到的是class的值(c在i前面),而Chrome下div.attributes[0]获取的值是id(书写顺序)
我尝试在标签内添加attributes这个属性来重写原本私有属性property上的attributes属性,但结果并不是我想象中的样子
而是在attributes下添加了一个attributes属性。
这2种获取属性和设置属性的方法在可编辑属性上是相互影响的比如
一开始我并没有给Input这个元素添加class,所以两种方法都获取不到class,然后用不同的方法设置class后,另一个方法也能获取到class值。有一个可编辑的属性是例外的,它就是value属性
从图中可以看到2种方法设置value值是互不影响的,并且setAttribute()这个方法是设置不了输入框的value值,它只是把attributes这个对象里面的value属性的值设为666而已,私有属性property上的value还是20。
不可编辑属性和value这种情况差不多,就不上图了,有兴趣的可以自己测试一下(tagName, nodeType等这些属性)
它们之间的影响还有一种特殊情况,同样是可编辑属性的特殊情况
初始化我给input元素加上hidden属性设为true隐藏,然后我把私有属性上hidden属性设为false,input元素重新出现,特性attributes上的hidden属性被移除了。
最后一个区别就是当getAttribute()方法获取一个不存在的属性或方法时,返回值为null;而在私有方法property上获取不存在的属性或方法时,返回值是undefiend。
最后来看看attributes原型上的方法
getNamedItem()和removeNamedItem()和setNamedItem()方法参数是字符串类型,传属性名,removeNamedItem()同样可以移除某个属性,setNamedItem()方法可以设置某个属性,这3个方法的返回值都是一个object
item()方法传索引,同样是返回一个object.
getNamedItemNS()和removeNamedItemNS()和setNamedItemNS()这3个方法暂时不知道有什么用
上述方法在IE8一样可以使用。