`
zhouyrt
  • 浏览: 1162212 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

读Ext之十一(通过innerHTML创建元素)

 
阅读更多

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


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

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

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

 
接下来

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 += '</' + o.tag + '>';
}

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

 

接下来如果有children或cn属性,则添加子元素,是一个递归调用,即子元素如果有属性,子元素仍然会继续递归添加。
最后是结束标签"</div>"

 

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

createHtml最终返回的是html片段,该片段会通过innerHTML添加到文档中去。
上面的关系图已经可以看到:

markup方法直接调用了createHTML

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

 

createHTML方法就是私有的createHTML

createHtml : createHtml

 

个人认为这个方法和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的其它方法。

 

 

 

  • 大小: 320.5 KB
  • 大小: 45.5 KB
分享到:
评论
3 楼 duchengning 2011-01-18  
谢谢,我晚上回去试一下,但是这个写法毕竟不是最好的办法。如果真是IE bug,我只能盼望微软能修复,昨天实在没辙了,只能把IE9卸载掉了,不然连我自己都不能用了,还怎么给别人用。
2 楼 zhouyrt 2011-01-15  
IE9后下输入框后面的文字的确显示不了。但F12开始调试工具->启动调试后按F5一直执行完。后面的文字可以显示。应该是IE9的Bug。它跳到DomHelper中的insertHtml的else语句块中。
在head中添加以下语句暂时解决以下

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
1 楼 duchengning 2011-01-15  
冒昧的请帮我个忙,我的hoouf.com登录页面在IE9上文本框后面的提示信息出不来,不知是什么问题?该如何书写代码,目前主要代码如下
var dom_loginPassword = Ext.getDom('loginPassword');
    var dom_loginPassword_parentNode = Ext.get(dom_loginPassword.parentNode);
    dom_loginPassword_parentNode.createChild({
        tag:'span',
        html: " <a href='#' onclick='forget_password()'>取回密码</a>"
    });
详细代码请到我的网站查看,再次先行谢过!

相关推荐

    EXT中文手册.pdf

    例如,`Ext.MessageBox.show({title:'ParagraphClicked', msg:paragraph.dom.innerHTML, width:400, buttons: Ext.MessageBox.OK});`这行代码会显示一个消息框,标题为"ParagraphClicked",显示选中段落的内容,并...

    ext教程

    ### ext教程知识点详解 #### 一、概述 **ext** 是一个非常强大的 JavaScript 类库,最初它是基于 Yahoo UI 库开发的,但现在已经完全独立。它提供了丰富的组件和功能,适用于构建复杂的 Web 应用程序。 #### 二、...

    3------通过实例学习------Ext.js------.docx

    `Ext.get`和`Ext.getBody`是两个常用的DOM访问方法,前者允许通过ID获取元素,后者则可以直接获取`&lt;body&gt;`元素。注意,尽管在HTML中应避免ID重复,但`Ext.get`在遇到相同ID时会返回最后一个匹配的元素。 通过这种...

    js 和 ext 示例

    例如,我们可以使用`document.getElementById`来获取特定ID的div元素,然后通过`innerHTML`或`style`属性来改变其内容或样式。此外,还可以使用`appendChild`和`removeChild`方法进行元素的添加和删除。 2. **ExtJS...

    使用Ext.UpdateManager实现页面任意部分自动刷新处理

    Ext.UpdateManager是Ext JS框架中的一个强大工具,它允许开发者轻松地实现页面元素的自动刷新功能。本文将详细介绍如何使用Ext.UpdateManager来实现在不重新加载整个页面的情况下,自动刷新页面的特定部分。 #### ...

    EXT-DEMO无后台JS写的一面与大家分享

    1. **DOM操作**:JavaScript的核心之一是操作文档对象模型(DOM),在EXT-DEMO中,开发者可能使用了`document.getElementById`、`querySelector`或`querySelectorAll`等方法来选取元素,并使用`innerHTML`、`...

    纯手工打造类似Ext的验证效果

    这可以通过修改元素的`innerHTML`,或者显示弹出警告来实现。 6. **表单重置**:验证成功后,应清空错误提示,并可能重置表单以便用户重新输入。 7. **表单状态管理**:在复杂表单中,可能需要跟踪每个字段的验证...

    IE6/7/8/9中Table/Select的innerHTML不能赋值的解决方法

    例如,Ext.DomHelper在处理表格时,会通过创建`&lt;div&gt;`并间接实现表格内容的添加。 总的来说,当在IE6、7、8、9中遇到innerHTML无法赋值的问题时,开发者应转向使用DOM API进行更底层的操作,而不是依赖innerHTML...

    innerText和innerHTML 一些问题分析

    相比于使用DOM方法创建和插入每个元素,innerHTML使得这样的操作更加高效。 此外,innerText 和 innerHTML 在获取内容时也有不同。当元素只包含纯文本时,两者返回相同的结果。但如果有子元素,innerText只会返回...

    深入理解javascript动态插入技术

    例如,jQuery的`append`方法在处理DOM插入操作时,会创建一个文档碎片,然后将所有待插入的元素添加到这个文档碎片中,最后一次性将它们添加到目标元素上。这一过程减少了对DOM的直接操作次数,从而提高了性能。 ...

    javascript中innerText和innerHTML属性用法实例分析

    而`EditInnerText` 和 `EditInnerHTML` 两个函数分别展示了如何通过 `innerText` 和 `innerHTML` 修改元素内容。`EditInnerText()` 改变了链接文本为 "凤凰网",而 `EditInnerHTML()` 则将链接替换为带有蓝色字体的 ...

    ExtJS增删改查

    - 在触发查询前清空Grid的DOM元素(`div.innerHTML = ""`),然后重建Grid。 #### 四、示例代码分析 接下来,我们通过一个具体的例子来说明如何实现上述四种情况中的第三种情况:页面加载时显示Grid但不查询数据,...

    ExtJs入门 ExtJs很好的电子书 ExtJS入门.pdf 入门ExtJs必备电子书

    Ext.getDom('elId').innerHTML = 'Test'; ``` - **插入HTML片段**:此外,还介绍了如何使用`insertHtml`方法在指定位置插入HTML片段。 ```javascript Ext.get('id').insertHtml({ where: 'beforeBegin', // ...

    javascript动态增加文本框

    函数中,我们创建了一个新的`&lt;div&gt;`元素(用作新的输入框容器),并添加了一个新的文本框输入元素。新文本框的id是动态生成的,以避免id冲突。最后,我们将新的输入框容器添加到主容器中。 通过这种方式,每当用户...

    Ext JS 4实现带week(星期)的日期选择控件(实战一)

    在本文中,我们将探讨如何在Ext JS 4中创建一个带有星期显示的日期选择控件。在标准的Ext JS库中,虽然提供了日期选择器组件(Ext.picker.Date),但并未直接提供显示星期数的功能。这导致开发者需要自定义扩展以...

    Ajax toolkit prototype PPT

    - `update()`:更新元素内容,相当于设置`innerHTML`。 - `hide()`:隐藏元素,等同于设置`style.display = 'none'`。 - `getStyle()`:获取CSS样式属性。 - `setStyle()`:设置一组CSS样式。 - `setAttribute()`:...

    JS搜索框下拉自动填充

    在JavaScript(JS)中,搜索框下拉自动填充是一种常见的用户体验增强功能,它允许用户在输入搜索关键词时,系统会根据历史记录或者预定义的...通过不断地学习和实践,你可以创建出更加高效且用户体验极佳的搜索功能。

    ajaxfileupload.js

    Ajax(Asynchronous JavaScript and XML)是一种创建动态网页的技术,通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下更新部分网页内容。Ajax的核心是 ...

    js抓取网页中标记保存成文件

    我们可以通过`document.documentElement.innerHTML`来获取整个HTML文档的源码,或者通过`document.querySelector()`和`document.querySelectorAll()`选择特定元素及它们的HTML内容。 接着,我们将讨论如何将网页...

Global site tag (gtag.js) - Google Analytics