纯JavaScript可拖动div元素,限制在父元素内

3
我希望使用纯JavaScript实现可拖动元素。我想在一个正方形div中使一个小圆形div可拖动。
更明确地说,我不想:
  • 创建拖放
  • 使用jQuery UI或任何其他库或插件来实现这一点,只使用纯JavaScript
我已经有了处理拖动的几个事件: parent.addEventListener("mousedown", ..),
document.addEventListener("mouseup", ..)
document.addEventListener("mousemove", ..) 我的问题是如何将可拖动的元素保持在其父元素给定的范围内?
参考:https://codepen.io/ChickenFlavored/pen/rNxRXGo
2个回答

3
您可以使用getBoundingClientRect,该方法返回一个DOMRect对象(一个包含对象的无敌矩形),包括八个属性:left、top、right、bottom、x、y、width、height。
var parent = document.querySelector('.parent');
var parentRect = parent.getBoundingClientRect();

var draggable = document.querySelector('.draggable');
var draggableRect = draggable.getBoundingClientRect();

你可以随时使用 e.clientXe.clientY 获取鼠标的 (X,Y) 坐标,因此只需检查它们是否在 .parent div 的边界矩形之外,如果是,则仅更新 draggable div 的 lefttop 属性即可。
if( (e.clientX >= parentRect.left && (e.clientX+draggableRect.width <= parentRect.right)) &&
    (e.clientY >= parentRect.top && (e.clientY+draggableRect.height <= parentRect.bottom)) 
    //+draggableRect.height and +draggableRect.height accounts for the size of ball itself
){
            draggable.style.left = `${e.clientX}px`;
            draggable.style.top = `${e.clientY}px`;
}

请注意,在图形世界中,数字向下和向右增加。 enter image description here https://codepen.io/vsk/pen/PozVryr 更新: 要解决评论中提到的问题,请使用以下方法。
  if(/* mouse was moved withing red container's bounds*/)
  else{
    //if mouse went out of bounds in Horizontal direction
    if(e.clientX+draggableRect.width >= parentRect.right){
       draggable.style.left = `${parentRect.right-draggableRect.width}px`;
    }
    //if mouse went out of bounds in Vertical direction
    if(e.clientY+draggableRect.height >= parentRect.bottom){
       draggable.style.top = `${parentRect.bottom-draggableRect.height}px`;
    }
  }

将mousemove事件分配给文档而不是div容器。

你的代码真是太棒了。我喜欢它的简洁明了,但是当你快速拖动可拖动的元素时,它会在边界之前卡住。有没有解决方法? - user12682229
感谢您的关注,实际上根本原因是由于性能问题,'mousemove'事件仅会触发有限次数,但这有一个简单的解决方法 - 一旦您注意到绿色球超出边界,即可使其接触红色容器的墙壁。https://codepen.io/vsk/pen/dyXLGVw - Vinay
非常感谢!我真的很喜欢这段代码,它既简单又功能强大。 - user12682229

0
我希望你可以提供一个代码片段来尝试模拟你想要的内容,一个 codepen 链接,codesandbox 或类似的东西。
我使用你提供的内容制作了这个样本 : )
let x = event.clientX - element.offsetLeft
const elementWidth = element.clientWidth
const fullX = x + elementWidth
const containerW = yourContainer.clientWidth
if(fullX > containerW){
  //If element will be out of container
  x = containerW - elementWidth // So it will be never out of container
}
element.style.transform = "translate("+x+"px, "+y+"px)"

我尝试了你的代码,但它没有起作用。我会发布我的代码,很抱歉之前没有提供代码。 - user12682229

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接