7

アイテムを選択してから、リスト内でそれらのアイテムを並べ替えることができる「上へ」または「下へ」ボタンをクリックできる複数選択リストの作成に取り組んでいます。

私は簡単な自己完結型の例を持っています:

<html>
    <head>
        <title>Example</title>
    <script src="https://www.google.com/jsapi"></script>
    <script>
        google.load('jquery', '1.4.1');
    </script>
    </head>
    <body>
        <select id="selectedDataPoints" multiple="multiple">
            <option>Pig</option>
            <option>Duck</option>
            <option>Dog</option>
            <option>Zebra</option>
            <option>Snake</option>
            <option>Giraffe</option>
            <option>Cow</option>
        </select>
    <input type="button" id="btnReorderUp"  value="Up" />
    <input type="button" id="btnReorderDown" value="Down" />
    </body>
</html>

<script type="text/javascript">
    var DataPointSelector = (function() {

    var $selectedList = $('#selectedDataPoints');

        $('#btnReorderUp').click(function(e) {
            moveUp();
            e.preventDefault();
        });

        $('#btnReorderDown').click(function(e) {
            moveDown();
            e.preventDefault();
        });

    function moveUp() {
            var select = $selectedList[0];
            for (var i = 1, n = select.options.length; i < n; i++)
                if (select.options[i].selected && !select.options[i - 1].selected)
                select.insertBefore(select.options[i], select.options[i - 1]);
        }

        function moveDown() {
            var select = $selectedList[0];
            for (var i = select.options.length - 1; i > 0; i--)
                if (select.options[i].selected && !select.options[i + 1].selected)
                    select.insertBefore(select.options[i + 1], select.options[i]);           
        }

    } ());
</script>

ただし、上/下ボタンが IE7/8 で有効になるまでには文字通り 3 ~ 8 秒かかります。最初のクリックは速い場合もありますが、その後、選択リストが新しい位置で更新されるまでに非常に長い時間がかかります (特にいくつかのアイテムが選択されている場合)。

この問題は Chrome/FF には存在しません。この単純な並べ替えがこれほど手間がかかるとは思いませんでした。

moveUp/moveDown関数を高速化するために使用できる情報を誰かが持っていますか?!

4

2 に答える 2

4

既存の DOM 要素を移動する代わりに、<select>IE のすべての子を含む要素全体を再作成します。

于 2010-11-16T15:42:57.353 に答える
2

IEは遅い、遅い、遅い。そのため、コードをチェックして、不要な操作を最小限に抑える必要があります。

@Arron Digullaのアイデアは良いです。ただし、次の変更によってプロセッサ時間を最小限に抑えることもできます。

function moveUp() {
  var select = $selectedList[0];
  for (var i = 1, n = select.options.length; i < n; i++)
    var selected = select.options[i],
        selectedPrior = select.options[i - 1]; 
        // Don't locate obj/array element more than once
    if (selected.selected && !selectedPrior.selected) {
      select.insertBefore(selected, selectedPrior);
      break; // Since we have found the right elements, don't do 
    }        // any further checking
  }

追加: うーん、複数のアイテムを選択できるようになりました。それで、複数のアイテムを移動する必要がありますよね?その場合、break ステートメントは正しくありません。

IE の UI レイヤーが足を引っ張っていませんか? -- IE は、JS スレッドが終了するまで画面の外観を更新しない傾向があります。回避策は、タイマーを 0 秒で実行することです。これにより、IE レンダリング エンジンが処理され、画面を更新できるようになります。

于 2010-11-16T15:50:53.623 に答える