首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JS的智能拖拽?

使用JS的智能拖拽?
EN

Stack Overflow用户
提问于 2021-02-12 07:24:58
回答 1查看 51关注 0票数 1

当元素到达屏幕边缘时,是否可以停止拖动该元素?在过去的一个小时里,我一直在尝试,但一无所获。到目前为止,我的代码如下:

代码语言:javascript
复制
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;
  }
}
代码语言:javascript
复制
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;
}
代码语言:javascript
复制
<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,但到目前为止我还没有成功。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-12 18:23:56

我重命名为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的代码在进行计算时有错误的想法,所以我也改变了它。他们有xPosDiff = xPosOld - e.clientX,这似乎是错误的,因为你需要从旧位置减去这个值:elmnt.offsetTop - yPosDiff。这似乎是倒退的,我更喜欢添加不同之处。DS,

代码语言:javascript
复制
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;
  }
}
代码语言:javascript
复制
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 */
}
代码语言:javascript
复制
<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>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66164445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档