前两次写的都实现了MVVM框架的一些基本功能,包括双向绑定、v-text、v-for、v-show、v-if 、插值等功能,这一节主要是实现绑定事件的功能。
首先,使用methods存储所有的事件,节点对象增加event属性,是用来存储事件的数组,这里需要使用正则去匹配'@'或者'v-on:',取出事件类型以及事件名称,注意这里需要用bind绑定执行环境,代码如下:
var attributes = node.attributes;
attributes = [].slice.call(attributes);
var reg = /(@)|(s-on:)/g;
temp.event = [];
for (var i = 0; i < attributes.length; i++) {
if (reg.test(attributes[i].name)) {
var len = attributes[i].name.match(reg)[0].length;
var type = attributes[i].name.substring(len);
temp.event.push({type: type, event: attributes[i].value});
}
}
在render函数中:
if (item.event) {
for (var i = 0; i < item.event.length; i++) {
//console.log(methods[item.event[i].event]);
item.node.addEventListener(item.event[i].type, that.eventProcess(methods[item.event[i].event]), false);
}
}
this.eventProcess = function(fn) {
return fn.bind(oop);
}
还需要注意的是,循环模版中,因为改变了dom结构,所以里面如果有绑定的事件需要重新绑定一次:
case 's-for':
var items = data[item.list];
var fragment = document.createDocumentFragment();
if (content) {
for (var i = 0, len = items.length; i < len; i++) {
var dom = document.createElement(item.node
.nodeName.toLowerCase());
dom.innerHTML = items[i][content];
_if (item.event) {
for (var j = 0; j < item.event.length; j++) {
dom.addEventListener(item.event[j].type, that.eventProcess(methods[item.event[j].event]), false);
}
}_
fragment.appendChild(dom);
}
if (item.parentNode) {
var dom = document.createElement(item.node
.nodeName.toLowerCase());
item.parentNode.innerHTML = '';
item.parentNode.appendChild(fragment);
} else{
if (item.nextElementSibling === undefined) {
item.nextElementSibling = item.node.nextElementSibling;
if (item.node.nextElementSibling === null) {
item.node.parentNode.insertBefore(fragment, item.node);
//console.log(item.node.parentNode.lastElementChild);
item.node.parentNode.removeChild(item.node.parentNode.lastElementChild);
} else {
item.node.nextElementSibling.parentNode.insertBefore(fragment, item.node);
item.node.nextElementSibling.parentNode.removeChild(item.node);
}
}
}
}
break;
至此,就实现了基本绑定事件,这时候,这个对象里存储的东西预览一下:
好嘞,算完工吧!