JavaScript div订购脚本bug(切换下面两个div的顺序)

时间:2012-12-28 23:29:04

标签: javascript list web onclick

代码:

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本身,而是在这里发布任何编辑/改进。谢谢。)

<编辑:编辑:我不是真的写一个陈词滥调的科幻小说,他们只是一个例子,因为我想不出更好的东西]

1 个答案:

答案 0 :(得分:2)

在语句neworder =...中,您更改了onclick函数的值,但您只对即将移动的块执行此操作。问题是其他块也改变了位置。例如,如果单击块2的“发送”,则块2向上移动到位置1,块1向下移动到位置2.但是只有块2上的事件处理程序相应地更新。因此,下次单击(最初的)块1时,它将无法正常运行。

一种解决方案是在每次移动其中一个块时更新受影响的所有块上的事件处理程序。例如,创建一个名为updateEventHandlers(blockNumber)的函数,并为所有受影响的块调用它。

然而,依赖于ID来指示块的位置,然后在移动ID之后摆弄ID可能会导致各种混淆。最好是保持一个数组或字典记录块的位置,或者循环通过它们以确定它们在每次移动它们时在DOM中的位置。

例如,下面的代码使用后一种方法提供moveup,moveown和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最初不会执行任何操作,因为直到其中一个元素移动后才会为其分配事件处理程序
  • html
  • 末尾缺少</div>
  • 优良作法是在代码中的某处使用var声明变量
  • appendChild和insertBefore从DOM中的当前位置移除一个节点,然后将其插入/插入新位置,因此无需显式删除该元素。
  • 具有moveup和moveown函数比只有moveto更好,这需要你将当前,前后位置插入到html中,并在每次移动一个块时刷新它们。