zoukankan      html  css  js  c++  java
  • Javascript元编程创建DOM节点

    在使用javascript创建DOM节点的过程中,难免要使用document.createElement、setAttribute、 document.createTextNode等冗长、还有浏览器兼容性问题的节点操作方法,虽然有人提议使用字符串拼接后,再使 用.innerHTML=可以降低创建节点的成本,而且还有更好的性能,但在我印象中innerHTML并不能适应所有需求(具体神马需求我也忘了),所 以下面给大家介绍一种使用javascript元编程技巧来动态创建节点的方法。
    那么什么是元编程呢?了解Ruby的同学知道,Ruby的风靡离不开Ruby on Rails(RoR)框架的推动。RoR框架通过魔幻实现质朴的方式,把很多需要用其他语言实现的功能用Ruby来实现,最经典当属RoR框架的 ActiveRecord。让我们看一下下面这段代码:

    person = Person.find_by_email('xxx@x1989.com')
    person.age = 23
    person.save
    上述代码可以用SQL语句替换,如下所示:

    SELECT * FROM person WHERE email = 'xxx@x1989.com'
    UPDATE person SET age = 23 WHERE email = 'xxx@x1989.com'
    即使不会Ruby和SQL的人也可以看出,采用Ruby语法方式更自然。而正是Rails通过元编程技巧,让我们无须在一个程序中混用两种不同的语言。元编程的定义:
    <blockquote>元编程是指某类计算机程序的编写,这类计算机程序编写或者操纵其它程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作。</blockquote>
    那么,我希望用javascript实现"create_"+任意HTML5标签名的动态节点生成函数,比如用create_form、create_div、create_input来生成对应名称的节点,使用下面的api:

    //①创建只含有文本的节点
    //<span>hello world</span>
    var span = create_span('hello world');
    //<br />
    var br = create_br();

    //②可以在参数1中以对象字面量来定义属性
    //<input type="text" size="20" value="123" />
    var input = create_input({
        'type': 'text',
        'size': 20,
        'value': '123'
    })
    //③用参数2定义文本节点
    //<a href="http://www.google.com.hk" title="谷歌搜索" target="_blank" rel="xxxxx" costom_attr="自定义属性">搜索</a>
    var a = create_a({
        'href': 'http://www.google.com.hk',
        'title': '谷歌搜索',
        'target': '_blank',
        'rel': 'xxxxx',
        'costom_attr': '自定义属性',
    }, '搜索');

    //④参数2可以是节点 参数3(可选)是文本节点
    //<div><img src="http://www.google.com.hk/intl/zh-CN/images/logo_cn.png">这是logo</div>
    var div = create_div({}, create_img({'src': 'http://www.google.com.hk/intl/zh-CN/images/logo_cn.png'}), '这是logo')

    //⑤参数2也可以是节点构成的数组
    //<ul class="list1"><li>项目1</li><li>项目2</li><li>项目3</li></ul>
    var ul = create_ul({
        'class': 'list1'
    }, [create_li('项目1'), create_li('项目2'), create_li('项目3')]);
    实现方式:

    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))
        }
    } ();

  • 相关阅读:
    hihoCoder #1062 : 最近公共祖先·一
    hihoCoder #1050 : 树中的最长路
    hihoCoder #1049 : 后序遍历
    108 Convert Sorted Array to Binary Search Tree 将有序数组转换为二叉搜索树
    107 Binary Tree Level Order Traversal II 二叉树的层次遍历 II
    106 Construct Binary Tree from Inorder and Postorder Traversal 从中序与后序遍历序列构造二叉树
    105 Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树
    104 Maximum Depth of Binary Tree 二叉树的最大深度
    102 Binary Tree Level Order Traversal 二叉树的层次遍历
    101 Symmetric Tree 判断一颗二叉树是否是镜像二叉树
  • 原文地址:https://www.cnblogs.com/sky7034/p/2110344.html
Copyright © 2011-2022 走看看