JS之DOM案例之由浅入深探究左右互选栏(上)

JavaScript/前端
365
0
0
2022-06-03

昨天我发表了一篇文章JS之DOM案例之tab栏切换封装,今天继续深入学习DOM,带来一个左右互选栏案例(GIF图如下)。该案例分为上中下三版,分别对应简单,封装,优化版本。

JS之DOM案例之由浅入深探究左右互选栏(上)

左右互选栏

HTML CSS部分

<body>
<select name="" id="sel1" size="10" multiple>
<option value="0">C语言</option>
<option value="1">C++</option>
<option value="2">JAVA</option>
<option value="3">PHP</option>
</select>
<input type="button" value=">>>"/>
<input type="button" value="<<<"/>
<input type="button" value=">"/>
<input type="button" value="<"/>
<select name="" id="sel2" size="10" multiple>
</select>
</body>
<style>
select {
  width: 170px;
  height: 200px;
  font-size: 16px;
  background-color: orange;
}
</style>

分析

2个下拉多选框,4个按钮,为左,右全移动,左,右部分移动。但触动左右全移动,左下拉框内容整体移动到右,部分移动,只移动被选择选项到右边。当我们执行左全移动,遍历左下拉框所有元素,然后利用apendChild()整体移动到右边。这里有一个坑!

JS之DOM案例之由浅入深探究左右互选栏(上)

一个坑

如果采用上图红框方法,随着appenfChild让左边元素一个个减少,右边元素一个个增加,i也在增大,同时arr.length也在减小,这样当i=2,arr.length=2,这个程序就执行不下去了,就执行了2次就结束了。

JS之DOM案例之由浅入深探究左右互选栏(上)

一个坑

解决

让i与arr.length同步减少即可(比较复杂,等到优化版再写简单版),就是事先就让i=arr.length,然后i与length同时减。添加的时候,采用反插入即可正序。

JS之DOM案例之由浅入深探究左右互选栏(上)

解决

插入元素处还可以优化一下,即每次添加到对面都是排第一位。看代码注释。

JS之DOM案例之由浅入深探究左右互选栏(上)

优化

同理,右全移动如下

JS之DOM案例之由浅入深探究左右互选栏(上)

右全移动

重点:部分移动

全移动容易,部分移动是重点,如何选择被选的移动,没有被选的不动。即当左下拉框的元素是被选定状态的,我才移动你,没有的不动。而且移动后,设置被选状态为无。代码如下:

JS之DOM案例之由浅入深探究左右互选栏(上)

部分移动

同理,第四个按钮如下

JS之DOM案例之由浅入深探究左右互选栏(上)

第4个按钮

整个代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
select {
  width: 170px;
  height: 200px;
  font-size: 16px;
  background-color: orange;
}
</style>
</head>
<body>
<select name="" id="sel1" size="10" multiple>
<option value="0">C语言</option>
<option value="1">C++</option>
<option value="2">JAVA</option>
<option value="3">PHP</option>
</select>
<input type="button" value=">>>"/>
<input type="button" value="<<<"/>
<input type="button" value=">"/>
<input type="button" value="<"/>
<select name="" id="sel2" size="10" multiple>
</select>
</body>
</html>
<script>
var sel1=document.getElementById("sel1");
var sel2=document.getElementById("sel2");
var inpArr = document.getElementsByTagName("input");
inpArr[0].onclick=function(){
    var arr=sel1.children;
    //for(var i=0;i<arr.length;i++){  
    for(var i=arr.length-1;i>=0;i--){
        //sel2.appendChild(arr[arr.length-1-i]);//传过去顺序不变
        sel2.appendChild(arr[0]);//每次添加都是第一位 因为取得时候是倒叙取得 如果添加每次都是第一位那么顺序就不变。  
        //PHP PHP JAVA JAVA,PHP C++ C++,JAVA,C++
    }
}
inpArr[1].onclick=function(){
var arr=sel2.children;
//for(var i=0;i<arr.length;i++){  
    for(var i=arr.length-1;i>=0;i--){
        //sel1.appendChild(arr[arr.length-1-i]);
        sel1.appendChild(arr[0]);
    }
}
inpArr[2].onclick=function(){
    var arr=sel1.children;
    for(var i=arr.length-1;i>=0;i--){
        if(arr[i].selected===true){
            arr[i].selected=false;
            sel2.appendChild(arr[i]);
        }
    }
}
inpArr[3].onclick=function(){
    var arr=sel2.children;
    for(var i=arr.length-1;i>=0;i--){
        if(arr[i].selected===true){
            arr[i].selected=false;
            sel1.appendChild(arr[i]);
        }
    }
}
</script>

总结与问题

这个方法有以下问题,1,代码不简练,第一第二个按钮其实代码一样,第三第四个代码其实也一样,却都重复了一遍。所以明天来封装他们。2,即部分移动后,到对面与原顺序的位置发生变化了,即不能实现我左侧什么顺序,我右侧必须怎么移动都是左侧顺序。后天来优化解决。