【问题标题】:Vanilla javascript draggable div within parent父级中的香草javascript可拖动div
【发布时间】:2020-07-24 15:10:12
【问题描述】:

我想在 vanilla javascript 中实现一个可拖动的元素。 我想在方形 div 中制作一个可拖动的小圆形 div。

为了让自己更清楚一点,我确实想要:

  • 创建拖放,
  • 使用 jQuery UI 或任何其他库或插件来实现这一点,只需原版 javascript

我已经有一些处理拖动的事件:

parent.addEventListener("mousedown", ..),
document.addEventListener("mouseup", ..)
document.addEventListener("mousemove", ..)

我的问题是如何将可拖动对象保持在其父对象的给定范围内?

参考:https://codepen.io/ChickenFlavored/pen/rNxRXGo

【问题讨论】:

    标签: javascript draggable color-picker


    【解决方案1】:

    您可以使用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`;
    }
    

    请注意,图形世界中的数字会向下和向右增加

    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 容器的文档

    【讨论】:

    • 你的代码真的很棒。我喜欢它非常简单和简短,但是当您快速拖动时,可拖动对象会卡在边界之前的各个位置。有解决办法吗?
    • 感谢您的关注,实际上根本原因是“mousemove”事件仅触发了有限的次数(由于性能原因),但有任何简单的解决方法 - 只要您注意到绿球出界,你让它接触到红色容器的墙壁。 codepen.io/vsk/pen/dyXLGVw
    • 非常感谢!我真的很喜欢这段代码的简单性,但也非常实用。
    【解决方案2】:

    我希望你可以提供一个代码 sn-p 来尝试模拟你想要的东西,一个 codepen url、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)"
    

    【讨论】:

    • 我尝试了你的代码,但它不起作用我将发布我的代码,对于之前没有可用的代码,我深表歉意。
    猜你喜欢
    • 2020-05-22
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多