将元素存储在内存中以防止过于频繁地更新 DOM?

发布于 2024-10-30 02:21:39 字数 1231 浏览 5 评论 0原文

目前我有一个循环在每次迭代中更新 DOM;我知道这是一种不好的做法。为了提高速度,你应该尽可能少地更新 DOM。

所以我想知道如何编辑下面的内容,以便我可以将所有元素存储在一个元素或其他元素中。然后在循环结束后执行一次 DOM 添加。

这是循环..

    for (var i = spot; i < spot + batchSize && i < cats.options.length; i++) {

        // Check if the cat is selected

        if (cats.options[i].selected == true) {

            // Set this category's values to some variables
            var cat_id = cats.options[i].getAttribute('value');
            var cat_name = cats.options[i].text;     

            if (checkCatSICAdd(cat_id) === false) {           

                // Now we create the new element
                var new_option = document.createElement('option');

                // Add attribute
                new_option.setAttribute('value',cat_id);

                // Create text node
                var new_text_node = document.createTextNode(cat_name);

                // Append new text node to new option element we created
                new_option.appendChild(new_text_node);

                // Append new option tag to select list
                sel_cats.appendChild(new_option);

            } else {
                failed++;
            }

        }

    }

Currently I have a loop that updates the DOM in each iteration; I have learned this is a bad practice & you should update the DOM as little as possible for better speed.

So I was wondering how I go about editing the below so I can store all the elements in one element or something & then do a single DOM addition once the loop ends.

Here is the loop..

    for (var i = spot; i < spot + batchSize && i < cats.options.length; i++) {

        // Check if the cat is selected

        if (cats.options[i].selected == true) {

            // Set this category's values to some variables
            var cat_id = cats.options[i].getAttribute('value');
            var cat_name = cats.options[i].text;     

            if (checkCatSICAdd(cat_id) === false) {           

                // Now we create the new element
                var new_option = document.createElement('option');

                // Add attribute
                new_option.setAttribute('value',cat_id);

                // Create text node
                var new_text_node = document.createTextNode(cat_name);

                // Append new text node to new option element we created
                new_option.appendChild(new_text_node);

                // Append new option tag to select list
                sel_cats.appendChild(new_option);

            } else {
                failed++;
            }

        }

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

醉态萌生 2024-11-06 02:21:39

在循环中使用 DOM 元素的速度很慢 - 无论您是否将它们附加到文档中。将它们附加到最后会快一点,因为只需要重绘,但仍然很慢。

正确的方法是生成一个包含 HTML 的普通旧字符串,并使用 DOM 元素的 innerHTML 属性将此字符串附加到 DOM。

Working with DOM element in the loop is slow - no matter if you attach them to the document or not. Attaching them at the end is a bit faster since only only redraw is required but it's still slow.

The proper way is generating a plain old string containing HTML and attaching this string to the DOM using the innerHTML property of a DOM element.

○愚か者の日 2024-11-06 02:21:39

你的代码应该没问题。在 Javascript 执行完毕之前,DOM 实际上不会重绘。但是,如果您遇到性能不佳的问题浏览器,您可以尝试在循环之前创建一个尚未附加到 DOM 的新 select,按现在的方式填充它,然后替换sel_cats 并在末尾添加新的 select。这样,DOM 只更新一次。

Your code should be ok. The DOM won't actually redraw until the Javascript has finished executing. However, if you've encountered a problem browser that does perform badly, you could try creating a new select before your loop that is not yet attached to the DOM, populating it as you are now, then replacing sel_cats with that new select at the end. That way, the DOM is only updated once.

起风了 2024-11-06 02:21:39

你的方法已经足够好了,除非你有很多项目添加到 sel_cats 中 - 你只添加到 DOM 一次。

提高效率的唯一方法可能是将选项存储为原始 HTML,然后在循环后分配:

var arrHTML = [];
for (var i = spot; i < spot + batchSize && i < cats.options.length; i++) {
    // Check if the cat is selected
    if (cats.options[i].selected == true) {
        // Set this category's values to some variables
        var cat_id = cats.options[i].value;
        var cat_name = cats.options[i].text;     
        if (checkCatSICAdd(cat_id) === false) {           
            arrHTML.push("<option value=\"" + cat_id + "\">" + cat_name + "</option>";
        }
        else {
            failed++;
        }
    }
}
sel_cats.innerHTML = arrHTML.join("");

Your way is good enough unless you have great many items added to sel_cats - you add to the DOM only once.

The only way to improve efficiency might be to store the options as raw HTML then assign that after the loop:

var arrHTML = [];
for (var i = spot; i < spot + batchSize && i < cats.options.length; i++) {
    // Check if the cat is selected
    if (cats.options[i].selected == true) {
        // Set this category's values to some variables
        var cat_id = cats.options[i].value;
        var cat_name = cats.options[i].text;     
        if (checkCatSICAdd(cat_id) === false) {           
            arrHTML.push("<option value=\"" + cat_id + "\">" + cat_name + "</option>";
        }
        else {
            failed++;
        }
    }
}
sel_cats.innerHTML = arrHTML.join("");
月朦胧 2024-11-06 02:21:39

将选择列表分配给变量后,使用其父标签上的removeChild将其从dom中删除。然后,您可以在将选择列表添加回 dom 之前在循环中使用appendChild。

Once you have the select list assigned to a variable, remove it from the dom using removeChild on its parent tag. You can then use appendChild in the loop before adding the select list back into the dom.

神爱温柔 2024-11-06 02:21:39

你的代码太臃肿了,DOM 0 方法会快得多。

如果速度确实很重要,则存储现货+批量大小&&我< cats.options.length 在变量中,这样它们就不会在每个循环中重新计算(现代浏览器可能不会,但旧浏览器会这样做):

for (var i=spot, j=spot+batchSize, k=cats.options.length; i < j && i < k; i++) {

    // Store reference to element
    var opt = cats.options[i];

    // The selected property is boolean, no need to compare
    if (opt.selected) {

        // if checkCatSICAdd() returns boolean, just use it
        // but maybe you need the boolean comparison
        if (checkCatSICAdd(opt.name) === false) {

            // Wrapped for posting
            sel_cats.options[sel_cats.options.length] = 
                                         new Option(opt.value, opt.name);

        } else {
            failed++;
        }
    }
}

Your code is way bloated, DOM 0 methods will be much faster.

If speed really matters, store spot + batchSize && i < cats.options.length in variables so they aren't re-calcuated on each loop (modern browsers probably don't, but older ones did):

for (var i=spot, j=spot+batchSize, k=cats.options.length; i < j && i < k; i++) {

    // Store reference to element
    var opt = cats.options[i];

    // The selected property is boolean, no need to compare
    if (opt.selected) {

        // if checkCatSICAdd() returns boolean, just use it
        // but maybe you need the boolean comparison
        if (checkCatSICAdd(opt.name) === false) {

            // Wrapped for posting
            sel_cats.options[sel_cats.options.length] = 
                                         new Option(opt.value, opt.name);

        } else {
            failed++;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文