如何使用固定的 X 和 Y 轴使 jQuery 可拖动?

Posted

技术标签:

【中文标题】如何使用固定的 X 和 Y 轴使 jQuery 可拖动?【英文标题】:How to make jQuery draggable with fixed X and Y axis? 【发布时间】:2010-12-07 01:47:33 【问题描述】:

我想知道是否有一种方法可以使 jQuery 可拖动,只能向上、向下和向左、向右拖动。我想防止用户对角拖动 div。在我的情况下,无法在可拖动 UI 中使用网格选项。

http://jqueryui.com/demos/draggable/#constrain-movement

这怎么可能?

谢谢!

【问题讨论】:

如果你可以左右、上下拖动一个对象……你不能沿对角线拖动它吗?还是您仅从“起始位置”谈论? IE,如果你从 0,0 开始,然后移动到 0,-3 以外的点......突然你只能垂直? 是的,这正是我想要实现的目标。 好吧,我编写了正确的代码,而 JQuery 只是不允许您在拖动时更改轴。 【参考方案1】:

jQueryUI 支持两种控制在固定轨道上拖动的方法。

    您可以使用轴选项来限制拖动移动 特定的轴。例如:

    $('.draggable_horiz').draggable(axis: "x");
    

    更多信息在这里:http://api.jqueryui.com/draggable/#option-axis

    您可以使用元素或 x/y 数组来限制移动 定义边界框的坐标。

        $('.draggable_track').draggable( containment: [0,0, 250, 24] );
    
    or to just use the parent element as a reference track:
    
        $('.draggable_track').draggable( containment: 'parent' );
    

    更多信息在这里: http://api.jqueryui.com/draggable/#option-containment

我希望这会有所帮助。

【讨论】:

【参考方案2】:

我编写了一个插件,允许在两个轴上移动可拖动对象。它完成了工作,但它会更好地实现为 jQuery UI widget 而不是简单的 jQuery 插件。

托管演示:http://jsbin.com/ugadu/1(可通过 http://jsbin.com/ugadu/1/edit 编辑)

插件代码:

$.fn.draggableXY = function(options)  
  var defaultOptions =  
    distance: 5, 
    dynamic: false 
  ; 
  options = $.extend(defaultOptions, options); 

  this.draggable( 
    distance: options.distance, 
    start: function (event, ui)  
      ui.helper.data('draggableXY.originalPosition', ui.position || top: 0, left: 0); 
      ui.helper.data('draggableXY.newDrag', true); 
    , 
    drag: function (event, ui)  
      var originalPosition = ui.helper.data('draggableXY.originalPosition'); 
      var deltaX = Math.abs(originalPosition.left - ui.position.left); 
      var deltaY = Math.abs(originalPosition.top - ui.position.top); 

      var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag'); 
      ui.helper.data('draggableXY.newDrag', false); 

      var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax'); 
      ui.helper.data('draggableXY.xMax', xMax); 

      var newPosition = ui.position; 
      if(xMax)  
        newPosition.top = originalPosition.top; 
       
      if(!xMax) 
        newPosition.left = originalPosition.left; 
       

      return newPosition; 
     
  ); 
; 

【讨论】:

啊!抱歉,除非您打开 Firebug,否则其中有一条调试线会破坏它。我已经修复它并更改了答案中的链接。 我在以下线程中对您的代码进行了修改,以支持缓动拖动。这是您几年前在那里编写的一段很棒的代码。 ***.com/questions/6398854/jquery-draggable-with-ease 似乎有超过 250 人编辑了您的代码,但它不再有效,更改 URL 以返回到第一个修订版就可以了。 jsbin.com/ugadu/1 感谢您告诉我@Johannes。我已经修复了链接。 @Johannes @brianpeiris 添加 grid: [80, 80], 属性 - 第一个 div('你可以在两个轴上拖动我!')无法正常工作 仅移动到 x 轴而不是 Y【参考方案3】:

利用拖动事件来发挥你的优势

$('.selector').draggable(
   drag: function(event, ui)  ... 
);

我不是 100% 确定如何,但在这里,您可以检查坐标。正如〜jack-laplante所说,这就是您要比较的地方。如果坐标比y更接近x轴,则将轴更改为x

//setter
$('.selector').draggable('option', 'axis', 'x');

如果相反,将其更改为 y。这将使您获得一个捕捉动作,以始终将项目放在 x 轴或 y 轴上(从起点)。如果轴是 (x+n,y+n),您必须进行检查才能将项目留在原处,但如果有人在 |x| 上停留的像素超过几个像素,那将是非常令人印象深刻的。 =|y|行。

您没有指定轴是否始终保持在它们最初开始的位置,或者它们是否根据可拖动项目在拖动开始时的位置而改变(例如,如果您将其移动一点,然后松开,然后尝试拖动它多一点)。还有一个 start: 和 end: 事件也可以帮助您完成那部分。

你到底想拖动什么不能对角线,但可以向左、向右、向上和向下?

【讨论】:

感谢您的意见!我正在创建一个图像库,用户将在其中拖动图像以移动到下一张图片。如果用户向上或向下拖动图像,将显示一个小的信息文本。【参考方案4】:

在经过多次摆弄之后,我发布了这个答案,说 just jqueryui 调用对象是不可能的。似乎它不允许您在拖动时更改约束轴。

请证明我错了吗?

【讨论】:

这应该可以使用自定义拖动事件侦听器并更新 ui.position 对象。有关此方法的更多详细信息,请参阅this answer。【参考方案5】:

我没有确切的代码给你,但我可以帮助你更深入地思考这个问题,从而为你指明正确的方向。

于是用户开始拖动一个不受约束的对象。当对象从起点移动一个像素时,如果第一个像素位于这四个 (x,y) 坐标中的任何一个,其中 x em> 和 y 是起点:(x-1,y-1), (x- 1,y+1),(x+1,y-1) 或 (x-1, y+1),目前还不清楚用户的意思是走哪条路,例如,如果对象在左下角,则无法判断约束是否应该在x上或 y 轴。

一旦你移动超过一个像素,它就会变得更容易。但是你仍然需要对像素坐标进行一些舍入,如上面的坐标,abs(xoffset) == abs(yoffset),然后你可以触发当 x 和/或 y 距离大于某个任意小整数(例如“3”)时应用约束的事件。

下一个要处理的问题是,您希望允许用户在距离上次触发轴约束多远时更改轴。我猜你想要一个网格效果,所以你必须在移除约束之前设置一个像素移动阈值并寻找用户想要拖动的下一个“方向”。

如果您弄清楚如何去做,这是一个有趣的挑战和良好的学习体验。

【讨论】:

以上是关于如何使用固定的 X 和 Y 轴使 jQuery 可拖动?的主要内容,如果未能解决你的问题,请参考以下文章

jquery如何判断能否被整除?

具有固定列和标题的可滚动表格,带有现代 CSS

jQuery 可拖放和可滚动的 div

使用jquery.hammer.js时如何返回X和Y坐标

如何存储任何特定拖放 div 的 X 和 Y 坐标?

如何使用 JQuery 将对象数据传递到节点服务器并保存到 mongodb?