我有一个包含很长人名的select元素。我希望能够在列表中选择多个人,并通过单击箭头对其进行上下排序。我以为我得到了它的工作,但每次我移动一个选择,所选的选项按顺序颠倒。
这就像第二个选择的选项向上移动并且也移动到第一个...不确定发生了什么。提前谢谢!
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
答案 0 :(得分:2)
您的错误是您将选项放在上一个选项之前,因此第二个选项&#34; insertBefore&#34;第一个。
实施例: 选项1 - 索引0 选项2(选定) - 索引1 选项3(选定) - 索引2
在索引0之前的第一个选定插入即可,secod选择在索引1之前插入,因此它在索引1的顶部,不是很好。
你可以做这样的事情来解决你的问题。
if (isSortUp === true && firstSelected !== 0) {
for (var i = 0, currIndex; i < len; i++) {
var currIndex = selectedIndexes[i];
if(i == 0){
insertBefore(options[currIndex], options[currIndex-1]);
}else{
insertAfter(options[currIndex], options[currIndex-1]);
}
}
}
使用第一个选定的插入位于前一个插入之前,所选的其余部分放在第一个选定位置之后。
答案 1 :(得分:0)
根本不需要循环。而不是移动整个组,只需在(或之后)之前移动选项:
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>