我们从下面例子开始说起
<body>
<div class="container">
<input id="input" type="text" value="jinchs">
<br>
<button class="attr-btn">改变attribute</button>
<br>
<button class="props-btn">改变props</button>
</div>
<script>
const inputEl = document.querySelector('#input')
const attrBtn = document.querySelector('.attr-btn')
const propsBtn = document.querySelector('.props-btn')
attBtn.addEventListener('click', e => {
inputEl.setAttribute('value', 'attribute')
})
propsBtn.addEventListener('click', e => {
inputEl.value = 'props'
})
</script>
</body>
复制代码
3个问题,
- 点击
改变attribute
按钮,输入框显示的value是? - 点击
改变props
按钮,输入框显示的value是? - 再次点击
改变attribute
按钮,输入框显示的value是?
同学们可以先思考2分钟,然后再往下看…...
正确答案是:attribute、props、props
如果你的3个答案都完全正确,你可以点击右上角的X了,因为下面的话题估计不能给你带来帮助的。如果你的答案没有完全正确,那么我们继续往下看:
当我们在书写html代码的时候,我们可以给html元素添加attribute
,比如上面的<input id="input" type="text" value="jinchs">
中我们添加了id、type和value3个attribute。浏览器在编译完html后,会将input元素转换成一个dom节点对象,该对象就是代码中的inputEl
。该对象包含了一系列的属性,例如:accept、alt、baseURI、className、attributes等等。
对于一个给定的dom节点对象,properties指的是这个节点对象所拥有的所有属性,attributes指的是该节点对象的attributes属性中的所有属性。
听着有点绕,回到上面的例子中,
<input id="input" type="text" value="jinchs">
该input节点对象包含着id、type、value、attributes的props,当然还有很多其他的props,其中:
- id反映的是attributes中的id属性,并且两者是“完全相同”的映射,即:attribute中的id属性改变了,input节点对象中的id属性也将同步改变,反之亦然;
- type反映的是attributes中的type属性,但是由于input节点对象中的type属性只可能是一些固定的值,如果你设置
<input type="foo">
,此时theInput.getAttribute('type')
的输出结果为foo
,但theInput.type
的输出结果为text
(因为默认值是text啊) - value比较特殊,它反映的是当前输入框中的文本值,初始时input节点对象中的value属性等于attributes中的value属性,用户改变输入框中的文本值本质改的就是input节点对象中的value属性,attributes中的value属性并不会同步变化。需要特别注意的是若没有修改过
theInput.value
,则默认情况下theInput.value
将跟theInput.getAttribute('value')
保持同步,一旦修改过theInput.value
,则该层同步关系即被打破,attribtue的更新将不会影响theInput.value
。反之,theInput.value
的改动任何时候都不会对theInput.getAttribute('value')
有任何影响! - 除了上面的几个属性外,还有一个特殊的
defaultValue
属性,该属性反映的就是attributes中的value属性,并且跟id一样也是“完全相同”的映射。
最后我们看下开篇的3个问题,
- 首次点击
改变attribute
按钮,inputEl
的attributes中的value属性被设置为attribute
,由于之前并没有修改过inputEl.value
的值,此时inputEl.value
将同步更新为attribtue
,此时文本框内容显示props
; - 然后点击
改变props
按钮,此时inputEl.value
被修改props
,所以此时文本框内容显示props
; - 再次点击
改变attribute
按钮,inputEl
的attributes中的value属性被设置为attribute
,由于在第二步中已经修改过inputEl.value
的值,inputEl.getAttribute('value')
和inputEl.value
的同步关系被打破,此时inputEl.value
的值将保持不变。
其实只是很基础的一些东西,但如果不求甚解的话可能很容易忽略“基础背后的真相”,只有将基础打得足够的牢实,才能在实际的开发中少给自己和他人挖坑~