纯JS控制DIV选择范围移动与复制 改进版

本文介绍了一个使用纯JavaScript实现的DIV选择范围移动与复制的功能。支持批量选择、移动与复制选定的DIV,并提供了全选、反选等快捷键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     和上一个版本相比,增加了快捷键操作,增加了批量删除功能,改变了操作方式

<html>
<head>
    
<title>纯JS控制DIV选择范围移动与复制 改进版</title>
    
<style type="text/css">
    .newbtn
{margin-right:10px;border:solid 1px green;cursor:pointer;padding:2px;background:#efd;}
    body,table
    
{
        font-size
: 12px;
    
}

    
/*DIV未被选择时样式*/
    div.noSelected
    
{
        text-align
: center; 
        position
: absolute; 
        background-color
: #f5f5f5;
        border
: #000000 1px solid; 
    
}

    
    
/*DIV已被选择时样式*/
    div.isSelected
    
{
        text-align
: center; 
        position
: absolute; 
        background-color
: #f5f5f5;
        border
: #996600 3px solid; 
    
}


    
/*选择虚线框样式*/
    div#selectArea
    
{
        position
: absolute;
        border
: #FF6600 1px dashed;
    
}

    
</style>
</head>
<body>
    
<div style="margin:10px;">
        
<span class="newbtn" onclick="AllSelect()">全选(Ctrl+A)</span>
        
<span class="newbtn" onclick="ReverseSelect()">反选(Ctrl+X)</span>
        
<span class="newbtn" onclick="deleteNodes()">删除选中(Delete)</span>
        
<span class="newbtn" onclick="CancelSelect()">取消选择(Ctrl+Z)</span>
        
<input id="move" type="radio" name="moveOrCopy" checked="checked" /><label for="move">移动(-)</label>
        
<input id="copy" type="radio" name="moveOrCopy" /><label for="copy">复制(+)</label>
    
</div>
    
<div id="WorkFlowSpan"></div>
    
<script type="text/javascript" language="javascript">
//范围选择
var saveDiv = new Array();
var areaDiv = new Array();
var cloneNodes;
var oLeft, oTop;
var panel = $("WorkFlowSpan");
var groupName = "GroupItem";
var eventStatus = "nothing";        //"nothing"未选择状态,"selected"选择完毕状态,"selecting"范围选择中状态,"move"移动状态
var selectArea;
var oX,oY;                          //鼠标按下位置
var moveSize = 30;                  //单位移动的大小(动画的速度),越大越快
var copyNo = 0;

//通过名称删除数组元素
Array.prototype.remove = function()
{
    
var removeIndex = -1;
    
if (arguments.length == 1)
    
{
        
//存储预删除的所在位置
        for (var i = 0; i < this.length; i++)
        
{
            
if (this[i] == arguments[0])
            
{
                removeIndex 
= i;
                
break;
            }

        }

        
//删除
        if (removeIndex >= 0)
        
{
            
for(var i = removeIndex; i < this.length; i++)
            
{
                
this[i] = this[i + 1];
            }

            
this.length -= 1;
        }

    }

}


//进栈(只进栈非重复的)
Array.prototype.insert = function()
{
    
var removeIndex = -1;
    
if (arguments.length == 1)
    
{
        
//存储预重复的所在位置
        for (var i = 0; i < this.length; i++)
        
{
            
if (this[i] == arguments[0])
            
{
                removeIndex 
= i;
                
break;
            }

        }

        
//进栈
        if (removeIndex == -1)
        
{
            
this[this.length] = arguments[0];
        }

    }

}


function $(controlId)
{
    
return document.getElementById(controlId);
}


//创建DIV
function createDiv(divID, divLeft, divTop)
{
    
var div = document.createElement("div");
    div.id 
= divID;
    div.group 
= "GroupItem";            //所在组
    div.isSelected = false;            //是否是被选中状态
    div.className = "noSelected";
    div.style.cursor 
= "default";
    div.style.width 
= "250px";
    div.style.height 
= "50px";
    div.style.left 
= divLeft;
    div.style.top 
= divTop;
    div.innerHTML 
= "<table style="width: 100%; height: 100%; text-align: center; vertical-align: middle"><tr><td>coding by pippe<br /><a href='mailto:pippe@163.com'>pippe@163.com</a></td></tr>";
    panel.appendChild(div);
}


//创建三个DIV
createDiv("oldDiv1""100px""400px");
createDiv(
"oldDiv2""400px""400px");
createDiv(
"oldDiv3""700px""400px");

//设置空间选择的样式
function SelectStyle(objControl, isSelected)
{
    objControl.className 
= isSelected ? "isSelected" : "noSelected";
    objControl.isSelected 
= isSelected;
}


//选择范围开始
function AreaCreate()
{
    
if (event.button == 1 && (eventStatus == "nothing" || event.ctrlKey))
    
{
        oX 
= event.x;
        oY 
= event.y;
        
//通过鼠标位置取对象
        var element = document.elementFromPoint(oX, oY);
        
while (element.tagName != "undefined" && element.tagName.toUpperCase() != "BODY")
        
{
            
//可移动或复制的组里面
            if (element.group == groupName)
            
{
                
if (event.ctrlKey)
                
{
                    
//按住CTRL添加或减少选择
                    if (element.isSelected)
                    
{
                        saveDiv.remove(element.id);
                        SelectStyle(element, 
false);
                        eventStatus 
= saveDiv.length == 0 ? "nothing" : "selected";
                    }

                    
else
                    
{
                        saveDiv.insert(element.id);
                        SelectStyle(element, 
true);
                        eventStatus 
= "selected";
                    }

                }

                
else
                
{
                    
//未按住CTRL
                    saveDiv.insert(element.id);
                    SelectStyle(element, 
true);
                    eventStatus 
= "selected";
                    MouseDown();
                }

                
return;
            }

            element 
= element.parentNode;
        }

        
        
//范围选择
        selectArea = document.createElement("div");
        selectArea.id 
= "selectArea";
        selectArea.style.left 
= oX + "px";
        selectArea.style.top 
= oY + "px";
        selectArea.setCapture();
        panel.appendChild(selectArea);
        eventStatus 
= "selecting";
        
return;
    }

}


function AreaSelecting()
{
    
//范围选择中
    if (event.button == 1 && eventStatus == "selecting")
    
{
        
var nX = event.x;
        
var nY = event.y;
        selectArea.style.left 
= nX <= oX ? nX + "px" : oX + "px";
        selectArea.style.top 
= nY <= oY ? nY + "px" : oY + "px";
        selectArea.style.width 
= nX >= oX ? nX - oX : oX - nX;
        selectArea.style.height 
= nY >= oY ? nY - oY : oY - nY;
        
        
var elements = document.all;
        
var len = elements.length;
        
var thisLeft, thisTop, thisRight, thirBottom;
        
var x1,y1,x2,y2;
        x2 
= nX <= oX ? oX : nX;
        x1 
= nX <= oX ? nX : oX;
        y2 
= nY <= oY ? oY : nY;
        y1 
= nY <= oY ? nY : oY;
        
for (var i = 0; i < len; i++)
        
{
            
if (elements[i].group != groupName)
            
{
                
continue;
            }

            thisLeft 
= parseInt(elements[i].style.left);
            thisRight 
= thisLeft + parseInt(elements[i].childNodes[0].offsetWidth);
            thisTop 
= parseInt(elements[i].style.top);
            thisBottom 
= thisTop + parseInt(elements[i].childNodes[0].offsetHeight);
            
//判断是否在选择框范围内
            if ((((thisLeft > x1 && thisLeft < x2) || (thisRight > x1 && thisRight < x2)) && ((thisTop > y1 && thisTop < y2) || (thisBottom > y1 && thisBottom < y2)))
                
|| (((x1 > thisLeft && x1 < thisRight) || (x2 > thisLeft && x2 < thisRight)) && ((y1 > thisTop && y1 < thisBottom) || (y2 > thisTop && y2 < thisBottom))))
            
{
                
if (!elements[i].isSelected)
                
{
                    areaDiv.insert(elements[i].id);
                    SelectStyle(elements[i], 
true);
                }

            }

            
else if (elements[i].isSelected)
            
{
                
//不在选择框范围内
                var isTrue = false;
                
for (var j = 0; j < saveDiv.length; j++)
                
{
                    
if (elements[i].isSelected && elements[i].id == saveDiv[j])
                    
{
                        isTrue 
= true;
                        
break;
                    }

                }

                
if (!isTrue)
                
{
                    areaDiv.remove(elements[i].id);
                    SelectStyle(elements[i], 
false);
                }

            }

        }

    }

}


//范围选择结束
function AreaSelected()
{
    
if (eventStatus == "selecting")
    
{
        selectArea.parentNode.removeChild(selectArea);
        selectArea 
= null;
        
//将选择框内的数组存到移动/复制的数组里面
        for (var i = 0; i < areaDiv.length; i++)
        
{
            saveDiv.insert(areaDiv[i]);
        }

        areaDiv.length 
= 0;
        eventStatus 
= saveDiv.length == 0 ? "nothing" : "selected";
    }

}


//鼠标按下移动开始
function MouseDown()
{
    
if (event.button == 1 && !event.ctrlKey && eventStatus == "selected")
    
{
        oX 
= event.x;
        oY 
= event.y;
        cloneNodes 
= new Array();
        oLeft 
= new Array();
        oTop 
= new Array();
        
for (var i = 0; i < saveDiv.length; i++)
        
{
            cloneNodes[i] 
= $(saveDiv[i]).cloneNode(true);
            $(saveDiv[i]).parentNode.appendChild(cloneNodes[i]);
            cloneNodes[i].childNodes[
0].style.filter = "alpha(opacity=50)";
            cloneNodes[i].childNodes[
0].src = cloneNodes[i].childNodes[0].img2;
            oLeft[i] 
= parseInt(cloneNodes[i].style.left);
            oTop[i] 
= parseInt(cloneNodes[i].style.top);
            cloneNodes[i].childNodes[
0].setCapture();
        }

        document.body.style.cursor 
= "move";
        eventStatus 
= "move";
    }

}


//鼠标移动
function MouseMove()
{
    
if (event.button == 1 && eventStatus == "move")
    
{
        
var nX = event.x;
        
var nY = event.y;
        
//移动中
        var len = cloneNodes.length;
        
for (var i = 0; i < len; i++)
        
{
            cloneNodes[i].style.left 
= (oLeft[i] + nX - oX) + "px";
            cloneNodes[i].style.top 
= (oTop[i] + nY - oY) + "px";
        }

    }

}


//鼠标弹起移动结束
function MouseUp()
{
    
if (eventStatus == "move")
    
{
        eventStatus 
= "moving";
        
var aimLeft, aimTop;
        
var xmlStr = "<nodes>";
        
for (var i = cloneNodes.length - 1; i >= 0 ; i--)
        
{
            cloneNodes[i].childNodes[
0].releaseCapture();
            aimLeft 
= parseInt(cloneNodes[i].style.left);
            aimTop 
= parseInt(cloneNodes[i].style.top);
            
if ($("move").checked)
            
{
                
//移动操作
                MoveNodes(i, aimLeft, aimTop);
            }

            
else
            
{
                
//复制操作
                aimLeft = parseInt(cloneNodes[i].style.left);
                aimTop 
= parseInt(cloneNodes[i].style.top);
                cloneNodes[i].style.left 
= $(saveDiv[i]).style.left;
                cloneNodes[i].style.top 
= $(saveDiv[i]).style.top;
                CopyNodes(i, aimLeft, aimTop);
            }

        }

        document.body.style.cursor 
= "default";
    }

}


//移动位置
function MoveNodes(saveIndex, aimLeft, aimTop)
{
    
var nowLeft = parseInt($(saveDiv[saveIndex]).style.left);
    
var nowTop = parseInt($(saveDiv[saveIndex]).style.top);
    
if (nowLeft > aimLeft + moveSize || nowLeft < aimLeft - moveSize || nowTop > aimTop + moveSize || nowTop < aimTop - moveSize)
    
{
        $(saveDiv[saveIndex]).style.left 
= aimLeft > nowLeft + moveSize ? (nowLeft + moveSize) + "px" : aimLeft < nowLeft - moveSize ? (nowLeft - moveSize) + "px" : nowLeft + "px";
        $(saveDiv[saveIndex]).style.top 
= aimTop > nowTop + moveSize ? (nowTop + moveSize) + "px" : aimTop < nowTop - moveSize ? (nowTop - moveSize) + "px" : nowTop + "px";
        setTimeout(
"MoveNodes(" + saveIndex + "" + aimLeft + "" + aimTop + ")"1);
    }

    
else
    
{
        $(saveDiv[saveIndex]).style.left 
= aimLeft;
        $(saveDiv[saveIndex]).style.top 
= aimTop;
        cloneNodes[saveIndex].parentNode.removeChild(cloneNodes[saveIndex]);
        cloneNodes.remove(cloneNodes[saveIndex]);
        
if (cloneNodes.length == 0)
        
{
            eventStatus 
= "selected";
        }

    }

}


//复制
function CopyNodes(saveIndex, aimLeft, aimTop)
{
    
var nowLeft = parseInt(cloneNodes[saveIndex].style.left);
    
var nowTop = parseInt(cloneNodes[saveIndex].style.top);
    
if (nowLeft > aimLeft + moveSize || nowLeft < aimLeft - moveSize || nowTop > aimTop + moveSize || nowTop < aimTop - moveSize)
    
{
        cloneNodes[saveIndex].style.left 
= aimLeft > nowLeft + moveSize ? (nowLeft + moveSize) + "px" : aimLeft < nowLeft - moveSize ? (nowLeft - moveSize) + "px" : nowLeft + "px";
        cloneNodes[saveIndex].style.top 
= aimTop > nowTop + moveSize ? (nowTop + moveSize) + "px" : aimTop < nowTop - moveSize ? (nowTop - moveSize) + "px" : nowTop + "px";
        setTimeout(
"CopyNodes(" + saveIndex + "" + aimLeft + "" + aimTop + ")"1);
    }

    
else
    
{
        cloneNodes[saveIndex].style.left 
= aimLeft;
        cloneNodes[saveIndex].style.top 
= aimTop;
        cloneNodes[saveIndex].id 
= "copyDiv" + (++copyNo);
        cloneNodes[saveIndex].isSelected 
= false;
        cloneNodes[saveIndex].childNodes[
0].style.filter = null;
        SelectStyle(cloneNodes[saveIndex], 
false);
        cloneNodes.remove(cloneNodes[saveIndex]);
        
if (cloneNodes.length == 0)
        
{
            eventStatus 
= "selected";
        }

    }

}


//取消选择
function CancelSelect()
{
    
for (var saveIndex = 0; saveIndex < saveDiv.length; saveIndex++)
    
{
        SelectStyle($(saveDiv[saveIndex]), 
false);
    }

    saveDiv.length 
= 0;
    eventStatus 
= "nothing";
}


//全选
function AllSelect()
{
    
var elements = document.all;
    
var len = elements.length;
    saveDiv.length 
= 0;
    
for(var i = 0; i < len; i++)
    
{
        
if (elements[i].group == groupName)
        
{
            saveDiv.insert(elements[i].id);
            SelectStyle(elements[i], 
true);
        }

    }

    eventStatus 
= "selected";
}


//反选
function ReverseSelect()
{
    
var elements = document.all;
    
var len = elements.length;
    
var tempDiv = new Array();
    
for(var i = 0; i < saveDiv.length; i++)
    
{
        tempDiv.insert(saveDiv[i]);
    }

    
var isExist = false;
    CancelSelect();
    
for (var i = 0; i < len; i++)
    
{
        
if (elements[i].group == groupName)
        
{
            
for(var j = 0; j < tempDiv.length; j++)
            
{
                
if (elements[i].id == tempDiv[j])
                
{
                    isExist 
= true;
                    
break;
                }

            }

            
if (isExist)
            
{
                isExist 
= false;
                
continue;
            }

            saveDiv.insert(elements[i].id);
            SelectStyle(elements[i], 
true);
        }

    }

}


//删除选中
function deleteNodes()
{
    
var saveLen = saveDiv.length;
    
for (var saveIndex = saveLen - 1; saveIndex >= 0; saveIndex--)
    
{
        $(saveDiv[saveIndex]).parentNode.removeChild($(saveDiv[saveIndex]));
    }

    saveDiv.length 
= 0;
    eventStatus 
= "nothing";
}


document.body.onselectstart 
= function() {return false};
document.body.onmousedown 
= AreaCreate;
document.body.onmousemove 
= AreaSelecting;
document.body.onmouseup 
= AreaSelected;
panel.onmousedown 
= MouseDown;
panel.onmousemove 
= MouseMove;
panel.onmouseup 
= MouseUp;

//快捷键
document.onkeydown = function()
{
    event.ctrlKey 
&& event.keyCode == 65 ? AllSelect() : null;          //CTRL+A全选
    event.ctrlKey && event.keyCode == 88 ? ReverseSelect() : null;      //CTRL+X反选
    event.ctrlKey && event.keyCode == 90 ? CancelSelect() : null;       //CTRL+Z取消选择
    event.keyCode == 189 ? $("move").checked = true : null;     //- 选中移动
    event.keyCode == 187 ? $("copy").checked = true : null;     //+ 选中复制
    event.keyCode == 46 || event.keyCode == 110 ? deleteNodes() : null//Delete或者Del删除选中节点
}

</script>    
</body>
</html>
 

操作说明:

  1. 未选择状态下,单击DIV上可选中此DIV。

  2. 未选择状态下,单击在背景上按住左键拖动产生范围虚线框,在此范围虚线框内的DIV边框变粗变色为被选中,虚线框外的则不被选中。

  3. 已选择状态下,按住Ctrl可再次选择,按住Ctrl的同时,单击在DIV上,如果DIV已被选中则取消本节点选择,反之选中此节点。

  4. 已选择状态下,按住Ctrl的同时,如果单击在背景上按住左键拖动产生范围虚线框,在此范围虚线框内的DIV边框变粗变色为被选中,虚线框外的如果为上次已选中的则不仍然选中,否则不选中。

  5. 释放后虚线消失,需要添加选择可重复第“3”,“4”步操作,多次选择的节点选中。

  6. 快捷键选择,Ctrl +A全选,Ctrl +X反选,Ctrl +Z取消选择。

  7. 移动位置,选中DIV后,如果单选组选中移动(-)(默认,快捷键为“-”)按住左键拖动位置后释放可批量移动位置,产生一段过度动画,不撤销选择的DIV可多次移动,如已移动完毕按Ctrl+Z撤销选择即可。

  8. 复制节点,选中DIV后,如果单选组选中复制(+,快捷键为“+”),按住左键拖动位置后释放,产生一段过度动画,即复制选中的DIV,如复制完毕按Ctrl+Z取消选择即可。

  9. 删除选中DIV,选中DIV后,按下按钮或者快捷键“Delete”、“.”可删除所有选中的DIV。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值