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

  • 相关阅读:
    八皇后问题--------------------递归回溯
    排序算法06------------------------插入排序
    无重复字符最长子串----------------滑动窗口法
    排序算法05------------------------堆排序(图解)
    排序算法04------------------------归并排序
    图形学基础(一)光栅图形学_下:剪裁
    计网Top-Down 抄书笔记(二)——应用层
    图形学基础(二)图形变换_下:3D 平行投影
    图形学基础(二)图形变换_上:2D 基本变换/复合变换
    图形学基础(一)光栅图形学_上:画直线/圆、区域填充
  • 原文地址:https://www.cnblogs.com/sky7034/p/2110344.html
Copyright © 2020-2023  润新知