js变量与节点双向绑定

由 夕空 撰写于  2020年2月3日
<html>
<body>
<h1 ng-bind="num"></h1>
<input id="text"/>
</body>

<script>

//缓存
let watchers = {};
let scope = {};

//绑定变量
function watch(obj){
scope=obj;
const propertys = Object.keys(scope);

propertys.forEach(function (prop){
//console.log(prop);
//不处理函数属性
if( 'function' == typeof scope[prop] ) return;

const propName = prop;
console.log(propName, scope[prop]);
//监听对象属性
Object.defineProperty(scope, prop, {
//value: scope[prop],
configurable: true,
get: function() {
//scope[property]会导致栈溢出,因为一直递归(Uncaught RangeError: Maximum call stack size exceeded)
//console.log('get', prop, 'for', propName);
return watchers[propName];
},
set: function(value) {
//scope[property]会导致栈溢出,因为一直递归(Uncaught RangeError: Maximum call stack size exceeded)
//console.log('set', prop, 'for', propName);
//防止递归导致的栈溢出,先去掉监听的函数
document.removeEventListener('DOMCharacterDataModified', element);
document.removeEventListener('DOMNodeInserted', element);
watchers[prop] = value;
document.querySelector("*[ng-bind='"+prop+"']").innerText = watchers[prop];
//重新监听
document.addEventListener('DOMCharacterDataModified', element,false);
document.addEventListener('DOMNodeInserted', element,false);
}
});
});
}

//dom的修改触发JS变量的修改
function element(e){
console.log(e.newValue, e.prevValue, e.path);
const attrs = e.target.parentElement.attributes;
for(let i=0; i<attrs.length; i++){
const attr = attrs[i];
if('ng-bind' === attr.nodeName){
console.log('ng-bind:', scope[attr.nodeValue]);
scope[attr.nodeValue] = e.target.nodeValue;
}
}
}
//绑定从dom到js
document.addEventListener('DOMCharacterDataModified', element,false);
document.addEventListener('DOMNodeInserted', element,false);

</script>

<script>

//实际数据
var myData = {
num: 0
};
//绑定:从js到dom
watch(myData);
myData.num = 2; // set:2
console.log(myData.num); // get:2

//通过输入框修改变量
document.getElementById('text').oninput = function(e){
const v = document.getElementById("text").value;
const prop = 'num';
document.querySelector("*[ng-bind='"+prop+"']").innerText = v; //改变DOM
// myData.num = v; //改变变量
console.log('myNum:'+myData.num)
}
</script>
</html>



声明:星耀夕空|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - js变量与节点双向绑定


欢迎光顾我的小站!