jQuery ui在嵌套排序中的可排序不准确的占位符放置

时间:2014-08-31 18:16:40

标签: javascript jquery html jquery-ui jquery-ui-sortable

我在另一个可排序元素中有一个可排序元素。两者都相互连接。 在样本标记之后:

<div id='container'>
  <div class='parent'>
    <div class='child'>1</div>
    <div class='child'>2</div>
    <div class='child'>3</div>
    <div class='child'>4</div>
  </div>
  <div class='parent'>
    <div class='child'>5</div>
    <div class='child'>6</div>
    <div class='child'>7</div>
    <div class='child'>8</div>
  </div>
</div>

我要做的是在.parent&{39}和#container之间拖动多个项目。

以下是JS:

$("#container").on('click', '.child', function () {
  $(this).toggleClass('selected');
});

$('.parent').sortable({
  appendTo: "#container",
  connectWith: '.parent, #container',
  revert: 0,
  helper: function (e, item) {
    if (!item.hasClass('selected')) {
        item.addClass('selected').siblings().removeClass('selected');
    }
    var elements = $('#container').find('.selected').clone();
    $('#container').find('.selected').not(item).addClass('hidden');
    var helper = $('<div/>', {
        class: 'parent'
    });
    return helper.append(elements);
  },
  start: function (e, ui) {
    var len = ui.helper.children().length;
    var width = ui.item.width() + 2;
    ui.helper.width((len * width));
    ui.placeholder.width((len * width));
  },
  stop: function (e, ui) {
    $('.selected').removeClass('selected');
  }
});

$('#container').sortable({
  connectWith: '.parent',
  tolerance: "pointer"
});

以下

JSFiddle

使用整个代码(我删除了附加项目的代码以最小化代码,因为这与占位符位置无关)演示了我面临的问题:

我可以将项目从.parent拖到#container,如下所示:

  • 将项目拖至#container左侧,如下所示: enter image description here
  • #container上方的项目拖动到.parents之间的空格(这有点棘手,但当中心正好悬停在空间上时有效),如下所示: enter image description here

但是一旦我将项目拖到外面,即使我直接将项目悬停在#container上,占位符也不会出现在.parent的右侧。

预期产出:

desired outpuy

目前的结果:

current output

如图所示,占位符位于#container内,即使项目远离 $('#container').find('.selected').not(item).addClass('hidden');

根据我的尝试,问题在于:

display:none

我使用#container隐藏所选项目,可能会导致jQuery UI误算。

所以我在refresh事件中尝试了refreshPositionsstart,就像在此JSFiddle中一样,这会产生预期的输出,但它不再正确显示占位符在另外两个场景中的.parent中。

我想要做的是能够通过

将项目从#container拖到#container
  1. 将项目拖到#container
  2. 的左侧
  3. .parents上方的项目拖动到#container
  4. 之间的空格
  5. 将项目拖至{{1}}
  6. 的右侧

    旁注:尝试解决问题时,大多数sortable options都已添加,而且css维度仅用于演示目的,如果需要,可以添加或删除这些维度。 < / p>

    更新:这似乎是一个错误,我报告了here。 jQuery UI团队回复说他们正在重写所有交互。所以希望这将在下一个版本中修复。

2 个答案:

答案 0 :(得分:1)

修改

不要介意第三方插件,请查看此信息,如果这就是您所追求的,请告诉我:http://jsfiddle.net/6opxyvkp/7/ -

http://jsfiddle.net/6opxyvkp/9/ -

<强> HTML

<div id='container'>
    <div class='parent'>
        <div class='child'>1</div>
        <div class='child'>2</div>
        <div class='child'>3</div>
        <div class='child'>4</div>
    </div>
    <div class='parent'>
        <div class='child'>5</div>
        <div class='child'>6</div>
        <div class='child'>7</div>
        <div class='child'>8</div>
    </div>
</div>

<强> CSS

#container {
    display: inline-block;
    height:60px;
    background:dodgerblue;
}
.parent {
    float:left;
    height:58px;
    margin:0 15px;
    border:0px solid red;
    background:silver;
}
.child {
    float:left;
    width:50px;
    height:60px;
    text-align: left;
    background:#fff;
    border:1px solid;
    margin:0px;
}
.ui-sortable-placeholder {
    visibility: visible !important;
    border: none;
    padding:1px;
    background:rgba(0, 0, 0, 0.5) !important;
}
.selected {
    background:red;
}
.hidden {
    display:none !important;
}

<强> JS

$("#container").on('click', '.child', function () {
    $(this).toggleClass('selected');
});

$('.parent').sortable({
    connectWith: '.parent, #container',
    appendTo: '#container',
    revert: 0,
    helper: 'clone',
    helper: function (e, item) {
        var helper = $('<div/>');
        if (!item.hasClass('selected')) {
            item.addClass('selected').siblings().removeClass('selected');
        }
        var elements = item.parent().children('.selected').clone();
        item.data('multidrag', elements).siblings('.selected').remove();
        return helper.append(elements);
    },
    start: function (e, ui) {
        var len = ui.helper.children().length;
        var width = ui.item.width() + 2;
        ui.helper.width((len * width));
        ui.placeholder.width((len * width));
    },
    stop: function (e, info) {
        info.item.after(info.item.data('multidrag')).remove();
    }
});

$('#container').sortable({
    connectWith: '.parent',
    tolerance: 'pointer'
});

如果允许使用第三方jQuery插件,请查看https://github.com/shvetsgroup/jquery.multisortable

答案 1 :(得分:1)

在我的代码中,将这个记录不佳的hack应用于Sortable的overout回调函数几乎已成为惯例:

if($.ui.ddmanager.current)
    $.ui.ddmanager.prepareOffsets($.ui.ddmanager.current, null);

这将确保刷新位置,与内置的refreshrefreshPositions方法相比,它似乎有效。

您可以尝试这种方法,看看它是否会改善您的Sortable的行为?