【问题标题】:Jquery draggable snap only to outmost elementsJquery可拖动捕捉仅到最外面的元素
【发布时间】:2016-06-02 11:52:58
【问题描述】:

我创建了一个网格,其中每一列都分配了一个数字。我想要一个可拖动的 div 捕捉到每列的边框,然后基本上显示我的 div 捕捉到的最外列的范围。

示例在这里: https://jsfiddle.net/Cataras/dpdLLcft/

$(function() {
  $(".draggable").draggable({
    snap: ".hour-full, .hour-half",
    snapMode: 'both',
    stop: function(event, ui) {
      /* Get the possible snap targets: */
      var snapped = $(this).data('ui-draggable').snapElements;

      /* Pull out only the snap targets that are "snapping": */
      var snappedTo = $.map(snapped, function(element) {
        return element.snapping ? element.item : null;
      });
      /* Display the results: */
      var result = '';
      $.each(snappedTo, function(idx, item) {
        result += $(item).text() + ", ";
      });

      $("#results").html("Snapped to: " + (result === '' ? "Nothing!" : result));
    }
  });
});

取自这个问题的代码:How to find out about the "snapped to" element for jQuery UI draggable elements on snap

但是,它不仅显示 div 左右两侧的列号,还显示其间的所有列。有时还有右边的下一个,红色条显然没有触及。有什么建议吗?

【问题讨论】:

  • 我认为使用 Draggable 和 droppables 创建这种交互会更好。
  • 调整snapTolerance 似乎使捕捉不那么贪婪。它仍然显示捕捉比您想要的更多的元素。由于它可以捕捉到两种类型的元素.hour-full, .hour-half,因此它将捕捉到的两个元素都设置为真。例如,如果你在 2 和 5 之间下降,你会得到 1、2、3、4、5、6,因为从技术上讲,由于模式为 both,它会同时捕捉到所有这些。我认为您需要根据它在stop 中的位置与其捕捉到的位置进行映射。

标签: jquery jquery-ui draggable jquery-ui-draggable


【解决方案1】:

snappedTo 数组有点贪心,我会使用left 定位来确定拖动项本质上是哪个元素over

这是一个工作示例:https://jsfiddle.net/Twisty/dpdLLcft/5/

jQuery

$(function() {
  $(".draggable").draggable({
    snap: ".hour-full, .hour-half",
    snapMode: 'both',
    stop: function(event, ui) {
      console.log("Drag stopped at Left: " + ui.offset.left);
      /* Get the possible snap targets: */
      var snapped = $(this).data('ui-draggable').snapElements;
      console.log($(this).data('ui-draggable'));

      /* Pull out only the snap targets that are "snapping": */
      var snappedTo = $.map(snapped, function(element) {
        if (element.snapping) {
          console.log("Found snapped element: " + $(element.item).text() + ". Left: " + element.left + " Width: " + element.width);
          return element;
        }
      });
      /* Display the results: */
      var result = '';
      $.each(snappedTo, function(idx, item) {
        if (ui.offset.left == item.left) {
          console.log(item);
          result = $(item.item).text() + ", ";
          result += $(snappedTo[idx + 3].item).text();
        }
      });

      $("#results").html("Snapped to: " + (result === '' ? "Nothing!" : result));
    }
  });
});

首先,使用您的循环,我刚刚从 snappingtrue 的元素中获取了所有数据。

其次,我们循环遍历这些元素,并将可拖动元素的左边缘与各种元素进行比较。我们在控制台中看到了这一点:

Drag stopped at Left: 48
Found snapped element. Left: 28 Width: 20
Found snapped element. Left: 48 Width: 20
Found snapped element. Left: 68 Width: 20
Found snapped element. Left: 88 Width: 20
Found snapped element. Left: 108 Width: 20
Found snapped element. Left: 128 Width: 20

然后我们可以比较它并确定我们从哪个元素开始。

if (ui.offset.left == item.left) 

当左边的偏移量是48,元素的左边是48(48 == 48),我们再更新结果:

result = item.item.innerHTML + ", ";
result += snappedTo[idx + 3].item.innerHTML;

由于我们知道可拖动覆盖的列数,并且我们知道起点,我们只需通过增加索引从其他元素获取信息。

Snapped to: 2, 5

我认为这是您试图从您的描述中实现的目标。如果要获取外部的,只需调整索引即可:

result = snappedTo[idx - 1].item.innerHTML + ", ";
result += snappedTo[idx + 4].item.innerHTML;

这应该让你想要你想要的一种或另一种方式。如果您有任何问题,请告诉我。

【讨论】:

  • 非常感谢!到目前为止,这似乎有效。我可能需要添加更多代码,因为我的栏的宽度可能会有所不同。抱歉这么晚才回复。有什么办法我也可以获得行名吗?
猜你喜欢
  • 1970-01-01
  • 2011-07-07
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 2010-11-20
相关资源
最近更新 更多