`
bigtall
  • 浏览: 10380 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

我的动态javascript对象到DOM元素的生成器

阅读更多

 

06年曾经写过一个将 object 转化为 DOM 元素的生成器,后来换工作之后一段时间不写js,代码就找不到了。但是最近因工作需要,所以重新写了一个。不过现在似乎很多js代码库都实现了该技术了,不新鲜了。

 

代码的原理很简单,就是一个简单的js对象,根据其中的 nodeName字段值 调用 document.createElement() 生成DOM元素,然后将js对象其余的字段值都设置到新生成的 DOM元素中。先看一下demo代码,用于生成一个表格,每个单元格中存放一个checkbox:

 

 

    var table = {nodeName: "table", className: "selection", children:[]};
    var ctrls;
    for(var i = 0; i < infos.length; ++i)
    {
        if( i % 5 == 0 )
        {
            var row = {nodeName: "tr", children:[]};
            ctrls = row.children;
            table.children.push(row);
        }
        ctrls.push({nodeName: "td", className: "select_project", children:[
            {nodeName:"input", "id": "proj_" + infos[i].id, name:"selproj", "type": "radio", value:infos[i].id, onclick: fnOnProjectCheck}
            , {nodeName: "label", "htmlFor": "proj_" + infos[i].id, innerHTML: infos[i].lname}
        ]});
    }

    containor.innerHTML = "";
    generateElements(containor, table);

 

 如果用直接的字符串拼装,看起来就不会那么清爽了。我在使用过程中最觉得方便的是创建了一个几百行的表格,因为表格很长,所以需要每隔20行插入一行表头,用这个技术实在是简化好多重复工作。

 

  要使用很简单,就是调用 generateElements ,并传入两个参数,一个是容器DOM对象,一个是要创建的节点描述信息。描述信息对象是一个纯js对象,其中:

 

  • 必须包含 nodeName 或者 tagName 字段,值为 要创建的DOM对象的 nodeName 值,比如 "table","div"等
  • 其他属性会被直接赋予给DOM对象的属性中
  • 如果包含 children 属性,则该属性对应的值将会作为子元素创建
generateElements(parentDomElement, options)的参数和使用组合描述如下:
  • parentDomElement:可选,存放生成节点的容器对象
    • 参数存在,则自动将生成的元素直接加入到容器对象中,然后将创建的元素同时返回给调用者
    • 如果省略,则仅仅帮助创建DOM元素,然后返回给调用者
  • options:根据内容创建DOM元素
    • 类型为数组:则每一个数组元素都是一个option对象,最终生成一组DOM元素
    • 类型为对象:参考 option 对象的定义,生成一个DOM元素

 

option对象字段定义:

 

  • nodeName 或 tagName:必须,为DOM对象对应的tag值
  • children:子元素定义
    • 类型为数组:则每一个数组元素都是一个 option 对象,表示包含多个子元素
    • 类型为对象:参考 option 对象定义,表示包含单个子元素
  • 其他属性:直接复制到DOM对象中,不支持递归嵌套复制,比如 style.backgroundColor这种形式就无法复制到DOM对应的style属性的backgroundColor中去
其他话就不多说了,上代码:

 

// return element that generated
function generateElements(parentElem, info)
{
    if( parentElem == null ) return null;
    if( info == null )
    {
        if( parentElem.ownerDocument == document ) return null;
        info = parentElem;  // means single argument
        parentElem = null;
    }

    if( info instanceof Array )
    {
        var elems = [];
        for(var i = 0; i < info.length; ++i)
            elems.push(generateElements(parentElem, info[i]));
        return elems;
    }
    else
    {
        var pName = parentElem? parentElem.nodeName.toLowerCase(): "";
        var nodeName = (info.nodeName||info.tagName).toLowerCase();

        var fnCreate = function(p, n){return document.createElement(n);};
        var fnAppend = function(p, el){p.appendChild(el);};

        if( "table" == pName )
        {
            fnAppend = empty;
            if( "thead" == nodeName )
                fnCreate = function(p, n){ return p.createTHead(); };
            else if( "tfoot" == nodeName )
                fnCreate = function(p, n){ return p.createTFoot(); };
            else if( "tr" == nodeName )
                fnCreate = function(p, n){
                    return p.insertRow(-1);
                };
            else
                fnCreate = empty;
        }
        else if( indexOfArray(["tbody", "thead", "tfoot"], pName) != -1 )
        {
            fnAppend = empty;
            if( "tr" == nodeName )
                fnCreate = function(p, n){
                    return p.insertRow(-1);
                };
            else
                fnCreate = empty;
        }
        else if( "tr" == pName )
        {
            if( "td" == nodeName )
            {
                fnCreate = function(p, n){ return p.insertCell(-1); };
                fnAppend = empty;
            }
        }

        var elem = fnCreate(parentElem, nodeName);
        if( elem )
        {
            // fill properties
            var filtered_props = ["children", "nodeName", "tagName", "children"];

            for(var prop in info)
            {
                if( prop.length > 0 && prop.charAt(0) != '_' && indexOfArray(filtered_props, prop) == -1)
                    elem[prop] = info[prop];
            }
            // create children
            if( info.children )
                generateElements(elem, info.children);
            // append child
            if( parentElem )
                fnAppend(parentElem, elem);
        }

        return elem;
    }

}
 

以上代码还存在有如下需要改进的地方:

 

  1. 属性的设置没有使用标准的 setAttribute,但是目前在ie、ff和chrome中都好使
  2. 直接 return 已经创建的DOM对象,是否会造成内存泄漏?我没有去测试。
  3. 支持属性的嵌套设置,即应该能够将 style.xxx 直接设置到 DOM的 Style 属性中
在使用过程中,使用者一定要谨慎使用,因为我发现似乎 jQuery 没有包含这个功能,不知道是什么原因,也许能诱发内存泄漏?

 

 

 

0
1
分享到:
评论

相关推荐

    javaScript 生成DOM 对象(html标签).rar

    在“JavaScript 动态生成.txt”中可能包含了关于如何动态生成和操作DOM的具体示例代码,比如创建表单元素、添加事件监听器等。这些技巧在构建交互式网页时非常实用。 在实际应用中,我们还常常需要处理嵌套的DOM...

    JsObjExporter:一个小JavaScript插件,仅从前端就可以从JavaScript对象或DOM元素生成PDF,XLS,CSV和DOC!

    :dizzy: JavaScript对象到csv,xls,pdf,doc和DOM到html生成器 :dizzy: 一个小小JavaScript插件只能从前端从JavaScript Object或DOM元素生成PDF,XLS,CSV和DOC!演示版请导航到以下演示以测试此库:安装您可以从...

    javascript_DOM操作

    在JavaScript中,我们可以利用DOM API来创建、修改、删除和查找网页上的任何元素,实现动态更新和交互。 **DOM的基本操作** 1. **获取元素**: `document.getElementById()` 是最基础的获取元素方法,通过ID查找。...

    jquery对象和dom对象

    当你通过JavaScript的`document.getElementById`、`document.querySelector`或`document.querySelectorAll`等方法获取到的元素时,返回的就是DOM对象。DOM对象拥有原生的JavaScript属性和方法,如`innerHTML`、`...

    angularjs,ng-repeat循环渲染时,无法获取dom对象.pdf

    在`ng-repeat`循环渲染过程中,直接获取DOM对象可能会遇到困难,因为`ng-repeat`的渲染是动态进行的。循环内部的元素在每次数据模型更新时都可能发生变化,如果在数据更新后立即尝试获取DOM元素,那么获取到的可能是...

    domtoimage使用HTML5canvas从DOM节点生成图像

    5. **JavaScript事件处理**:在生成图像后,可能会结合JavaScript的事件监听器,如点击事件,来触发图像的生成和下载,提供用户友好的交互体验。 6. **Web性能优化**:转换DOM到图像可能会涉及大量计算,因此理解...

    JavaScriptDOM编程艺术.rar

    结合标签"js css",书中可能还会涉及CSS与JavaScript的交互,例如动态修改样式,通过JavaScript实现CSS动画,或者利用JavaScript操纵CSS预处理器(如Sass或Less)生成的样式。 通过阅读《JavaScript DOM编程艺术》...

    [JavaScript.DOM高级程序设计](加)桑贝斯.扫描版.part1.rar

     3.6.1 DOM生成工具的HTML文件   3.6.2 使用示例HTML片段进行测试   3.6.3 扩充ADS库   3.6.4 generateDOM对象的框架   3.7 小结   第4章 响应用户操作和事件   4.1 DOM2级事件   4.2 事件的...

    C#使用domtoimage生成图片保存服务器

    4. **调用dom-to-image方法**:在JavaScript中,调用`domtoimage.toPng()`或`domtoimage.toJpeg()`方法,传入DOM元素和配置对象,生成Base64编码的图片数据。 5. **将图片数据发送回C#**:在JavaScript执行完成后,...

    DOMBuilder, 具有多种输出格式的DOM生成器.zip

    DOMBuilder, 具有多种输出格式的DOM生成器 DOMBuilder 在JavaScript中动态创建HTML内容,并支持从相同的输入生成多种类型的输出,这 DOMBuilder 。是的,有一百万个构建库。 DOMBuilder的目标是:让编写可以在前端和...

    JavaScript 第三章 DOM编程基础 使用document对象

    在实际应用中,例如“简单树形菜单素材”,可能涉及到使用JavaScript动态创建和控制DOM元素,通过点击事件改变元素的`display`或`visibility`属性来实现菜单的展开和折叠效果。 复习框全选效果素材可能涉及`...

    domchef使用JSX自动构建DOM元素

    DOMChef适用于任何需要动态生成DOM的场景,比如数据驱动的用户界面、富文本编辑器或者DOM操作工具。它尤其适合那些不使用React或其他提供JSX的库,但仍想利用JSX简洁性的项目。 ### 学习与实践 要深入了解DOMChef...

    JS动态创建DOM元素的方法

    本文将详细解释如何使用JavaScript动态创建DOM元素及其相关事件的绑定与删除方法。 首先,让我们来了解DOM是什么。DOM是HTML文档的一个树状结构表示,每个HTML元素都可以被看作是树上的一个节点。通过DOM,开发者...

    jQuery为动态生成的select元素添加事件的方法

    7. 绑定事件到动态元素:文章最后部分展示了如何为动态生成的select元素绑定事件处理器。通过`$.on()`方法,即使元素是后来添加到页面中的,我们依然可以捕捉到它们的事件。在这个例子中,为ID以`"sl_0"`开头的...

    JavaScript特效大全+网页代码自动生成器

    JavaScript特效大全和网页代码自动生成器是一套强大的资源,对于前端开发者,特别是专注于JavaScript的工程师来说,这是一个不可多得的工具集。JavaScript是一种广泛应用于网页动态效果和交互设计的脚本语言,它使得...

    IE Dom 0day 生成器 修正版

    **IE DOM 0day 生成器 修正版** 在网络安全领域,0day 漏洞是一种尚未被公开或未被软件供应商修复的安全漏洞。当这种漏洞被恶意利用时,它可以导致严重的安全问题,因为防御者没有预先的知识来防范。"IE DOM 0day ...

    javascript经典特效---动态按钮代码生成器2.rar

    总的来说,“动态按钮代码生成器2”这个工具利用了JavaScript的核心特性,结合DOM、事件处理、样式控制等多个方面,为开发者提供了一个便捷的方式来创建具有动态效果的按钮,提高了开发效率。通过深入理解这些知识点...

    javascript经典特效---动态按钮代码生成器.rar

    总的来说,JavaScript动态按钮代码生成器是提高开发效率、实现个性化设计的利器,它可以帮助开发者快速创建具有视觉吸引力的交互元素,增强网站或应用程序的用户体验。使用此类工具时,理解基本的JavaScript原理和...

    javascript经典特效---日历生成器.rar

    JavaScript经典特效——日历生成器是一个常见的前端开发实践,它主要利用JavaScript动态生成网页上的日历展示,方便用户查看和选择日期。在这个压缩包中,包含了一个名为"日历生成器.htm"的文件,这很可能是实现日历...

    原生JS经典小项目-DOM练习

    在本项目"原生JS经典小项目-DOM练习"中,我们将深入探讨JavaScript与DOM(文档对象模型)的交互,这是Web开发中的核心技能。DOM是HTML和XML文档的编程接口,它允许我们通过JavaScript来查找、修改和操作页面元素。在...

Global site tag (gtag.js) - Google Analytics