Javascript元編程建立DOM節點

來源:互聯網
上載者:User

在使用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="Google搜尋" target="_blank" rel="xxxxx" costom_attr="自訂屬性">搜尋</a>
var a = create_a({
    'href': 'http://www.google.com.hk',
    'title': 'Google搜尋',
    '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))
    }
} ();

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.