0

コード:

http://jsfiddle.net/s4UQP/

^これがコードとそれがdivでどのように機能するかを確認するための最良の方法です

しかし、とにかくここにコードがあります:

function move(from, to) {

document.getElementById('progress').innerHTML = '...';

from = parseInt(from,10);
to = parseInt(to,10);

tbc = document.getElementById(from);
before = document.getElementById(to);
containr = document.getElementById('alldivs');

neworder = 'Order: <select><option onclick="move(' + to + ',1)">1</option><option onclick="move(' + to + ',2)">2</option><option onclick="move(' + to + ',3)">3</option></select> <br><a href="#" onclick="move(' + to + ',' + (to - 1) + ')">Send up</a> | <a href="#" onclick="move(' + to + ',' + (to + 1) + ')">Send down</a><br><a href="#" onclick="move(' + to + ',1)">Bring to front (#1)</a> | <a href="#" onclick="move(' + to + ',4)">Send to back (#4)</a>';

document.getElementById(from).getElementsByClassName('order')[0].innerHTML = neworder;

document.getElementById(from).getElementsByClassName('number')[0].innerHTML = to;

tempdiv = document.createElement('div');
tmphtml = document.getElementById(from).innerHTML;
tempdiv.className = 'holder';
tempdiv.innerHTML = tmphtml;

n = 0;
npieces = 4;


if (from < to) {
    nochanges = to - from;
    fromone = from + 1;
    //alert(n+' '+to+' '+fromone);
    for (n = fromone; n <= to; n++) {

        //alert('down');
        idnum = parseInt(document.getElementById(n).id,10);
        //alert(idnum);
        document.getElementById(n).getElementsByClassName('number')[0].innerHTML = (idnum - 1);
        alert(document.getElementById(n).id);
        document.getElementById(n).id = (idnum - 1);

        //alert('down '+idnum+' to '+(idnum-1));
    }

}

if (from > to) {
    nochanges = from - to;
    totone = to + 1;


    for (n = to; n < from; n++) {
        //alert('n is '+n+' going to '+to+' ends at '+totone);
        //alert('up');
        idnum = parseInt(document.getElementById(n).id,10);
        //alert(idnum);
        document.getElementById(n).getElementsByClassName('number')[0].innerHTML = (idnum + 1);
        alert(document.getElementById(n).id);
        document.getElementById(n).id = (idnum + 1);

        //alert('up '+idnum+' to '+(idnum+1));
    }

}


//tempdiv.id = 'span'+to;
if (from > to) {
    containr.insertBefore(tempdiv, before);
}

if (from < to) {
    before = to + 1;
    containr.insertBefore(tempdiv, document.getElementById(before));
}

tbc.parentNode.removeChild(tbc);

tempdiv.id = to;

document.getElementById('progress').innerHTML = 'done';

}

スクリプトは、ブロック(またはdiv)を上下に移動すると機能しますが、別のブロック(たとえば、一番上のブロック)を移動しようとすると、その下の最初の2つのブロックが切り替わります。誰かアドバイスをいただけますか?

スクリプトが実行された順序によるものなのか、それとも別のものなのかはわかりません。しばらく混乱していたので、誰かに見てもらいアドバイスをいただければ幸いです。

(jQueryでコーディングしたくないのですが、これは実際には、何かをコーディングしてJavaScriptをさらに学習しようとしているだけです。それが最も効率的で安全ではない場合でも、それでも自分自身に教えようとしているものです。 JavaScript。)

読んでくれてありがとう。(JS Fiddle自体を編集するのではなく、ここに編集/改善を投稿してください。ありがとうございます。)

[編集:私は実際には決まり文句のSFを書いているわけではありません。これ以上のことは考えられなかったので、単なる例のdivです]

4

1 に答える 1

2

ステートメントneworder =...では、関数の値を変更しますが、onclick移動しようとしているブロックに対してのみこれを行います。問題は、他のブロックも位置が変わることです。たとえば、ブロック 2 の [送信] をクリックすると、ブロック 2 が位置 1 に移動し、ブロック 1 が位置 2 に移動します。ただし、それに応じてブロック 2 のイベント ハンドラーのみが更新されます。そのため、次に (元は) ブロック 1 をクリックすると、正しく動作しなくなります。

解決策の 1 つは、ブロックの 1 つが移動されるたびに、影響を受けるすべてのブロックのイベント ハンドラーを更新することです。たとえば、呼び出される関数を作成しupdateEventHandlers(blockNumber)、影響を受けるすべてのブロックに対して呼び出します。

ただし、ブロックの位置を示すために ID に依存し、移動後に ID をいじると、あらゆる種類の混乱が生じる可能性があります。ブロックの位置を記録する配列または辞書を保持するか、ブロックを移動するたびにそれらをループして DOM 内の位置を決定することをお勧めします。

たとえば、次のコードは、後者のメソッドを使用して moveup、movedown、および moveto 関数を提供します (要素が DOM 内のどこにあるかを検出し、前または後にホルダーと交換します)。( JSFIDDLE )

function E(id) { return document.getElementById(id);}
var holders = document.getElementsByClassName('holder');
function moveup(id) {
    for (var i = 0; i < holders.length - 1; i++) {
        // Find the holder before the one we're interested in
        if (holders[i + 1] == E(id)) {
            // Swap their positions
            E('alldivs').insertBefore(E(id), holders[i]);
            break;
        }
    }
    resetNumbers();
}
function movedown(id) {
    for (var i = 1; i < holders.length; i++) {
        // Find the holder after the one we're interested in
        if (holders[i - 1] == E(id)) {
            // Swap their positions
            E('alldivs').insertBefore(holders[i], E(id));
            break;
        }
    }
    resetNumbers();
}
function moveto(id, position) {
    if (position == holders.length) {  // move to end
        E('alldivs').appendChild(E(id));
    }
    else {                       // move before another holder
        E('alldivs').insertBefore(E(id), holders[position - 1]);
    }
    resetNumbers();
}
function resetNumbers() {
    // Reset all the numbers to reflect their current position
    var numbers = document.getElementsByClassName('number');
    for (var i = 0; i < numbers.length; i++) {
        numbers[i].innerHTML = i + 1;
    }
}​

その他のいくつかのポイント:

  • 元のコードの s をクリックしてselectも、要素の 1 つが移動されるまでイベント ハンドラーが割り当てられないため、最初は何も実行されません。
  • </div>html の最後に抜けがあります
  • varコードのどこかで変数を宣言することをお勧めします
  • appendChild と insertBefore は、ノードを新しい位置に追加/挿入する前に、DOM の現在の位置からノードを削除するため、要素を明示的に削除する必要はありません。
  • moveup および movedown 関数を使用すると、moveto のみを使用するよりも優れています。この場合、ブロックが移動するたびに、現在、前後の位置を html に挿入し、それらを更新する必要があります。
于 2012-12-29T12:04:12.690 に答える