我有一个选择元素,有一长串人。我希望能够在列表中选择多个人,然后通过单击箭头对他们进行上下排序。我以为我可以使用它,但是每次我向上移动选择项时,所选的选项就会按顺序反转。

就像选择的第二个选项向上移动,也超过了第一个...不确定发生了什么。提前致谢!

var select = _select;
var optionsNodeList = select.options;
var options = [];
var selectedIndexes = [];

for (var i = 0; i < optionsNodeList.length; i++) {
    var option = optionsNodeList.item(i);
    options.push(option);
    if (option.selected) {
        selectedIndexes.push(i);
    }
}

var len = selectedIndexes.length;
var firstSelected = selectedIndexes[0];
var lastSelected = selectedIndexes[len-1];
if (isSortUp === true && firstSelected !== 0) {
    for (var i = 0, currIndex; i < len; i++) {
        var currIndex = selectedIndexes[i];
        insertBefore(options[currIndex], options[currIndex-1]);
    }
} else if (isSortUp === false && lastSelected !== options.length-1) {
    for (var i = len-1, currIndex; i > -1; i--) {
        var currIndex = selectedIndexes[i];
        insertAfter(options[currIndex], options[currIndex+1]);
    }
}

function insertBefore(newNode, refNode) {
    refNode.parentNode.insertBefore(newNode, refNode);
}
function insertAfter(newNode, refNode) {
    refNode.parentNode.insertBefore(newNode, refNode.nextSibling);
}


按下向上箭头之前:
before screen shot
按下向上箭头后:
after screen shot

最佳答案

根本不需要循环。而不是移动整个组,只需在(或之后)移动选项:

if (isSortUp === true && firstSelected !== 0) {
    insertAfter(options[firstSelected - 1], options[lastSelected]);
} else if (isSortUp === false && lastSelected !== options.length-1) {
    insertBefore(options[lastSelected + 1], options[firstSelected]);
}


但是,为了完整起见,顺序被交换的原因是您正在对循环内DOM中的元素进行重新排序,但没有对所拥有的数组options进行重新排序。不需要使用用于存储选项的额外数组。如果将代码更改为直接使用select.options,则代码实际上将按编写时的方式工作,而无需在每次单击时重新排列所选选项。



document.getElementById("up").addEventListener("click", function(){
    move(true);
});
document.getElementById("down").addEventListener("click", function(){
    move(false);
});

function move(isSortUp){
    var select = document.getElementById("sel");
    var optionsNodeList = select.options;
    var options = [];
    var selectedIndexes = [];

    for (var i = 0; i < optionsNodeList.length; i++) {
        var option = optionsNodeList.item(i);
        options.push(option);
        if (option.selected) {
            selectedIndexes.push(i);
        }
    }

    var len = selectedIndexes.length;
    var firstSelected = selectedIndexes[0];
    var lastSelected = selectedIndexes[len-1];

    if (isSortUp === true && firstSelected !== 0) {
        insertAfter(options[firstSelected - 1], options[lastSelected]);
    } else if (isSortUp === false && lastSelected !== options.length-1) {
        insertBefore(options[lastSelected + 1], options[firstSelected]);
    }
}

function insertBefore(newNode, refNode) {
    refNode.parentNode.insertBefore(newNode, refNode);
}
function insertAfter(newNode, refNode) {
    refNode.parentNode.insertBefore(newNode, refNode.nextSibling);
}

<select id="sel" multiple="multiple" style="width: 100px; height: 150px;">
    <option>a</option>
    <option>b</option>
    <option>c</option>
    <option>d</option>
    <option>e</option>
    <option>f</option>
    <option>g</option>
    <option>h</option>
    <option>i</option>
    <option>j</option>
</select>
<button id="up">up</button>
<button id="down">down</button>





http://jsfiddle.net/9v32xs0o/

07-24 09:47
查看更多