双向绑定

Javascript

//JavaScript
var Hue = function(opt) {
var el = document.querySelector(opt.el);
var data = opt.data || {};

return new Hue.prototype.init(el, data);
};

Hue.prototype = {
constructor: Hue,

// 要实现类数组,必须要有这两个属性
length: 0,
splice: [].splice,

init: function(el, data) {
this.el = el;
this.data = data;

// 返回所有含有``h-*``属性的元素
this.elems = this.bindNodesArr(el);

// 初始化,同时防止位空时出现undefined
this.digest(true);

return this;
},

bindNodesArr: function(el) {
var arr = [],
_this = this,
childs = el.childNodes,
len = childs.length,
i, j,
attr,
lenAttr;

if (childs.length) {
for (i = 0; i < len; i++) {
el = childs[i];

if (el.nodeType === 1) {
for (j = 0, lenAttr = el.attributes.length; j < lenAttr; j++) {

attr = el.attributes[j];
if (attr.nodeName.indexOf('h-') >= 0) {
arr.push(el);
switch (attr.nodeName.slice(2)) {

// 监听model绑定的事件
case 'model':
if (document.addEventListener) {
el.addEventListener('keydown', function() {
_this.digest();
}, false);
} else {
el.attachEvent('onkeydown', function() {
_this.digest();
}, false);
}
break;

default:
break;
}

break;
}
}

arr = arr.concat(this.bindNodesArr(el));
}
}
}

return arr;
},

digest: function(bool, ms) {
var i, j,
len, len2;

var elems = this.elems,
data = this.data;

bool = bool === true ? true : false;
ms = ms || 0;

// 这里不能传参bool/ms, 否则bool和ms都会为undefined,因为setTimeout里的function作用域是指向window的
setTimeout(function() {
for (i = 0, len = elems.length; i < len; i++) {
el = elems[i];
attrs = el.attributes;
for (j = 0, len2 = attrs.length; j < len2; j++) {
var attr = attrs[j];
if (attr.nodeName.indexOf('h-') >= 0) {

switch (attr.nodeName.slice(2)) {
case 'model':
if (bool) {
el.value = data[attr.nodeValue] || '';

// dirty check
} else if (el.value !== data[attr.nodeValue]) {
data[attr.nodeValue] = el.value || '';
}
break;

case 'text':

// dirty check
if (el.innerHTML !== data[attr.nodeValue]) {
el.innerHTML = data[attr.nodeValue] || '';
}
break;

default:
console.error('Error: There is only h-model and h-text !');
break;
}
}
}
}
}, ms);
}
}

// 参考jQuery ...
Hue.prototype.init.prototype = Hue.prototype;


// test...
Hue({
el: '.app',
data: {
demo: '大轰'
}
});

HTML

<div class="app">
<input type="text" h-model="demo">

<p h-text="demo"></p>
</div>
posted @ 2017-11-15 14:42  幻城love  阅读(177)  评论(0编辑  收藏  举报