日期:2014-05-17 浏览次数:20893 次
innerHTML 这个由 IE
引入的属性成了事实标准,各浏览器均支持。尽管html4中没有承认它,但html5已经正式将其纳入
。
我们知道任何一个库都少不了DOM操作,因为用JS操作DOM(早期微软称DHTML)是日常开发中最基本的工作之一。
这篇主要讲述Ext.DomHelper中的 createHtml 函数。首先Ext.DomHelper为一个单例对象。使用其时可沿用Ext库的习惯使用别名
dh
var dh = Ext.DomHelper; // 使用dh别名
dh有以下方法:
markup
applyStyles
insertHtml
insertBefore
insertAfter
insertFirst
append
overwrite
createHtml
dh的createHtml方法就是整个闭包中私有的createHtml。
dh的markup方法内部调用的就是整个闭包中私有的createHtml。
dh的overwrite方法内部也用到了createHtml。
此外私有的doInsert函数内部用用到了createHtml,而dh的insertBefore、insertAfter、insertFirst、append方法用到了doInsert。
因此可以看到私有的createHtml函数是dh中处在底层的,最重要的函数
。它们之间的关系如下图
?
?
createHtml 的定义如下
function createHtml(o){ var b = '', attr, val, key, keyVal, cn; if(Ext.isString(o)){ b = o; } else if (Ext.isArray(o)) { for (var i=0; i < o.length; i++) { if(o[i]) { b += createHtml(o[i]); } }; } else { b += '<' + (o.tag = o.tag || 'div'); Ext.iterate(o, function(attr, val){ if(!/tag|children|cn|html$/i.test(attr)){ if (Ext.isObject(val)) { b += ' ' + attr + '="'; Ext.iterate(val, function(key, keyVal){ b += key + ':' + keyVal + ';'; }); b += '"'; }else{ b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"'; } } }); // Now either just close the tag or try to add children and close the tag. if (emptyTags.test(o.tag)) { b += '/>'; } else { b += '>'; if ((cn = o.children || o.cn)) { b += createHtml(cn); } else if(o.html){ b += o.html; } b += '</' + o.tag + '>'; } } return b; }
?
虽然代码较多,但接口却很简单:传入了一个参数o,返回了一个字符串b。
createHtml 内部有三个分支
分支1
,参数o为字符串时直接返回
分支2
,参数o为数组时递归调用自身.Ext.isArray用来判断所传参数是否为一个数组类型,该方法在 读Ext之二(实用方法)
中提到。
分支3
,参数o为对象时(通常使用最多的情况)
分之一的情况很简单
var str = createHtml('<div>test</div>'); alert(str); // "<div>test</div>"?
分支二的情况
var str = createHtml(['<div>test</div>','<p>pp</p>']); alert(str); // "<div>test</div><p>pp</p>"
?
分支三的情况
var obj = { tag:'ul', children:[{tag:'li',html:'li 1'},{tag:'li',html:'li 2'}] }; var str = createHtml(obj); alert(str); // "<ul><li>li 1</li><li>li 2</li></ul>"?
?
分支三的详细情况如下
b += '<' + (o.tag = o.tag || 'div');
?
b为空字符串,该语句执行完为:"<tag",如果没有所传对象没有tag属性,默认创建div即"<div"
接下来是为根元素添加属性,
Ext.iterate(o, function(attr, val){ if(!/tag|children|cn|html$/i.test(attr)){ if (Ext.isObject(val)) { b += ' ' + attr + '="'; Ext.iterate(val, function(key, keyVal){ b += key + ':' + keyVal + ';'; }); b += '"'; }else{ b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"'; } } });
?
Ext.iterate方法是一个通用迭代器,可以迭代数组,也可以是对象。在 读Ext之二(实用方法) 提到。即所传对象o的属性不为tag、children、cn、html时给该元素添加html属性
var obj = { tag: 'input',