javascript元编程创—OM节点
原文地址:http://x1989.com/a/407.html
在使用javascript创—OM节点的过程中,难免要使用document.createElement、setAttribute、document.createTextNode等冗长、还有浏览器兼容性问题的节点操作方法,虽然有人提议使用字符串拼接后,再使用.innerHTML=可以降低创建节点的成本,而且还有更好的性能,但在我印象中innerHTML并不能适应所有需求(具体神马需求我也忘了),所以下面给大家介绍一种使用javascript元编程技巧来动态创建节点的方法。
那么什么是元编程呢?了解Ruby的同学知道,Ruby的风靡离不开Ruby on Rails(RoR)框架的推动。RoR框架通过魔幻实现质朴的方式,把很多需要用其他语言实现的功能用Ruby来实现,最经典当属RoR框架的ActiveRecord。让我们看一下下面这段代码:
void function() { //支持以"create_"+任意HTML5标签名的动态节点生成函数 var doc = document, win = window, //HTML5标签: tags = ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "command", "datagrid", "datalist", "datatemplate", "dd", "del", "details", "dialog", "dir", "div", "dfn", "dl", "dt", "em", "embed", "event-source", "fieldset", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "label", "legend", "li", "link", "m", "map", "menu", "meta", "meter", "nav", "nest", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "rule", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "tt", "u", "ul", "var", "video", "xmp"]; for (var i = 0; tags[i]; i++) { //闭包是个好东东 win['create_' + tags[i]] = function(tag) { return function(attrs, childNode, textNode) { return createNode(tag, attrs, childNode, textNode) } } (tags[i]); } var createNode = function (tagName, attrs, childNode, textNode) { //创建以tagName命名的节点 var node = doc.createElement(tagName); //处理attrs参数 设置节点属性 typeof attrs === 'string' ? createTextNode(node, attrs) : createAttributeNode(node, attrs); //创建并设置属性节点 //处理childNode参数 添加子节点 if (typeof childNode === 'string') { createTextNode(node, childNode); } else if (childNode && childNode.nodeName) { node.appendChild(childNode) } else if (childNode instanceof Array) { for (var i = 0; childNode[i]; i++) { node.appendChild(childNode[i]) } } //处理文本节点 if (textNode && typeof textNode === 'string') { createTextNode(node, textNode); } return node; } var createAttributeNode = function(node, attrs) { for (var i in attrs) { //下面这种方式适用于原生的节点属性 //node[i] = attrs[i]; //在IE下setAttribute设置某些原生属性会有兼容性问题 //node.setAttribute(i, attrs[i]); //document.createAttribute在IE下设置原生属性会不带引号 var a = doc.createAttribute(i); a.value = attrs[i]; node.setAttributeNode(a); } } var createTextNode = function (node, text) { node.appendChild(doc.createTextNode(text)) }} ();