博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
读Ext之十一(通过innerHTML创建元素)
阅读量:6113 次
发布时间:2019-06-21

本文共 4194 字,大约阅读时间需要 13 分钟。

innerHTML 这个由  引入的属性成了事实标准,各浏览器均支持。尽管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 += '
'; } } return b;}

虽然代码较多,但接口却很简单:传入了一个参数o,返回了一个字符串b。

createHtml 内部有三个分支
分支1 ,参数o为字符串时直接返回
分支2 ,参数o为数组时递归调用自身.Ext.isArray用来判断所传参数是否为一个数组类型,该方法在 中提到。
分支3 ,参数o为对象时(通常使用最多的情况)
分之一的情况很简单

var str = createHtml('
test
');alert(str); // "
test
"

 

分支二的情况

var str = createHtml(['
test
','

pp

']);alert(str); // "
test

pp

"

 

分支三的情况

var obj = {        tag:'ul',        children:[{tag:'li',html:'li 1'},{tag:'li',html:'li 2'}]    };var str = createHtml(obj);alert(str); // "
  • li 1
  • li 2
"

 

分支三的详细情况如下

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',    name: 'uname',    cls: 'myClass',    id: 'myId'};var str = createHtml(obj); // 创建input元素,添加name、class及id属性alert(str); // 

 

对html元素的class,for属性做了特殊处理,因为js中class是保留字,for是关键字。

此外有些属性值是复合值组成,如style

var obj = {    tag: 'p',    style: {width:'100px',height:'100px',background:'red'}};var str = createHtml(obj);alert(str); // 

 

接下来

if (emptyTags.test(o.tag)) {    b += '/>';}

emptyTags 是一个正则,这句是对非闭合标签的处理,非闭合标签如br、input、img等。

所有的非闭合标签,都会以"/>"结束,这里遵循xml的习惯。对于非闭合标签不会有html内容。
接下来

else {    b += '>';    if ((cn = o.children || o.cn)) {        b += createHtml(cn);    } else if(o.html){        b += o.html;    }    b += '
';}

对于闭合标签,先完成首标签闭合。拿div示例,由先"<div"变成了"<div>"。

 

接下来如果有children或cn属性,则添加子元素,是一个递归调用,即子元素如果有属性,子元素仍然会继续递归添加。

最后是结束标签"</div>"

 

这就是这个createHtml函数了。该函数实现的很紧凑,巧妙。

createHtml最终返回的是html片段,该片段会通过innerHTML添加到文档中去。
上面的关系图已经可以看到:
markup方法直接调用了createHTML

markup : function(o){    return createHtml(o);},

个人认为这个方法和markup方法重复了。

doInsert方法也直接调用了createHtml

function doInsert(el, o, returnElement, pos, sibling, append){    var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));    return returnElement ? Ext.get(newNode, true) : newNode;}

 

好了,下一篇会接着看DomHelper的其它方法。

 

 

 

转载地址:http://hxcka.baihongyu.com/

你可能感兴趣的文章
(转)HTML的代码(从朋友那转的,看着觉得会有用就转了)
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
Go语言学习(五)----- 数组
查看>>
Android源码学习之观察者模式应用
查看>>
Content Provider的权限
查看>>
416. Partition Equal Subset Sum
查看>>
centos7.0 64位系统安装 nginx
查看>>
数据库运维平台~自动化上线审核需求
查看>>
注解开发
查看>>
如何用 Robotframework 来编写优秀的测试用例
查看>>
Django之FBV与CBV
查看>>
Vue之项目搭建
查看>>
app内部H5测试点总结
查看>>
Docker - 创建支持SSH服务的容器镜像
查看>>
[TC13761]Mutalisk
查看>>
三级菜单
查看>>
Data Wrangling文摘:Non-tidy-data
查看>>
加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
查看>>
while()
查看>>
常用限制input的方法
查看>>