【问题标题】:Programmatically sort jquery-ui sortable?以编程方式排序 jquery-ui 可排序?
【发布时间】:2020-09-26 22:49:17
【问题描述】:

我在 display:flex 父 div 中有一堆 div。父 div 可以使用 jquery-ui 的sortable 函数进行排序。

除了允许用户排序​​之外,我还想添加一些按钮来进行动画排序。

例如,使用以下 HTML:

<div class="sortable">
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
  <div id="div4"></div>
  <div id="div5"></div>
</div>

我想要一个按钮,当按下它时,将动画移动 div1 到 div4 和 div5 之间,平滑移动(事实上,有点不稳定,好像用手移动会更好)并移动所有 div通过,所以看起来好像是用手移动的。

这是否可以使用 jquery-ui 的 sortable(),或者我最好构建一个自定义解决方案?

【问题讨论】:

  • 这对于可排序是不可能的。它是 UI 的一部分,依赖于拖放操作。 UI Animate 和 Position 可以帮助您做到这一点。

标签: jquery-ui jquery-ui-sortable


【解决方案1】:

考虑以下示例。

$(function() {
  function arrange(obj, pre) {
    obj = $(obj);
    var t = $("[id^='div']:eq(" + pre + ")");
    obj.animate({
      top: t.position().top + "px"
    }, {
      duration: 1000,
      step: function(i) {
        $(this).position({
          my: "left top",
          at: "left bottom",
          of: t,
        });
      },
      complete: function() {
        obj.detach().css("top", "").insertAfter(t);
      }
    });
  }

  $(".sortable").sortable().disableSelection();

  $("#arrange").click(function() {
    arrange($("#div1"), 3);
  });
});
.sortable {
  list-style-type: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.sortable div {
  margin: 0 3px 3px 3px;
  padding: 0.4em;
  height: 18px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="sortable">
  <div id="div1" class="ui-state-default">Item 1</div>
  <div id="div2" class="ui-state-default">Item 2</div>
  <div id="div3" class="ui-state-default">Item 3</div>
  <div id="div4" class="ui-state-default">Item 4</div>
  <div id="div5" class="ui-state-default">Item 5</div>
</div>
<button class="btn" id="arrange">Arrange</button>

https://css-tricks.com/jquery-ui-position-function/构建

更新

$(function() {
  function swap(a, b, ms) {
    console.log("Swap:", a.attr("id"), "with", b.attr("id"));
    a.animate({
      top: b.position().top + "px"
    }, {
      duration: ms,
      step: function(i) {
        $(this).position({
          my: "left top",
          at: "left bottom",
          of: b,
        });
      },
      complete: function() {
        a.detach().css("top", "").insertAfter(b);
      }
    });
  }

  function arrangeAfter(a, b) {
    var n = a.next();
    for (var c = parseInt(n.attr("id").slice(-1)); n.index() <= b.index(); c++) {
      swap(a, n, 400);
      n = $("#div" + (c + 1));
    }
  }

  $(".sortable").sortable().disableSelection();

  $("#arrange").click(function() {
    arrangeAfter($("#div1"), $("#div4"));
  });
});
.sortable {
  list-style-type: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.sortable div {
  margin: 0 3px 3px 3px;
  padding: 0.4em;
  height: 18px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="sortable">
  <div id="div1" class="ui-state-default">Item 1</div>
  <div id="div2" class="ui-state-default">Item 2</div>
  <div id="div3" class="ui-state-default">Item 3</div>
  <div id="div4" class="ui-state-default">Item 4</div>
  <div id="div5" class="ui-state-default">Item 5</div>
</div>
<button class="btn" id="arrange">Arrange</button> <button class="btn" id="reset">Reset</button>

【讨论】:

  • 这已经很接近了,我想我可以让它跳过动画,依次为每个 div 设置一秒钟的动画,以使它们在它们之间移动时移动。谢谢!
  • 嗯,这将比我想象的更复杂,因为在我的场景中,它是 100 个 30 像素的 div 在一个包装的 display:flex 容器中。显示时 div 可能是 5 行,每行 20,这意味着对角线动画是可能的,我不能只将它动画到下一个 div,我要么需要计算动画的路径才能确定下一个 div 的位置是,或者看看我在动画的每一步都以某种方式结束了。
  • 我也遇到了 position().left 的问题,我认为是因为容器有 % 左右边距。我现在正在努力解决这个问题。
  • @BenHolness 我用swap 函数更新了另一个示例,这样您就可以遍历每个位置。 flex 会给你一些问题,但有办法解决它。
  • 我已经设法克服了 flex 定位问题,但是我不能逐步使用对角线,但是您的回答基本上符合我的要求,并且让我走上了正确的道路!谢谢:)
猜你喜欢
  • 2014-07-05
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 1970-01-01
  • 2012-12-22
  • 2017-02-20
相关资源
最近更新 更多