1

現在、反復ごとに DOM を更新するループがあります。これは悪い習慣であり、速度を向上させるために DOM の更新をできるだけ少なくする必要があることを学びました。

だから私は以下をどのように編集して、すべての要素を1つの要素または何かに保存し、ループが終了したら単一の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++;
            }

        }

    }
4

6 に答える 6

4

ループ内で DOM 要素を操作するのは遅くなります - それらをドキュメントに添付するかどうかに関係なく。再描画のみが必要なため、最後にそれらを取り付けると少し速くなりますが、それでも遅いです。

適切な方法は、HTML を含む単純な古い文字列を生成しinnerHTML、DOM 要素のプロパティを使用してこの文字列を DOM にアタッチすることです。

于 2011-04-04T21:35:30.077 に答える
1

今日の初めからこれを見ているかもしれません。

それが役立つかどうかはわかりませんが、トピックは十分に近いです:-) documentFragmentまたはインメモリ要素を使用してDOMインメモリに要素を追加することについての議論です。

于 2011-04-04T21:46:55.307 に答える
1

あなたのコードは問題ないはずです。Javascript の実行が完了するまで、DOM は実際には再描画されません。ただし、パフォーマンスの悪いブラウザに遭遇した場合はselect、ループの前にまだ DOM にアタッチされていない新しいループを作成し、現在のように入力してから、最後sel_catsにその新しいものに置き換えることができますselect。そうすれば、DOM は 1 回だけ更新されます。

于 2011-04-04T21:34:59.980 に答える
0

あなたのコードは非常に肥大化しており、DOM0メソッドははるかに高速になります。

速度が本当に重要な場合は、spot + batchSize && i <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++;
        }
    }
}
于 2011-04-05T01:20:25.133 に答える