使用JS进行智能拖动



元素到达屏幕边缘后,是否可以停止拖动?在过去的一个小时里,我一直在努力,但没有成功。这是我到目前为止的代码:

dragElement(document.getElementById("mp3Audio"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
elmnt.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// && elmnt.offsetTop - pos2 - Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0) >= 0
// set the element's new position:
if (!(elmnt.style.top - document.documentElement.clientHeight <= 0) && !(elmnt.style.left - document.documentElement.clientWidth <= 0) && !(elmnt.style.top >= document.documentElement.clientHeight) && !(elmnt.style.left >= document.documentElement.clientWidth)){
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
audio{
background: #D6D6D6;
border-radius: 0px;
border: none;
width: 100%;
height: 10%;
font-variant-numeric: oldstyle-nums;
-webkit-text-stroke: thin;
color: #FFFFFF;
transition: 0.5s;
}
audio::-webkit-media-controls-panel{
background: #A1A1A1;
border: none;
}
<div id="mp3Audio" style="background: #FFFFFF; position: fixed; border: 5px solid #800000; border-radius: 10px; overflow: hidden; left: 0px; top: 0px; height: 240px; width: 426px; bottom: 1em; right: 4em;">
<img src="graphics/HighResIcon.png" style="object-fit: contain;" height="90%" width="100%">
<audio type="audio/mpeg" controlsList='nodownload' controls><source src="songs/amhere.mp3"></source></audio>
</div>
<button id="playbutton">e</button>

我以为我可以使用clientHeightclientWidth,但到目前为止我还没有成功。任何帮助都将不胜感激。

我重命名了var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

xPosDiff = 0, yPosDiff = 0, xPosOld = 0, yPosOld = 0;,这样我更容易理解它们。:)

getBoundingClientRect()计算量很大,但我认为它对你的问题是必要的。通过该方法,您可以从要拖动的元素中提取top, right, bottom, left,然后我只是将其与0, window.innerWidth, window.innerHeight, 0进行了比较,但我也将光标的新X和Y差异添加到了比较中。因此,如果我预测新的移动将使元素穿过任何边界(顶部,右侧…),我不会移动元素。

我不得不调整#mp3Audio的大小,使其适合代码段。我还添加了一个虚线边框,以更好地展示弹力。

PS。W3Schools的代码在进行IMHO计算时有错误的想法,所以我也更改了它。他们有xPosDiff = xPosOld - e.clientX,这似乎是错误的,因为你需要从旧位置减去这个值:elmnt.offsetTop - yPosDiff。这似乎是倒退的,我更喜欢添加差异。DS,

dragElement(document.getElementById("mp3Audio"));
function dragElement(elmnt) {
var xPosDiff = 0, yPosDiff = 0, xPosOld = 0, yPosOld = 0;

/* ADDED */
var elmntRect;
var insideTop, insideBottom, insideLeft, insideRight;

elmnt.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
posXOld = e.clientX;
posYOld = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
xPosDiff = e.clientX - xPosOld;
yPosDiff = e.clientY - yPosOld;
xPosOld = e.clientX;
yPosOld = e.clientY;
/* ADDED */
elementRect = elmnt.getBoundingClientRect();
insideTop =    elementRect.top    + yPosDiff >= 0;
insideBottom = elementRect.bottom + yPosDiff <  window.innerHeight;
insideLeft =   elementRect.left   + xPosDiff >= 0;
insideRight =  elementRect.right  + xPosDiff <  window.innerWidth;

// set the element's new position:
if (insideTop && insideBottom && insideLeft && insideRight) {
elmnt.style.top = (elmnt.offsetTop + yPosDiff) + "px";
elmnt.style.left = (elmnt.offsetLeft + xPosDiff) + "px";
}    
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
html, body {
margin: 0px;
padding: 0px;
}
body {
border: 2px dashed #000;
height: 95vh;
}
audio{
background: #D6D6D6;
border-radius: 0px;
border: none;
width: 100%;
height: 10%;
font-variant-numeric: oldstyle-nums;
-webkit-text-stroke: thin;
color: #FFFFFF;
transition: 0.5s;
}
audio::-webkit-media-controls-panel{
background: #A1A1A1;
border: none;
}
#mp3Audio {
position: fixed;
left: 0px;
top: 0px;
/* bottom: 1em; */
/* right: 4em; */
height: 120px;  /* 240px */
width:  213px;  /* 426px */
overflow: hidden;
border: 5px solid #800000;
border-radius: 10px;
background: #FFFFFF;
box-sizing: border-box; /* ADDED */
}
<div id="mp3Audio">
<img src="graphics/HighResIcon.png" style="object-fit: contain;" height="90%" width="100%">
<audio type="audio/mpeg" controlsList='nodownload' controls><source src="songs/amhere.mp3"></source></audio>
</div>

最新更新