对jQuery UI可排序表应用包含可以防止将高行移动到最后一个位置

Applying containment to jQuery UI Sortable table prevents moving tall rows to the last position

本文关键字:高行 移动 位置 最后一个 UI jQuery 排序 包含可 应用      更新时间:2024-05-15

我有一个HTML表,我正在尝试使用jQuery UI可排序小部件来启用行的重新排序。我已经设置了可排序的axis: 'y',正在使用helper函数在拖动行时保留行的宽度,并将containment设置为父表:

jQuery(function($) {
    $("#rows").sortable({
        handle: ".handle",
        axis: "y",
        containment: "#main-table",
        helper: function(e, row) {
            // From http://www.paulund.co.uk/fixed-width-sortable-tables. 
            // Sets the width of each cell to be its original width.
            // This prevents the row collapsing into a narrower stub when being dragged.
            row.children().each(function() {
                $(this).width($(this).width());
            });
            return row;
        }
    });
});

但是,当存在具有多行高度的行时,包含部分的行为与预期不一样:当拖动较大的行时表的高度会降低,并且包含部分会收缩得更大,因此无法将较大的行移动到表的底部。其他行工作正常。

显示这种行为的JSFiddle可以在这里找到:https://jsfiddle.net/AndrewBennet/rc5pnazc/3/

这是已知/预期的行为吗?有什么变通办法吗?

containment的设置方式是,当拖动开始时,计算元素的坐标并将其推送到一个数组中,然后该数组用于查看鼠标移动时是否应该进行拖动。在您的情况下,此计算是在从表中删除该行之后进行的,因此包含值不正确。

您可以做的一件事是在开始事件时调整这些值,使它们与表的状态匹配,然后再从计算中删除行。您可以通过sortable的实例方法访问它们。

如果希望更精确,也可以调整此包含属性的顶部坐标,使其考虑单击偏移。

例如:

jQuery(function($) {
  $("#rows").sortable({
    handle: ".handle",
    axis: "y",
    containment: '#main-table',
    start: function(e, ui) {
      // get the instance of the sortable.
      // instance method is new to jquery ui 1.11, for previous versions
      // you can use $(this).data()['ui-sortable'];
      var sort = $(this).sortable('instance');
      // this makes the placeholder fit with the row that's being dragged
      ui.placeholder.height(ui.helper.height());
      // containment property of the sortable instance is not the same
      // as the containment option. The property is calculated
      // from the option. You need to adjust bottom coordinates
      // to take into account the row you just removed from it and the click offset.
      sort.containment[3] += ui.helper.height() * 1.5 - sort.offset.click.top;
      // Since your handle is centered, and pointer coordinates are used
      // for sortable, but top coordinates are used for containment
      // you can have issues with top row. Adjusting with the click offset
      // will resolve the issue.
      sort.containment[1] -= sort.offset.click.top;
    },
    helper: function(e, row) {
      // From http://www.paulund.co.uk/fixed-width-sortable-tables. 
      // Sets the width of each cell to be its original width.
      // This reverts the default behaviour of the row collapsing into a narrower stub when being dragged.
      row.children().each(function() {
        $(this).width($(this).width());
      });
      return row;
    }
  });
});

https://jsfiddle.net/f1nexjmz/4/

jQuery(function($) {
  $("#rows").sortable({
    handle: ".handle",
    axis: "y",
    containment: "#main-table",
    helper: function(e, row) {
        row.children().each(function() {
            $(this).width($(this).width());
        });
        return row;
    },
    start: function (e, ui) {
        var sort = $(this).sortable('instance');
        sort.containment[3] += ui.helper.height();
    }
  });
});