對於前端,有時候須要實現視圖層和數據層的雙向綁定(two-way-binding), 例如當前流行的各類框架和類庫:Vue.js、Angular.js、React.js。 然而,他們最原始的實現方式其實都相對比較簡單,只不過是後來隨着各類Bug的出現,才一如滾雪球般地被不斷優化和壯大。javascript
因此,不要畏懼,多多學習並攝取它們的精華。html
這裏, 我也但願經過簡單的思路讓你對數據的雙向綁定有個大概瞭解,而後去看各類MVVM框架中對於數據雙向綁定的實現纔不會一頭霧水。前端
Element繼承了Node,而Element是衆多Node類型中的其中一個, nodeType === 1, 因此,屬於Node的屬性能夠用於Element,但Element的屬性沒法用於Node,聽起來好拗口,看一下代碼吧.java
<div class="demo"> <p>大</p> <p>轟</p> </div> var el = document.querySelector('.demo'); // true console.log(el.children[0] instanceof Node); // true console.log(el.children[0] instanceof Element); // true console.log(el.childNodes[0] instanceof Node); // false console.log(el.childNodes[0] instanceof Element); // undefined console.log(typeof el.childNodes[0].children); // object console.log(typeof el.childNodes[0].childNodes);
雙向綁定對於理解Flux等架構所提倡的單向數據流特性有很好的幫助, 簡單點說,就是將數據的變化綁定到UI, 同時UI的變化又和數據同步。這樣一來,假如你是全站Ajax,你不用去管數據對UI的影響,同時也不用去管UI變化形成的數據變化,統一了數據操做的入口,很是方便維護。(不知道這樣理解對不對, 望指正)node
總而言之,雙向數據綁定的底層實現大概有兩種:git
一、手動綁定,同時使用dirty check去循環監聽。(Angular.js爲表明)github
二、前端數據劫持。(使用defineProperty, Vue.js貌似就是使用這種)架構
這種方法的實現相似**訂閱者模式**,實現思路是經過DOM的*keydown* *keyup* *keypress* *change*等事件觸發*dirty check*(固然你也能夠用setTimeout), 而後循環監聽並將value寫入某實例變量裏面,同時更新DOM。
如果有時間,推薦去看一下Angular.js文檔中關於digest / $watch的介紹。框架
若是使用jQuery實現起來更加簡單明瞭。
傳送門在此frontend
https://jsfiddle.net/fondadam/sdxhhoLx/2/embedded/js,html,result
第三種方法則是Vue.js
等框架使用的數據劫持方式。基本思路是使用Object.defineProperty
對數據對象作屬性get和set的監聽,當有數據讀取和賦值操做時則調用節點的指令,這樣使用最通用的=等號賦值就能夠觸發了。
https://jsfiddle.net/fondadam/a4qhp06s/embedded/js,html,result