实现文本插值与s-for循环模版。
对于文本插值的实现,我采用正则去匹配还原这个dom节点,以插值{{text}}形式为分界,将这个dom节点的文本分割成多个字符串,存储在this.muscha中,再者,将普通文本字符串以数组形式存储在string属性中,将插值存放在text属性值。当然,拼接的时候要明白先从string还是先从text开始拼接,我采用的方法是设置标志值,tag属性为0时,从text开始,为1时从string开始,存储完成后,解析拼接时只会出现这么几种情况:字串文本在前插值(1个或者多个)在后、只出现插值(1个或者多个)、前面后面插值中间为字串,前面后面为字串中间为插值。这些都可以分别处理,this.muscha函数如下:
this.muscha = function(value) {
var temp = {
string: [],
text: [],
tag: 0
};
var reg = /\{\{((?:.|\\n)+?)\}\}/g;
if (!reg.test(value)) {
return null;
}
var match;
var lastIndex = reg.lastIndex = 0;
var index;
while(match = reg.exec(value)) {
index = match.index;
if (index > lastIndex) {
temp.tag = 1;
temp.string.push(value.slice(lastIndex, index));
}
temp.text.push(match[1]);
lastIndex = index + match[0].length;
}
if (lastIndex < value.length) {
temp.string.push(value.slice(lastIndex));
}
return temp;
}
拼接字串的方式如下:
this.strSplit = function(item) {
var str = '';
if (!item.muscha.tag) {
var len = item.muscha.string.length;
switch(len) {
case 0:
for (var i = 0; i < item.muscha.text.length; i++) {
str += data[item.muscha.text[i]];
}
break;
case 1:
str = data[item.muscha.text[0]] + item.muscha.string[0];
break;
default:
for (var i = 0; i < len; i++) {
str = data[item.muscha.text[i]] + item.muscha.string[i];
}
str += data[item.muscha.text[i]];
}
} else {
var len = item.muscha.text.length;
switch(len) {
case 1:
//console.log(data[item.muscha.text[0]]);
str = item.muscha.string[0] + data[item.muscha.text[0]];
break;
default:
for (var j = 0; j < len; j++) {
str = item.muscha.string[j] + data[item.muscha.text[j]];
}
str += item.muscha.string[j];
}
}
return str;
}
进一步,实现循环模版。带有非根元素(代码中的最外层节点)的父元素的循环节点处理起来相对容易,只需要将父元素先清理干净(parentNode.innerHTML = ''),循环数据后插入相应的dom节点即可。只是花了不少的时间在父元素为根节点的循环模版上,如果采用相同的方法,页面结构必然会被破坏,当我们重写这个节点后对节点的引用也就失效了,于是上一种的情况采用父节点来辅助,于是在这就联想到,我是否可以借助兄弟元素来实现呢?当然,各种各样的问题也在这里出现,加深了对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;
};
好了,暂时就实现这么点,插值的供能是很强大的,这里实现的功能也只是一部分~