Skip to content

Instantly share code, notes, and snippets.

@wintercn
Created September 29, 2013 14:52
Show Gist options
  • Save wintercn/6753150 to your computer and use it in GitHub Desktop.
Save wintercn/6753150 to your computer and use it in GitHub Desktop.
一个简单的dom型模板示例
<div>
<a href="{{protocol}}//{{host}}{{pathname}}">{{protocol}}//{{host}}{{pathname}}</a>
</div>
<script>
function Template(node) {
var prototype = document.createDocumentFragment();
prototype.appendChild(node);
var queue = [{ node: prototype, path: []}];
var setters = [];
function path2node(root, path) {
var curr = root;
for (var i = 0; i < path.length && typeof path[i] == "number"; i++) {
curr = curr.childNodes[path[i]];
}
if (typeof path[i] == "string") {
return curr.getAttributeNode(path[i]);
}
else {
return curr;
}
}
while(queue.length)
{
var current = queue.shift();
//console.log(current.path, current.node);
if (current.node.nodeType == current.node.TEXT_NODE) {
if (current.node.textContent.match(/\{\{[^}]+\}\}/)) {
setters.push(function (path, prop, template) {
return function (root, data) {
var obj = path2node(root, path);
obj[prop] = template.replace(/\{\{([^}]+)\}\}/g, function (str, p) {
return data[p];
})
}
} (current.path, "textContent", current.node.textContent));
}
continue;
}
if (current.node.nodeType == current.node.ATTRIBUTE_NODE) {
if (current.node.value.match(/\{\{[^}]+\}\}/)) {
setters.push(function (path, prop, template) {
return function (root, data) {
var obj = path2node(root, path);
obj[prop] = template.replace(/\{\{([^}]+)\}\}/g, function (str, p) {
return data[p];
})
}
} (current.path, "value", current.node.value));
}
continue;
}
if(current.node.childNodes)
{
for(var i = 0; i<current.node.childNodes.length; i++)
{
queue.push({node:current.node.childNodes[i],path:current.path.concat([i])});
}
}
if (current.node.attributes) {
for (var i = 0; i < current.node.attributes.length; i++) {
queue.push({ node: current.node.attributes[i], path: current.path.concat([current.node.attributes[i].name]) });
}
}
}
this.apply = function (data) {
var element = prototype.cloneNode(true);
for (var i = 0; i < setters.length; i++) {
setters[i](element, data);
}
return element;
}
}
var t = new Template(document.querySelector("div"));
document.body.appendChild(t.apply(location));
document.body.appendChild(t.apply({protocol:"http:",host:"www.baidu.com",pathname:"/"}));
document.body.appendChild(t.apply({protocol:"http:",host:"127.0.0.1",pathname:"/"}));
</script>
@wintercn
Copy link
Author

wintercn commented Oct 9, 2013

@webzhangnan 这个模板的核心竞争力是绑定速度 用outerHTML毫无意义

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment