使jQuery可拖动并对齐到特定网格

14

(注意: 有些人问了类似的问题,但过于具体而没有得到可用的答案)

jQuery UI的draggable小部件具有对网格捕捉的选项,但没有办法设置相对于该网格的位置。

例如,我们在放置目标中拥有一个明确定义的20x20网格。从放置目标内部的0,0开始的拖动项目将与网格对应地捕捉。但是从不同位置或放置目标外部开始的拖动项目将无法与该网格对齐。

输入图像描述

http://jsfiddle.net/FNhFX/5/

HTML:

<div class="drop-target">
    <div class="drag-item">Drag me</div>
    <div class="drag-item" style="left:87px;top:87px;">Drag me</div>
</div>
<div class="outside-drag-item">Drag me</div>

JS:

$(function() {
    $(".drag-item").draggable({
        grid: [20, 20]
    });
    $(".outside-drag-item").draggable({
        grid: [20, 20],
        helper:"clone"
    });
    $(".drop-target").droppable({
        accept: ".drag-item"
    });
});

使用jQuery draggable,是否有任何一种方法可以将元素对齐到特定的网格上?


我认为您需要为外部拖动项设置helper:“original”,因为克隆选项会将克隆拖动,而原始项保持在原地。 - Neha
@Neha- 这没有任何区别:http://jsfiddle.net/FNhFX/7/ - Yarin
你能详细说明一下“drag-me” div的行为吗?我认为外部的div不能拖动到网格内部。 - Neha
2个回答

21

虽然我是通过你提出的后续问题来到这里的,但我也会在这里发布一个答案。

您可以在jQuery UI可拖动元素的drag事件中非常容易地创建自己的对齐网格功能。

基本上,您想要检查当前UI位置在可拖动元素被拖动到网格的任何点时有多接近该网格。该接近度始终可以表示为位置除以网格的余数。如果该余数小于或等于snapTolerance,则将位置设置为没有该余数的位置。

用语言表述可能有些奇怪,在代码中应该更清晰:

演示

// Custom grid
$('#box-3').draggable({
    drag: function( event, ui ) {
        var snapTolerance = $(this).draggable('option', 'snapTolerance');
        var topRemainder = ui.position.top % 20;
        var leftRemainder = ui.position.left % 20;

        if (topRemainder <= snapTolerance) {
            ui.position.top = ui.position.top - topRemainder;
        }

        if (leftRemainder <= snapTolerance) {
            ui.position.left = ui.position.left - leftRemainder;
        }
    }  
});

1
Nate来拯救了- 用一个绝妙的解决方案解决了我的两个问题。再次感谢! - Yarin
1
非常准确...非常有效-用% gridWidth和% gridHeight替换%20。 - Grebe.123

5
作为 jQuery UI 中“网格”选项的替代方案,我创建了自己的网格(您可以使用 CSS 使其可见或不可见),然后使用“吸附”选项并指定我的每个网格线的类。
对于您原始的 jsfiddle,我添加了以下 CSS:
.gridlines {
display: none;
position:absolute;
background-color:#ccc;
}

和以下javascript:

function createGrid(size) {
  var i,
  sel = $('.drop-target'),
      height = sel.height(),
      width = sel.width(),
      ratioW = Math.floor(width / size),
      ratioH = Math.floor(height / size);

  for (i = 0; i <= ratioW; i++) { // vertical grid lines
    $('<div />').css({
        'top': 0,
        'left': i * size,
        'width': 1,
        'height': height
    })
      .addClass('gridlines')
      .appendTo(sel);
  }

  for (i = 0; i <= ratioH; i++) { // horizontal grid lines
    $('<div />').css({
        'top': i * size,
        'left': 0,
        'width': width,
        'height': 1
    })
      .addClass('gridlines')
      .appendTo(sel);
    }

  $('.gridlines').show();
}

createGrid(20);

这是 jsFiddle(http://jsfiddle.net/madstop/46sqd/2/)链接。


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