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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1572950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 11:45:48  来源:igfitidea点击:

How to make jQuery draggable with fixed X and Y axis?

jqueryjquery-uidraggable

提问by Fred Bergman

I am wondering if there is a way to make the jQuery draggable to only drag straight up, down and left, right. I want to prevent the user from dragging a div diagonally. Using the grid option in the draggable UI is not possible in my situation.

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

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

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

How is this possible?

这怎么可能?

Thanks!

谢谢!

采纳答案by brianpeiris

I wrote a plugin that allows moving a draggable in both axes. It gets the job done but it would be better-implemented as a jQuery UI widgetrather than a simple jQuery plugin.

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

Hosted Demo: http://jsbin.com/ugadu/1(Editable via http://jsbin.com/ugadu/1/edit)

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

Plugin code:

插件代码:

$.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; 
    } 
  }); 
}; 

回答by mobilemonkey

jQueryUI supports two methods for controlling dragging on a fixed track.

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

  1. You can use the axis option to limit dragging movement on a particular axis. For instance:

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

    More Info here: http://api.jqueryui.com/draggable/#option-axis

  2. You can constrain movement using an element or an array of x/y coordinates that define a bounding box.

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

    More info here: http://api.jqueryui.com/draggable/#option-containment

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

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

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

  2. 您可以使用定义边界框的元素或 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

I hope this helps.

我希望这有帮助。

回答by Brandon Henry

use the drag event to your advantage

使用拖动事件对您有利

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

i'm not 100% sure how, but inside here, you can do a check on the coordinates. as ~Hyman-laplante said, this is where you would compare. if the coordinates are closer to the x axis than the y, change the axis to x

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

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

if the other way around change it to y. this will get you a snapping motion to always have the item either on the x axis or the y axis (from the starting point). you'd have to do a check to leave the item wherever it is if the axis was say (x+n,y+n), but it would be pretty impressive if someone got more than a few pixels staying on the |x|=|y| line.

如果反过来将其更改为 y。这将使您获得捕捉动作,使项目始终位于 x 轴或 y 轴(从起点)。如果轴是 (x+n,y+n),你必须检查一下才能将项目留在任何地方,但如果有人在 |x| 上留下多个像素,那将会非常令人印象深刻。 =|y| 线。

you didn't specify if the axes always remain where they originally started or if they change depending on where the draggable item is on drag start (like if you move it a little bit, then let go, and try to drag it some more). there's a start: and end: event too that could help you with that part.

您没有指定轴是否始终保持在它们最初开始的位置,或者它们是否根据可拖动项目在拖动开始时的位置而改变(例如,如果您稍微移动它,然后放手,并尝试再拖动它一些) . 还有一个开始:和结束:事件也可以帮助你完成那部分。

what exactly are you trying to drag that can't go diagonal, but can go left, right, up, and down?

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

回答by snicker

I'm posting this answer after much fiddling to say that it's not possible with justjqueryui calls on the object. It seems that it will not allow you to change the restraint axis while you are already dragging.

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

Please prove me wrong?

请证明我错了?

回答by user105090

I don't have exact code for you, but I might be able to point you in the right direction by helping you to think about the problem a little bit more deeply.

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

So the user begins to drag an unconstrained object. As the object moves one pixel away from the starting point, if the first pixel is at any of these four (x,y) coordinates, where xand yare the starting point: (x-1,y-1), (x-1,y+1),(x+1,y-1) or (x-1,y+1), it is still unclear which way the user means to go, For instance, if the object is at one down and on left, it's impossible to tell whether the constraint should be on the x or y axis.

所以用户开始拖动一个不受约束的对象。当物体从起点移开一个像素时,如果第一个像素位于这四个 ( x, y) 坐标中的任何一个,其中xy是起点: ( x-1, y-1), ( x-1, y+1),( x+1, y-1) 或 ( x-1, y+1) ,仍然不清楚用户打算走哪条路,例如,如果物体在一个下方在左侧,无法判断约束应该在 x 轴还是 y 轴上。

Once you move more than one pixel away, it gets easier. But you still have to do some rounding on the pixel coordinates where, as in the coordinates above, abs(xoffset) == abs(yoffset), Then you can fire an event to apply the constraint when the x and/or y distance are greater than some arbitrary small integer, say "3".

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

The next problem to deal with is how far from the last firing of the axis constraint do you want to allow the user to change the axis. I'm guessing that you want a grid effect, so you'll have to set a number-of-pixels moved threshold before you remove the constraint and look for the next "direction" that the user wants to drag.

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

This is an interesting challenge and a good learning experience if you figure out how to do it.

如果您知道如何去做,这是一个有趣的挑战和很好的学习经验。