jQuery 可在两个容器之间拖放和拖放,并且可排序

Posted

技术标签:

【中文标题】jQuery 可在两个容器之间拖放和拖放,并且可排序【英文标题】:jQuery draggable and droppable between two containers and sortable 【发布时间】:2012-12-27 19:31:27 【问题描述】:

我正在尝试开发一个具有以下功能的小页面:

    页面将有两个 div:一个是 #origin,包含很多缩略图,第二个是 #drop,可以放置图像(最多 3 个)。 需要能够将图像从#drop 拖放回原点。 #drop 需要可排序,因为 3 个选定图像的顺序很重要。 当放置在#drop 上时,图像应该对齐,就好像它们从一开始就是这样显示的。

我以前从未使用过 jQuery,我什至有一个工作页面原型,我已经通过原生 html5 拖放事件在两个容器之间进行拖放,但是当我添加 sortable() jquery 功能到#drop,无法再将图像拖回#origin,这破坏了我的功能。

所以,我重新开始,想用 jQuery 实现拖放功能和可排序功能。我已经阅读了几乎所有可拖动、可放置和可排序功能的整个 API,但我无法让它工作。不确定这是否是我为每个功能使用的设置。

在小提琴上,您可以看到图像变得可拖动,并且我可以看到我指定的有效设置(不透明度、光标),但图像无法在#drop 上拖放。

据我了解,使图像可拖动、图像具有“可拖动”类以及使#drop droppable 接受“.draggable”的组合,它应该允许最基本的功能,但即使这样也没有似乎没有。另外我读到,如果可拖动和可放置都具有相同的“范围”设置,它也应该可以工作,但事实并非如此。

这是页面代码的简单版本,加上一个 jsFiddle:http://jsfiddle.net/39khs/

代码:

css:

#origin 
  background-color: green;

#drop 
  background-color: red;
  min-height: 120px;

js:

$("img").draggable( helper: "clone", opacity: 0.5, cursor: "crosshair", scope: "drop" );
$("#drop").droppable( accept: ".draggable", scope: "drop");
$("#drop").sortable();

html:

<div id="wrapper">
    <div id="origin" class="fbox">
        <img src="http://placehold.it/140x100" id="one" title="one" class="draggable" />
        <img src="http://placehold.it/140x100" id="two" title="two" class="draggable" />
        <img src="http://placehold.it/140x100" id="three" title="three" class="draggable" />
    </div>
  <p>test</p>
    <div id="drop" class="fbox">

    </div>
</div>

非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

这是最终结果的小提琴:

http://jsfiddle.net/39khs/82/

关键是处理“drop”事件并手动从#origin 中删除已删除的图像并将其添加到#drop。这实际上是我在第一个实现中所做的,但不知道如何使用 jQuery 来做到这一点:

 $(dropped).detach().css(top: 0,left: 0).appendTo(droppedOn);

我不确定为什么 jQuery 并没有真正从旧容器中删除拖动的元素并将其添加到新容器中,但这是为了让新拖放的项目正确显示而不仅仅是它的确切位置必须做的事情被丢弃,不考虑 CSS 放置/样式。

@Barry Pitman 提出了以下 SO 问题:

jQuery draggable + droppable: how to snap dropped element to dropped-on element

更新:我今天有一些空闲时间,想检查一下是否可以仅使用可排序的,你瞧,确实如此。

http://jsfiddle.net/wj4ak/5/

只需两行代码就可以从一个容器拖放到另一个容器,并对项目进行排序。它们根本不需要在 ul/ol 列表中。一件烦人的事情是,我不打算让 origin div 上的项目可排序,但这是我现在可以忍受的。

【讨论】:

【参考方案2】:

如果你想使用.droppable().draggable(),&.sortable(),那么你只需要使用.sortable()

使用您的 jsfiddle,我进行了以下更改:

HTML:

<div id="wrapper">
    <div id="origin" class="fbox">
    <ul id="sort1" class="list">
      <li><img src="http://placehold.it/140x100" id="one" title="one" class="draggable" /></li>
      <li><img src="http://placehold.it/140x100" id="two" title="two" class="draggable" /></li>
      <li><img src="http://placehold.it/140x100" id="three" title="three" class="draggable" /></li>
    </ul>
    </div>
  <p>test</p>
    <div id="drop" class="fbox">
      <ul id="sort2" class="list"></ul>
    </div>
</div>

javascript

$( "#sort1, #sort2" ).sortable(
      helper:"clone", 
      opacity:0.5,
      cursor:"crosshair",
      connectWith: ".list",
      receive: function( event, ui ) //this will prevent move than 3 items in droppable list
         if($(ui.sender).attr('id')==='sort1' && $('#sort2').children('li').length>3)
           $(ui.sender).sortable('cancel');
         
      
);

$( "#sort1,#sort2" ).disableSelection();

CSS:

#origin

  background-color: green;

#drop

  background-color: red;
  min-height: 120px;

.list
 
  min-height: 120px;
 
.list li

 display: inline-block;
 list-style-type: none;
 padding-right: 20px;

演示:http://jsfiddle.net/39khs/80/

希望这对您有所帮助,如果您有任何问题,请告诉我!


链接: http://api.jqueryui.com/sortable/

【讨论】:

感谢多姆。很高兴知道可排序将包含拖放+可排序,但我不喜欢似乎需要的标记(添加 ol/ul 列表)。没有它我就可以工作......但在某些时候我会尝试看看它是否可以在没有 ul/ol 的情况下仅使用 sortable 来完成。 如果 div 中有占位符应该被丢弃,我应该如何使用它? 这对我有用,无需使用 ul/ol。我喜欢这种方法的简单性。

以上是关于jQuery 可在两个容器之间拖放和拖放,并且可排序的主要内容,如果未能解决你的问题,请参考以下文章

jquery拖放和克隆,找到元素的放置位置

JQuery-UI 在 Re-Drag 上拖放和重新拖动克隆

Jquery拖放和克隆

JQUERY 跨 div 拖放和克隆

让 jQuery 可排序、可拖放和可拖动以协同工作

Gridly是一个jQuery插件,可以在网格上进行拖放和调整大小。