createDocumentFragment()在用于循环createDocumentFragment

2023-09-10 15:01:37 作者:有一种冷゛透心凉ˇ

是 createDocumentFragment()在做下面的code什么?

我在努力适应这种code。我不知道它是如何工作和循环似乎并没有对 tableFrag 调用。您的见解?

 函数CREATETABLE(SearchResult所)
{
    VAR results_table =
        的document.getElementById(report_results)的getElementsByTagName(表)[0];

    VAR NEWLINK,tableFrag;
    tableFrag = document.createDocumentFragment();
    tableFrag.appendChild(results_table);

    对于(result_index在searchResults.results)
    {
        NEWROW = results_table.getElementsByTagName(TBODY)[0] .insertRow(-1);

        newCell = newRow.insertCell(-1);
        newCell.appendChild(document.createTextNode(searchResults.results [result_index] [得分]));

        newCell = newRow.insertCell(-1);
        NEWLINK = document.createElement方法(一);
        newLink.href =
            ?officer.php officer_seq =+ searchResults.results [result_index] [officer_seq];
        newLink.appendChild(document.createTextNode(searchResults.results [result_index] [officer_id]));
        newCell.appendChild(NEWLINK);

        NEWROW = NULL;
    }
    的document.getElementById(report_results)的appendChild(tableFrag)。
}
 

具体而言,有什么神秘化我的是 tableFrag 不是在循环中:

 的(result_index在searchResults.results)
    {
        ...
        tableFrag此有或那
        ...
    }
    的document.getElementById(report_results)的appendChild(tableFrag)。
 

解决方案

是的,它做的东西:一个性能优化

HTML文档中的元素保存在一个树数据结构的,您可以通过DOM接口访问(即方法,如的document.getElementById(id)的 document.getElementsByClassName()每当这棵树被操纵,即当您插入,删除或通过JavaScript code修改节点,浏览器的渲染引擎必须的重新布局的箱子(这也被称为的回流的),这取决于利用CSS定义的规则,以及重绘的所述树的浏览器的窗口上的可见部分

一种用于方形锂离子电池的新型电池热管理系统

在你的情况,你不得不行的固定号码添加到表中。当循环开始时,你已经知道,你必须添加 N 行表。如果你简单地添加行的DOM元素,每次通话时间 table.appendChild(行)浏览器将测量,布局和油漆的页面,而这发生在最 N 倍(实际上浏览器扼杀这些代价高昂的操作,然而,这并不需要任何的规格,因此,我们可以假设的学习,每次你追加的目的,浏览器的无效的树并进行重新绘制)。

所有这些处理是不需要的:我们不希望浏览器明显的时间长了表中的一行,我们只是希望把在 N 行表,在一个单杆一的的交易,实物的。 的DocumentFragment 存在此确切目的:当你操纵一个片段的孩子,浏览器不会测量和布局什么。这只是发生,当你终于追加片段主要DOM。在我们的想象和简单的浏览器,油漆例行程序调用,而不是 N 次只有一次。

那么您的脚本不能是创建一个片段,从主DOM除去该表中,在将节点添加到所述片段,而它的附加到片段操纵表,最后加入整个片段回到主DOM中,当孩子们终于测,布局和彩绘。请注意,code没有明确地将删除DOM的表,但是这是当子节点已经属于什么 Node.appendChild(节点)方法不一些层次:

  

中添加一个节点到一个指定的父的儿童的列表的末尾   节点。如果该节点已经存在它是从当前父除去   节点,然后添加到新的父节点。

您可以阅读更多关于的DocumentFragment 上的 MDN 。

Is createDocumentFragment() doing anything in the code below?

I'm trying to adapt this code. I'm not sure how it works and the for loop doesn't seem to call on tableFrag. Your insights?

function createTable(searchResults)
{
    var results_table = 
        document.getElementById("report_results").getElementsByTagName("table")[0];

    var newLink, tableFrag;
    tableFrag = document.createDocumentFragment();
    tableFrag.appendChild(results_table);

    for (result_index in searchResults.results)
    {
        newRow = results_table.getElementsByTagName("tbody")[0].insertRow(-1);

        newCell = newRow.insertCell(-1);
        newCell.appendChild(document.createTextNode(searchResults.results[result_index]["score"]));

        newCell = newRow.insertCell(-1);
        newLink = document.createElement("a");
        newLink.href = 
            "officer.php?officer_seq="+searchResults.results[result_index]["officer_seq"];
        newLink.appendChild(document.createTextNode(searchResults.results[result_index]["officer_id"]));
        newCell.appendChild(newLink);

        newRow = null;
    }
    document.getElementById("report_results").appendChild(tableFrag);
}

Specifically, what mystifies me is that tableFrag is not found in the loop:

    for (result_index in searchResults.results)
    {
        ...
        tableFrag this-or-that
        ...
    }
    document.getElementById("report_results").appendChild(tableFrag);

解决方案

Yes, it's doing something: a performance optimization.

The elements in the HTML document are kept in a tree data structure, which you can access via the DOM interface (ie methods like document.getElementById(id) or document.getElementsByClassName(). Each time this tree is manipulated, ie when you insert, remove or modify nodes via Javascript code, the browser's rendering engine must relayout boxes (this is also called a reflow) depending on the rules defined with CSS, and repaint the visible portion of the tree on the browser's window.

In your case, you have to add a fixed number of rows to a table. When the loop starts, you already know that you have to add N rows to the table. If you simply add rows to the DOM element, every time you call table.appendChild(row) the browser will measure, layout and paint the page, and this happens at most N times (actually browsers throttles these costly operations, however this is not required by any spec, so we can assume for learning purposes that every time you append, the browser invalidates the tree and repaints).

All of this processing is unneeded: we don't want the browser to visibly grow the table one row at a time, we simply want to put N rows in the table, in one single shot, kind of a transaction. DocumentFragment exists for this exact purpose: when you manipulate a fragment's children, the browser doesn't measure and layout anything. This only happens when you finally append the fragment to the main DOM. In our imaginary and simplified browser, the paint routines are called exactly once, instead of N times.

So what your script does is creating a fragment, removing the table from the main DOM, adding the node to the fragment, manipulating the table while it's attached to the fragment, and finally adding the whole fragment back to the main DOM, when children are finally measured, laid out and painted. Note that the code doesn't explicitely removes the table from the DOM, but this is what the Node.appendChild(node) method does when the child node already belongs to some hierarchy:

Adds a node to the end of the list of children of a specified parent node. If the node already exists it is removed from current parent node, then added to new parent node.

You can read more about DocumentFragment on MDN.

相关推荐