JQuery UI可排序的水平滚动使所有元素下移

6
我希望您能使用滚动条让用户从左到右对对象进行排序。
这些对象是带有HTML的盒子,包括一些文本,而不是像其他示例中的图片。
问题在于,当用户拖动其中一个对象时,所有其他对象都会在拖动期间向下移动。
以下是我的代码:
HTML:
<div id="parent" class="parent">
  <div id="list" class="list">
    <div class="item">A</div>
    <div class="item">B</div>
    <div class="item">C</div>
  </div>
</div>

CSS:

.parent {
  height:64px;
  width:280px;
}
.list {
  background-color:#d0d0d0;
  white-space:nowrap;
  overflow-x:scroll;
  overflow-y:hidden;
  /*text-align:left;*/
}
.item {
  background-color:#404040;
  height:40px;
  width:100px;
  margin:4px;
  cursor:pointer;
  display:inline-block;
  /*float:left;*/
  /*float:none;*/
  /*clear:both;*/
}
.placeholder {
  height:40px;
  width:20px;
  display:inline-block;
  margin:4px;
}

Javascript:

$(function() {
  $('#list').disableSelection().sortable({
    scroll: true,
    placeholder: 'placeholder',
    //containment:'parent',
    axis: 'x'
  });
})

我尝试了许多不同的设置,并将其中一些作为注释留下来。
最好的方法是在这里查看问题:http://jsfiddle.net/francispotter/gtKtE/

请查看 http://jsfiddle.net/sP3UZ/,该链接来自于 https://dev59.com/cnE85IYBdhLWcg3w64IA。 - Blazemonger
@mlbase75 感谢您的回复,但那并没有解决问题。您提供的链接中的示例使用了float,如果您想要对象形成平铺网格,那么这是可以的。我希望项目水平排列,并且区域向左/右滚动以适应项目。因此,我需要使用display:inline-block。 - Francis Potter
我一直在调试代码,就我所知,Sortable从未被设计成横向使用。我认为在DIV顶部创建的空白间隔是某种不可见的占位符DIV,除非更改jQuery UI代码本身否则无法移除。另请参阅http://bugs.jqueryui.com/ticket/6702。 - Blazemonger
5个回答

21

我找到的解决方案可以在不重写UI库的情况下工作,而且是一个干净的CSS修复:

.ui-sortable-placeholder {
  display: inline-block;
height: 1px;
}

4
我知道这件事已经过去一段时间了,但还是要感谢你——这帮助了我很多。 为了说明你的意思(并证明它有效),这里有一个可以工作的修改版本,是根据原帖的示例代码修改而来:http://jsfiddle.net/q4uze/3/ - Joshua Bambrick

2
这个答案显然对你来说太晚了,但也许它会帮助到其他处于同样情况的人。几天前我看到了你的问题,因为我正在尝试做同样的事情,允许用户重新排列“照片”在“胶片条”上。关于你的问题的评论建议使用“float”而不是“inline-block”,结果证明这是找到解决方案的关键。这使我使用了一个固定大小的DIV来容纳可排序的项目,避免了由于换行引起的高度变化,然后添加了一个外部DIV,并设置overflow-x:scroll来进行水平滚动。享受吧!

https://jsfiddle.net/kmbro/y8ccza34/

HTML

<div id='scrollable'>
<div id='sortable'>
<div class='item'>Block A</div>
<div class='item'>Block B</div>
<div class='item'>Block C</div>
<div class='item'>Block D</div>
</div>
</div>

CSS

#scrollable {
  overflow-x: scroll;
}

#sortable {
  border: dashed green;
  border-width: 6px 0;
  padding: 4px 0;
  background-color: yellow;
  height: 150px;
  width:calc(4 * 200px + 1px); // 1px for dragging
}

.item {
  float: left;
  height: 100%;
  width: 200px;
  box-sizing: border-box; /* keep padding/border inside height/width */
  border: solid green 4px;
  background-color: white;
}

jQuery 2.1.3 / jQuery UI 1.11.4
$('#sortable').sortable({
axis: 'x',
});

1
一个同事提出的一个答案(不太优雅,但它可以工作)是在项目上设置float:left,然后:
$(function() {
  $('#list').disableSelection().sortable({
    scroll: true,
    axis: 'x',
    create: function(event, ui) {
        var $e = $(event.target);
        var width = 0;
        $e.children().each(function(){
            width += $(this).outerWidth(true);
        });
        $e.width(width);
    }
  });
})

1
我知道这个回答有点晚了,但我也遇到了这个问题。 对我来说解决方法是改变


.removeClass("ui-sortable-helper")[0];

.removeClass("ui-sortable-helper").html('&nbsp;')[0];

在当前未压缩版本(v1.8.17)的659行。

我希望这仍然能对你有所帮助。


谢谢您的答复。我已经放弃了这个项目(只是留下了这个漏洞)。这是应该提交给jQuery本身的补丁吗? - Francis Potter
是的,我猜这就是补丁,因为我在水平和垂直可排序中都尝试过了。我也会在jQuery UI网站上发布它。 - Bert ter Heide
1
不必更改源代码,您也可以使用“start”回调函数。 start: function(event, ui) { ui.placeholder.html('&nbsp;'); }。别忘了将其附加到连接列表的两个列表上。 - Bert ter Heide
不要动核心文件!Boo。 - random_user_name

1
正如@BertterHeide所评论的那样,解决这个问题的正确方法是修改您的.sortable调用,添加start: function(event, ui) { ui.placeholder.html('&nbsp;'); },如下所示:
$(function() {
  $('#list').disableSelection().sortable({
    scroll: true,
    placeholder: 'placeholder',
    start: function(event, ui) { ui.placeholder.html('&nbsp;'),
    //containment:'parent',
    axis: 'x'
  });
})

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