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)时,该脚本会起作用,但是当您尝试移动不同的块(例如顶部的块)时,它只会在其下方的前两个块周围切换。谁能给我任何建议?

我不知道是因为脚本完成的顺序,还是其他原因。这让我困惑了一段时间,如果有人能仔细阅读并给我一些建议,我将不胜感激。

(我不想用 jQuery 编写代码,这实际上只是我试图通过编写代码来学习更多 JavaScript。如果它不是最有效、最安全的,无论如何,它仍然只是我试图自学的东西JavaScript。)

感谢您的阅读。(请不要编辑 JS Fiddle 本身,而是在此处发布任何编辑/改进。谢谢。)

[编辑:我并不是真的在写陈词滥调的科幻小说,它们只是示例 div,因为我想不出更好的东西]

4

1 回答 1

2

在语句中neworder =...,您更改onclick函数的值,但您只对即将移动的块执行此操作。问题是其他块也改变了位置。例如,如果您单击块 2 的“发送”,则块 2 会向上移动到位置 1,块 1 会向下移动到位置 2。但只有块 2 上的事件处理程序会相应更新。因此,下次您单击(最初的)块 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;
    }
}​

其他几点:

  • 单击select原始代码中的 s 最初不会执行任何操作,因为在移动元素之一之前没有为其分配事件处理程序
  • </div>html 末尾缺少一个
  • var使用代码中的某处声明变量是一种很好的做法
  • appendChild 和 insertBefore 在将节点追加/插入到新位置之前,从 DOM 中的当前位置移除节点,因此无需显式移除元素。
  • 拥有 moveup 和 movedown 函数比只拥有 moveto 更好,后者需要您将当前、前面和后面的位置插入到 html 中,并在每次移动块时刷新它们。
于 2012-12-29T12:04:12.690 回答