簡體   English   中英

使用JavaScript過濾客戶端項目,隱藏或從DOM中刪除的最佳實踐?

[英]Best practice for filtering items client-side with JavaScript, hide or remove from DOM?

我有一個相對較大的項目數據集(幾千個項目),我想通過在Web應用程序中應用多個過濾器客戶端來導航。 應用過濾邏輯本身不是問題,問題是使用哪種方法來更新匹配結果表以獲得最佳用戶體驗。 我提出的方法是:

  1. 設置每行的類以隱藏或顯示它(使用可見性:折疊以隱藏它),並將DOM元素保留在表中。
  2. 為每個數據項保留DOM元素,將其分離/附加到表以隱藏和顯示它。
  3. 只需為每個數據項保留一個抽象對象,根據需要創建一個DOM對象來顯示它。

哪一個可能會提供最佳用戶體驗? 除了我已經列出的那些之外的任何其他推薦方法?

如果顯示區域具有固定大小(或至少是最大大小),並且您必須在客戶端進行過濾,我不會為每個項目創建DOM節點,而是重用一組預定義的DOM節點作為模板 ,隱藏不必要的模板取決於過濾器的結果數量。 這將大大減少文檔中的DOM節點,這將使頁面呈現響應並且相當容易實現。

示例HTML *:

<ul id="massive-dataset-list-display">
    <li>
       <div class="field-1"></div>
       <div class="field-2"></div>
       <div class="field-n"></div>
    </li>
    <li>
       <div class="field-1"></div>
       <div class="field-2"></div>
       <div class="field-n"></div>
    </li>
    <li>
       <div class="field-1"></div>
       <div class="field-2"></div>
       <div class="field-n"></div>
    </li>
    .
    .
    .
</ul>

示例JavaScript *:

var MassiveDataset = function(src) {
    var data          = this.fetchDataFromSource(src);
    var templateNodes = $("#massive-dataset-list-display li");

    // It seems that you already have this handled, but just for 
    // completeness' sake
    this.filterBy(someParam) {
        var filteredData = [];
        // magic filtering of `data` 
        this.displayResults(filteredData);
    };

    this.displayResults(filteredData) {
        var resultCount = filteredData.length;

        templateNodes.each(function(index, node) {
            // There are more results than display node templates, start hiding
            if ( index >= resultCount ) {
                $(node).hide();
                return;
            }

            $(node).show();
            this.formatDisplayResultNode(node, filteredData[i]);
        });
    };

    this.formatDisplayResultNode = function(node, rowData) {
        // For great justice
    };
};

var md = new MassiveDataset("some/data/source");
md.filterBy("i can haz filter?");

*未經測試。 不要指望復制/粘貼工作,但那會很酷。

添加一個類並使用CSS來顯示/隱藏元素可能是最快的(編碼和性能方面),特別是有這么多項目。

如果您想要進行DOM操作路由,請考慮離線編輯DOM。 在內存中緩存DOM樹(局部變量),更新所有行並替換原始DOM節點。 有關此問題的更多信息,請參見http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5


我做了一個項目,需要在Google地圖“視口”中的位置過濾項目和最小 - 最大值滑塊(對於那些好奇的,它是針對房地產網站的)。

第一個版本使用AJAX請求獲取所有(服務器端)過濾項,因此過濾器中的每個更改都請求新數據。 然后將JSON數據解析為DOM節點並添加到文檔中。 此外,在這種情況下,項目的搜索引擎索引是不可能的。

第二個版本也使用了AJAX請求,但這次只請求過濾的項目ID。 所有項目都存在於HTML中,並帶有唯一ID,過濾后的項目有一個額外的類名稱,可以最初隱藏它們。 每當過濾器更改時,僅請求過濾的ID,並相應地更新項目的類名稱。 這顯着提高了速度,特別是在Internet Explorer(我們支持的瀏覽器中使用最慢的JavaScript引擎 - )中......

我意識到這並不是你所要求的,但是因為你打開了替代品的大門......

你有沒有考慮過任何過濾服務器端? 如果用戶更改過濾選項,您可以使用AJAX加載結果,這樣,當您可能只顯示其中的一部分時,您不會將數千行數據加載到瀏覽器中。 它可能會保存您和訪問者帶寬,但這取決於您的網站如何被真正使用。

基本上,如果您提前決定要顯示哪些數據,則不必經歷挑選那些數據的麻煩。

我知道這可能不符合您的需求,但如果您堅持客戶端的想法,我會提供它作為建議。

DOM操作對於“幾千個項目”來說太慢了。 假設你有一個非常非常好的理由為什么你沒有讓服務器進行過濾,那么我發現的最佳解決方案是對XML保存的數據使用客戶端XSL轉換。

即使在相當大的數據集上,變換本身也非常快。 然后,您最終將結果分配給包含DIV的innerHTML屬性,您希望表格顯示在該屬性中。 使用innerHTML進行DOM中的大型更改比使用Javascript操作DOM更快。

編輯 :賈斯汀約翰遜的評論答案: -

如果數據集很大,那么XML可能會變得非常龐大。

注意我已經在我的第一段中提出了關於在此處獲取服務器幫助的免責聲明。 這里可能有一種情況是切換設計並合理使用AJAX,或者根本不嘗試一次顯示大量數據。 但是我正在盡力回答提出的問題。

值得考慮的是,“野獸大”至少是帶寬的函數。 在連接良好的Intranet Web應用程序中,帶寬並不是很高。 此外,我已經看到並使用了隨着時間的推移構建和重用緩存XML的實現。

此外,如果將XML轉換為DOM對象,這又如何更好?

我建議的技術與Javascript直接進行DOM操作之間存在巨大差異。 考慮當javascript中的代碼修改DOM時,底層引擎無法知道其他更改將立即跟隨,也不能確定javascript不會立即檢查DOM的其他屬性。 因此,當通過Javascript對DOM進行更改時,瀏覽器需要確保它更新所有類型的其他屬性,以便它們與完成的呈現一致。

然而,當innerHTML被分配了一個大的HTML字符串時,瀏覽器可以很愉快地創建一大堆DOM對象而不進行任何重新計算,它可以推遲對各種屬性值的大量更新,直到構建完整個DOM之后。 因此,對於大規模的改變,innerHTML將直接將DOM操縱從水中吹走。

暫無
暫無

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

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