JavaScript div 排序脚本错误(切换下面两个 div 的顺序)

标签 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';

}

当您向上或向下移动一个 block (或 div)时,该脚本会起作用,但是当您尝试移动另一个 block (例如顶部的 block )时,它只会切换其下方的前两个 block 。 有人可以给我任何建议吗?

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

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

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

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

最佳答案

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

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

然而,依靠 ID 来指示 block 的位置,然后在移动 ID 后对其进行修改可能会导致各种困惑。最好保留一个数组或字典来记录 block 的位置,或者每次要移动它们时循环遍历它们以确定它们在 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 中,并在每次移动 block 时刷新它们。

关于JavaScript div 排序脚本错误(切换下面两个 div 的顺序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14077086/

相关文章:

Python:如何按几个值对字典列表进行排序?

java - ClassNotFoundException - 使用 ClassLoader 在 Web 应用程序中动态加载类时

javascript - Web Audio - 如何立即更改所有声音的播放速率?

javascript - 简化 jQuery 代码 简化

python - 对不同列表中具有相同索引的所有元素求和

php - 设置PHP项目自动GIT部署

java - 使用 Play Framework 上的按钮更改语言

javascript - 如何设置前端编码环境?

javascript - 在使用 Tailwind CSS 时从 `ListBox` 设置 `@headlessui/react` 上的最大内容以获取选项的最大宽度?

java - 如何保存ArrayList <List>