使用Object.defineProperty
来做input
元素和object
的双向绑定, 一个简单的例子:
<input type='text' class='binding'>
// 定义data对象
window.data = {}
// 当input元素的值改变时改变data
document.querySelector('input.binding').addEventListener('input', (e) => {
data.inputVal1 = e.target.value
})
Object.defineProperty(data, 'inputVal1', {
// 从input中读值
get () {
return document.querySelector('input.binding').value
},
// 改变时写入到input
set (val) {
document.querySelector('input.binding').value = val
}
})
不过这里有个问题:
当我改变input的值时(不管是通过input.value
写值还是直接输入), data.inputVal1
的setter
都会触发, 反过来触发input.binding
元素的input
事件, 该事件又触发data.inputVal1
的setter
...循环触发, 这里是个死循环啊
反过来改变data.inputVal1
的值也有一样的问题: setter
触发input
事件, input
事件又触发setter
...
但是实际上这段双向绑定的代码工作得很好
这是为什么呢?
已解决
原因是使用input.value
方法写值, 并不会触发元素的input
和change
事件. input
事件: 当用户直接在文本域输入时触发; change
事件: 当文本域onblur
并且值和focus
前不一致时触发.
用于setter
对于input
是直接写值, 因此input
的input
事件并没有被触发.