我设法实现了一个简单的JavaScript拖动效果,在网页内创建“面板窗口”,我可以从任意角落或位置拖动对象。我只使用onmousedown
(表示可能的拖动),onmousemove
(执行拖动)和onmouseup
(停止拖动)事件。
除非我将对象拖得太靠近边缘并且以正常速度移动鼠标,否则它的效果很好。当我将鼠标移动到对象外部的区域时,拖动将失败,直到我再次移动到对象的区域,我必须单击该对象以停止拖动它。
这就像鼠标太快,但显然它不会在本机应用程序窗口中发生,因为它们可以更好地实现。
我可以将哪些检查添加到当前代码中,以便它不会失败多少?它似乎通过某种方式处理onmouseout
事件来支持一点点这个问题,但是当它发生时,窗口会摇动以将鼠标指针返回到对象区域,并且看起来不太好。
JavaScript Simple Dragging Effect
<!doctype html>
<html>
<head>
<title>JavaScript Simple Dragging Effect</title>
<style type="text/css">
.moveableRect {
position:absolute;
width:320px;
height:200px;
background-color:rgba(254, 220, 186, 0.8);
}
</style>
</head>
<body bgcolor="#abcdef">
<span id="span0000" class="moveableRect"><b>Drag Me<hr /></b></span>
<textarea id="txt" cols="40" rows="12"></textarea>
<script>
//Custom variable to indicate that we
//must drag the SPAN:
///
document.getElementById("span0000").myDragFlag = false;
//When we click and hold the mouse down,
//we must activate the dragging process:
///
document.getElementById("span0000").onmousedown = function(e)
{
if(e.button==0)
{
//This is the part of the trick that allows us
//to drag the object from any starting position
//that we click on it:
///
this.startX=(e.pageX-this.offsetLeft);
this.startY=(e.pageY-this.offsetTop);
//This flag indicates that we must drag
//when moving the mouse while the button is pressed:
///
this.myDragFlag=true;
}
};
//When we move the mouse, we must follow
//the mouse cursor around:
///
document.getElementById("span0000").onmousemove = function(e)
{
var bcr=this.getBoundingClientRect();
if(this.myDragFlag)
{
//When we start dragging (moving the mouse
//while the mouse button is pressed)
//we will perform the effect of dragging from any
//initial position in the rectangle:
///
this.style.left = (e.pageX-this.startX)+"px";
this.style.top = (e.pageY-this.startY)+"px";
document.getElementById("txt").value=
"getBoundingClientRect.left="+bcr.left+"\n"+
"getBoundingClientRect.top="+bcr.top+"\n"+
"getBoundingClientRect.width="+bcr.width+"\n"+
"getBoundingClientRect.height="+bcr.height+"\n"+
"getBoundingClientRect.bottom="+bcr.bottom+"\n"+
"getBoundingClientRect.right="+bcr.right+"\n"+
"e.pageX="+e.pageX+"\n"+
"e.pageY="+e.pageY+"\n"+
"this.offsetLeft="+this.offsetLeft+"\n"+
"this.offsetTop="+this.offsetTop+"\n"+
"relatX="+(e.pageX-this.offsetLeft)+"\n"+
"relatY="+(e.pageY-this.offsetTop);
}
};
//When we release the mouse button,
//we must finish the dragging process:
///
document.getElementById("span0000").onmouseup = function(e)
{
if(e.button==0)
this.myDragFlag=false;
};
document.getElementById("span0000").onmouseout = function(e)
{
if(this.myDragFlag==true)
{
//In this code, we basically check that
//when the mouse slips out from the object
//area while we are still dragging, we will
//force moving the object back under the mouse
//pointer. Here we will check from a logical
//edge of 48 pixels, and we will move the object
//back to 90% within those pixels, vertically and/or
//horizontally. It makes look the object shaky
//but at least it is minimally functional:
///
var minEdge=48;
var edgeCorrect=0.90;
var minEdgeCorrect=(minEdge*edgeCorrect)|0;
var bcr=this.getBoundingClientRect();
var bcrw=bcr.width;
var bcrh=bcr.height;
if(this.startX<minEdge)
{
this.style.left = (e.pageX-minEdgeCorrect)+"px";
}
else if(this.startX>bcrw-minEdge)
{
this.style.left = (e.pageX-this.startX+minEdgeCorrect)+"px";
}
if(this.startY<minEdge)
{
this.style.top = (e.pageY-minEdgeCorrect)+"px";
}
else if(this.startY>bcrh-minEdge)
{
this.style.top = (e.pageY-this.startY+minEdgeCorrect)+"px";
}
}
};
</script>
</body>
</html>
答案 0 :(得分:3)
onmousemove
的事件监听器放在可拖动的div上。因此,如果鼠标离开它,事件将停止发射。它在拖动时会消失,因为它会以一定间隔而不是每个像素触发鼠标移动事件。
要修复它,请将mousemove侦听器放在容器上。
document.body.onmousemove
你可能需要改变你获得坐标的方式。
我想象还有其他方法。但这是最简单的。
修改强>
当我试图摆弄这个但最终让它起作用时,开始怀疑自己: http://jsfiddle.net/tg33u8mv/3/
document.body.onmousemove = function (e) {
if (myDragFlag) {
var draggable = document.getElementById("span0000");
var bcr = draggable.getBoundingClientRect();
draggable.style.left = (e.pageX - draggable.startX) + "px";
draggable.style.top = (e.pageY - draggable.startY) + "px";
}
};
我将myDragFlag
更改为范围变量,而不是this.myDragFlag
。
<强>加成强>
在这个版本中,我在拖动时添加一个类。 http://jsfiddle.net/tg33u8mv/4/
此类的CSS目前禁用突出显示,从而显着改善外观。您还可以使其更改颜色或添加阴影以获得良好的效果。