簡體   English   中英

任何返回DOM片段的JavaScript模板庫/系統/引擎/技術?

[英]Any JavaScript templating library/system/engine/technique that returns a DOM fragment?

我必須制作一個高速的Web應用程序,並且需要一個JavaScript模板庫/ system / engine / technique,該模板可以返回DOM片段而不是包含HTML的String。

當然,它應該具有與Resig的Micro-Templating類似的語言

編譯后,我期望這樣的事情:

function myTemplate(dataToRender){
    var fragment = document.createDocumentFragment();
    fragment = fragment.appendChild(document.createElement('h1'));
    fragment.appendChild(document.createTextNode(dataToRender.title));
    fragment = fragment.parentNode;
    fragment = fragment.appendChild(document.createElement('h2'));
    fragment.appendChild(document.createTextNode(dataToRender.subTitle));
    fragment = fragment.parentNode;
    return fragment;
}

有什么選擇嗎?

編輯:模板函數不應連接HTML字符串。 它降低了速度。 JQuery模板在內部使用字符串。 因此,Resig的微模板化。

Edit2:我剛剛在jsPerf上做了一個基准測試。 這是我在JavaScript中進行的第一個基准測試,因此有人可以檢查一下(我不確定它是否正確)。

查看jQuery模板。 http://api.jquery.com/category/plugins/templates/

它使您可以創建帶有“ if”,“ each”等關鍵字和未聲明變量的html片段。 然后,您可以使用一些值從JavaScript片段上調用“ tmpl”,並返回DOM元素。

我不知道這是否是您要搜索的內容,但是Underscore.js具有模板實用程序

而且,jquery可以返回匹配元素的DOM

您可以創建代表頁面區域的單個對象,甚至可以下降到單個元素級別,並且無需依靠太慢的DOM腳本即可完成所有這些操作。 例如:

function buttonFrag(data) {
    this.data = data;
}
buttonFrag.prototype = (function() {
    return {
        _html : function(h) {
            h.push("<h1>",data.title,"</h1>");
            h.push("<h2>",data.subTitle,"</h2>");
        },
        render : function(id) {
            var html = [];
            this._html(html);
            document.getElementById.innerHTML = html.join("");
        }
    }
})();

為此,您只需創建一個新對象,然后將其render方法調用到頁面上的id即可:

var titleFragObj = new titleFrag({title: "My Title",subTitle: "My Subtitle");
titleFragObj.render("someId");

當然,您可以對render方法有更多的創意,並使用類似jQuery的方法寫入選擇器,然后使用.html或.append方法,如下所示:

render : function(selectorString, bAppend) {
    var html = [];
    this._html(html);
    var htmlString = html.join("");
    var destContainer = $(selectorString);
    if (bAppend) {
        destContainer.append(htmlString);
    } else {
        destContainer.html(htmlString);
    }
}

在這種情況下,您只需要提供選擇器字符串,以及是否要附加到容器的末尾或完全替換其內容即可:

        titleFragObj.render("#someId",true);

您甚至可以創建一個基礎對象,所有片段都來自該基礎對象,然后您要做的就是覆蓋_html方法:

function baseFragement(data) {
        this.data = data;
    }
baseFragment.prototype = (function() {
    return {
        _html : function() {
            //stub
        },
        render : function(selectorString, bAppend) {
            var html = [];
            this._html(html);
            var htmlString = html.join("");
            var destContainer = $(selectorString);
            if (bAppend) {
                destContainer.append(htmlString);
            } else {
                destContainer.html(htmlString);
            }
        }
    };
})();

然后所有后代看起來像這樣:

function titleFrag(data) {
    baseFragment.call(this,data);
}
titleFrag.prototype = new baseFragment();
titleFrag.prototype._html = function() {
    h.push("<h1>",data.title,"</h1>");
    h.push("<h2>",data.subTitle,"</h2>");
}

您可以創建一個由小片段生成器組成的整個庫,這些片段生成器來自該通用基類。

我在這個jsFiddle中嘗試了一下 使用DOM方法時,替換大部分內容最快,但是如果模板不是很復雜並且不會在字符串操作上浪費太多時間,則設置innerHTML不會慢很多,並且可能可以接受。 (這並不奇怪,“快速處理損壞的HTML”是瀏覽器應該做的事情,而innerHTML是古老而流行的屬性,可能要進行很多優化。)在步驟中添加另一個join()步驟innerHTML方法也沒有真正減慢它的速度。

相反,在Mac上的Chrome中,使用jQuery.tmpl()和// DOM片段方法要慢幾個數量級。 我在dom_tmpl函數中做錯了dom_tmpl ,或者深度克隆DOM節點本來就很慢。

我注釋掉了附加測試,因為它們在您運行整個套件時會凍結選項卡過程-將成千上萬個節點塞入文檔可能會以某種方式使Chrome感到困惑。 單獨使用innerHTML追加時,結果變得很慢,因為該字符串實際上非常大。

結論似乎是:除非笨拙地或在非常大的字符串上完成,否則將字符串合並到模板庫中可能不會使它變慢 ,同時嘗試更聰明地克隆DOM塊。 另外, jQuery.tmpl()在我的計算機上處​​理2000 ish ops / sec,在我的iPhone 4上處理500 ish ops / sec,如果您瞄准這些平台,則可能“足夠快”。 它也與DOM片段功能處於同一局面,這使得后者在很大程度上毫無意義。

如果您最需要替換現有節點的內容並且模板不是很大,請使用Underscore.js的templating和innerHTML Underscore.js似乎在整個字符串中進行了十次傳遞,因此,如果模板/ are /大,則可能會出現問題。

如果需要附加到現有節點,則可以通過創建wrapper元素,設置其innerHTML ,然后將wrapper元素附加到目標節點來避免序列化和重新解析現有內容。

如果您確實想要速度或模板太龐大了,則可能需要做一些事情,例如讓服務器端腳本將模板預編譯為可創建各個節點的Javascript。

(免責聲明:我並沒有聲稱自己擅長構造測試用例和基准,僅在WebKit中對此進行了測試,您應該針對您的用例進行定制,並獲得更多相關的數字。)

更新:更新了jsFiddle基准測試,使其不使用任何jQuery功能,以防它的存在(節點上的用戶數據等)是DOM節點克隆緩慢的原因。 沒什么幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM