jQuery 可排序和可删除

发布于 2024-08-17 22:53:11 字数 71 浏览 5 评论 0原文

我想要一个可排序的列表,但我也希望该列表中的元素可放置到我定义为可放置的 div 中。我似乎找不到办法做到这一点。有什么想法吗?

I want to have a list that is sortable, but I also want the elements in that list to be droppable to the divs I have defined as droppable. I can't seem to find a way to do it. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

单身情人 2024-08-24 22:53:11

这是科林解决方案的简化版本。

最大的区别是,该解决方案不存储可排序元素的整个 html,而仅存储当前拖动的项目。如果该项目被放置在可放置区域上,它将被插入到其原始位置。

不管怎样,代码如下:

<!doctype html>
<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js"></script>

<script type="text/javascript">
$(document).ready(function() {
    var dropped = false;
    var draggable_sibling;

    $("#sortable").sortable({
        start: function(event, ui) {
            draggable_sibling = $(ui.item).prev();
        },
        stop: function(event, ui) {
            if (dropped) {
                if (draggable_sibling.length == 0)
                    $('#sortable').prepend(ui.item);

                draggable_sibling.after(ui.item);
                dropped = false;
            }
        }
    });

    $(".droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        drop:function(event,ui){
            dropped = true;
            $(event.target).addClass('dropped');
        }
    });
});

</script>

<style type="text/css">
#sortable li{
    clear:both;
    float:left;
}

.droppable {
    clear:both;
    height:300px;
    width:400px;
    background-color:#CCC;
}

.droppable.active { background: #CFC; }
.droppable.hovered { background: #CCF; }
.dropped { background: #f52; }
</style>

</head>
<body>

<ul id="sortable">
    <li id="one">One</li>
    <li id="two">Two</li>
    <li id="three">Three</li>
    <li id="four">Four</li>
    <li id="five">Five</li>
    <li id="six">Six</li>
</ul>

<div class="droppable">Drop Here</div>
<div class="droppable">Drop Here</div>

</body>
</html>

如果将一个项目拖到列表中的新位置,然后将其放在

    和可放置 之外,它仍然遇到与 Colin 的解决方案相同的问题

    。该项目将不会重置,而是占据列表中的最后一个位置(在 Google Chrome 中测试)。无论如何,通过一些鼠标悬停检测可以轻松解决这个问题,或者它甚至可能是理想的行为。

Here's a simplified version of Colin's solution.

The biggest difference is that this solution does not store the entire html of the sortable elements, but only the currently dragged item. It is then inserted into it's original position if the item is dropped on the droppable area.

Anyway, here's the code:

<!doctype html>
<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js"></script>

<script type="text/javascript">
$(document).ready(function() {
    var dropped = false;
    var draggable_sibling;

    $("#sortable").sortable({
        start: function(event, ui) {
            draggable_sibling = $(ui.item).prev();
        },
        stop: function(event, ui) {
            if (dropped) {
                if (draggable_sibling.length == 0)
                    $('#sortable').prepend(ui.item);

                draggable_sibling.after(ui.item);
                dropped = false;
            }
        }
    });

    $(".droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        drop:function(event,ui){
            dropped = true;
            $(event.target).addClass('dropped');
        }
    });
});

</script>

<style type="text/css">
#sortable li{
    clear:both;
    float:left;
}

.droppable {
    clear:both;
    height:300px;
    width:400px;
    background-color:#CCC;
}

.droppable.active { background: #CFC; }
.droppable.hovered { background: #CCF; }
.dropped { background: #f52; }
</style>

</head>
<body>

<ul id="sortable">
    <li id="one">One</li>
    <li id="two">Two</li>
    <li id="three">Three</li>
    <li id="four">Four</li>
    <li id="five">Five</li>
    <li id="six">Six</li>
</ul>

<div class="droppable">Drop Here</div>
<div class="droppable">Drop Here</div>

</body>
</html>

It still suffers the same problem as Colin's solution if an item is dragged into a new position in the list and then dropped outside both the <ul> and the droppable <div>. The item will then not reset but take the last position in the list (tested in Google Chrome). Anyway, this is easily solved with some mouse over detection or it may even be desirable behaviour.

咆哮 2024-08-24 22:53:11

据我所知,我发布的先前代码的问题是,在可排序的 mouseup 之前调用了可放置的 drop 函数,并且由于我重写了列表,可排序变得愤怒(由于缺乏更好的术语) )。这多少有些猜测。

看看最终的代码:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
    <script type="text/javascript">

var dropped = false;
var templateHtml;
$(document).ready(function(){

    setSortable();

    $("#droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        accept:".drop",
        drop:function(event,ui){
            dropped = true;
            //alert(ui.draggable.text());
        }
    });

});

function setSortable(){
    $("#sortable").sortable({
        stop:function(event,ui){
            if(dropped){
                $("#sortable").sortable('destroy').html(templateHtml);
                dropped = false;
                setSortable();
            }
        }
    });

    $("#sortable li").addClass("drop").bind('mousedown',function(){
        templateHtml = $("#sortable").html();
    });
}

    </script>
    <style type="text/css">
    #sortable li{
        clear:both;
        float:left;
    }

    #droppable {
        clear:both;
        height:300px;
        width:400px;
        background-color:#CCC;
    }
    #droppable.active {
        background-color:#CFC;
    }
    #droppable.hovered {
        background-color:#CCF;
    }
    </style>

</head>
<body>

<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>

<div id="droppable">
Drop Here
</div>

</body>

这里涉及大量的怪癖。

我尝试在 sortable 的开始事件上保存 #sortable html,但是在应用所有 ui-css 之后调用该 get,并最终将列表元素放置在疯狂的地方。因此,我需要在 LI 上使用 mousedown 功能。

setSortable 位于函数中,因为停止事件重写了可排序,我猜这是“递归”。不确定这里的确切术语,但我们可以接受令人烦恼的混乱。

幸运的是,droppable 的 drop 函数在 sortables stop 函数之前被调用,因此我能够设置一个全局“dropped”变量,用于查看元素是否被删除。

我仍然很惊讶这并不容易做到,我认为 jQuery 会有函数来更好地处理它。也许我错过了什么?

As far as I could tell, the issue with the previous code I posted is that the drop function of the droppable was getting called before the mouseup of the sortable, and since I rewrote the list the sortable was getting angry (for lack of better terms). That's somewhat a guess.

Looking at the final code:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
    <script type="text/javascript">

var dropped = false;
var templateHtml;
$(document).ready(function(){

    setSortable();

    $("#droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        accept:".drop",
        drop:function(event,ui){
            dropped = true;
            //alert(ui.draggable.text());
        }
    });

});

function setSortable(){
    $("#sortable").sortable({
        stop:function(event,ui){
            if(dropped){
                $("#sortable").sortable('destroy').html(templateHtml);
                dropped = false;
                setSortable();
            }
        }
    });

    $("#sortable li").addClass("drop").bind('mousedown',function(){
        templateHtml = $("#sortable").html();
    });
}

    </script>
    <style type="text/css">
    #sortable li{
        clear:both;
        float:left;
    }

    #droppable {
        clear:both;
        height:300px;
        width:400px;
        background-color:#CCC;
    }
    #droppable.active {
        background-color:#CFC;
    }
    #droppable.hovered {
        background-color:#CCF;
    }
    </style>

</head>
<body>

<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>

<div id="droppable">
Drop Here
</div>

</body>

Tons of quirks are involved here.

I tried to save the #sortable html on the start event of sortable, but that get's called after all of the ui-css gets applied, and ended up placing list elements in crazy places. So, I needed to use the mousedown function on the LIs.

The setSortable is in a function because the stop event rewrites the sortable, which is "recursive" I guess. Not sure the exact terminology here, but we can go with annoyingly confusing.

Fortunately, the droppable's drop function gets called before the sortables stop function, so I was able to set a global "dropped" variable that was used to see if the element was dropped.

I'm still surprised this wasn't easier to do, I thought jQuery would have functions to handle it a lot better. Perhaps I'm missing something?

痴情 2024-08-24 22:53:11

不完全是你所要求的,但我需要一个初始容器,可以将项目拖到另一个可排序的容器中 - 并且我认为我应该分享它。这就是我实现它的方式(jQuery 1.8.3):

$("#sortable-list").sortable();
$("#initial-list div").draggable({
  revert: true,
  revertDuration: 0
});

$("#initial-list").droppable({
  accept: ".item-selected",
  drop: function(e, ui) {
    var dropped = ui.draggable;
    var droppedOn = $(this);
    var itemInOtherList = $(this).children("#" + dropped.attr('id'));
    itemInOtherList.removeClass('ui-state-disabled').draggable({ disabled: false });
    dropped.remove();
  }
});
$("#sortable-list").droppable({
  accept: ".item-initial",
  drop: function(e, ui) {
    var dropped = ui.draggable;
    var droppedOn = $(this);
    droppedOn.append(dropped.clone()
      .removeAttr('style')
      .removeClass("item-initial")
      .addClass("item-selected"));
    dropped.animate(dropped.data().origPosition, {
      complete: function() {
        $(this).addClass('ui-state-disabled').draggable({ disabled: true });
      }
    });
  }
});

JSFiddle: http://jsfiddle.net/马斯克/dwz4mvxa/8/

Not exactly what you asked for, but I needed an initial container where the items could be dragged to another sortable container - and thought I should share it. This was how I achieved it (jQuery 1.8.3):

$("#sortable-list").sortable();
$("#initial-list div").draggable({
  revert: true,
  revertDuration: 0
});

$("#initial-list").droppable({
  accept: ".item-selected",
  drop: function(e, ui) {
    var dropped = ui.draggable;
    var droppedOn = $(this);
    var itemInOtherList = $(this).children("#" + dropped.attr('id'));
    itemInOtherList.removeClass('ui-state-disabled').draggable({ disabled: false });
    dropped.remove();
  }
});
$("#sortable-list").droppable({
  accept: ".item-initial",
  drop: function(e, ui) {
    var dropped = ui.draggable;
    var droppedOn = $(this);
    droppedOn.append(dropped.clone()
      .removeAttr('style')
      .removeClass("item-initial")
      .addClass("item-selected"));
    dropped.animate(dropped.data().origPosition, {
      complete: function() {
        $(this).addClass('ui-state-disabled').draggable({ disabled: true });
      }
    });
  }
});

JSFiddle: http://jsfiddle.net/Muskar/dwz4mvxa/8/

╰ゝ天使的微笑 2024-08-24 22:53:11

我花了一整天的时间在这上面,并且已经接近了很多,但仍然没有达到我想要的效果。我现在拥有了所需的功能,但抛出了 Javascript 错误。

问题是,如果元素被放置在可放置对象中,而不是列表中,则可排序列表返回到其先前的位置。目前,我正在保存 html onmousedown,然后在 droppable 的 drop 函数中重写 html。这可行,但它给我一个 jquery 变量为空错误。有人能找到更好的解决方案吗?

代码:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
    <script type="text/javascript">

var templateHtml;
$(document).ready(function(){

    $("#sortable").sortable();
    $("#sortable li").addClass("drop").bind('mousedown',function(){
        templateHtml = $("#sortable").html();
    });
    $("#droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        accept:".drop",
        drop:function(event,ui){
            $("#sortable").sortable('destroy').html(templateHtml);
            $("#sortable").sortable();
            $("#sortable li").addClass("drop").bind('mousedown',function(){
                templateHtml = $("#sortable").html();
            });          
        }
    });

});

    </script>
    <style type="text/css">
    #sortable li{
        clear:both;
        float:left;
    }

    #droppable {
        clear:both;
        height:300px;
        width:400px;
        background-color:#CCC;
    }
    #droppable.active {
        background-color:#CFC;
    }
    #droppable.hovered {
        background-color:#CCF;
    }
    </style>

</head>
<body>

<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>

<div id="droppable">
Drop Here
</div>

</body>

I've spent all day on this, and I've gotten a lot closer, but still not doing as well as I'd like. I now have the functionality I need, but a Javascript error is getting thrown.

The issue is getting the sortable list to return to its previous position if the element is dropped in the droppable, rather than in the list. Currently, I'm saving the html onmousedown, then rewriting the html in the drop function of the droppable. This works, but its giving me a jquery variable is null error. Can anyone find a better solution?

Code:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
    <script type="text/javascript">

var templateHtml;
$(document).ready(function(){

    $("#sortable").sortable();
    $("#sortable li").addClass("drop").bind('mousedown',function(){
        templateHtml = $("#sortable").html();
    });
    $("#droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        accept:".drop",
        drop:function(event,ui){
            $("#sortable").sortable('destroy').html(templateHtml);
            $("#sortable").sortable();
            $("#sortable li").addClass("drop").bind('mousedown',function(){
                templateHtml = $("#sortable").html();
            });          
        }
    });

});

    </script>
    <style type="text/css">
    #sortable li{
        clear:both;
        float:left;
    }

    #droppable {
        clear:both;
        height:300px;
        width:400px;
        background-color:#CCC;
    }
    #droppable.active {
        background-color:#CFC;
    }
    #droppable.hovered {
        background-color:#CCF;
    }
    </style>

</head>
<body>

<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>

<div id="droppable">
Drop Here
</div>

</body>
刘备忘录 2024-08-24 22:53:11

通过使每个目标 DIV 成为自己的可排序项,能够获得类似的最终结果。

然后,我通过 connectWith 使所有可排序项都能够连接和共享可拖动项。

像这样的东西:

var connects = '#main_sortable, div.target';
$('#main_sortable').sortable({ connectWith: connect });
$('div').sortable({ connectWith: connect} );

Was able to get a similar end result by making the each of the target DIVs their own sortables.

I then, via connectWith, made all of the sortables able to connect and share draggables.

Something like:

var connects = '#main_sortable, div.target';
$('#main_sortable').sortable({ connectWith: connect });
$('div').sortable({ connectWith: connect} );
情话难免假 2024-08-24 22:53:11

如果您可以允许其他可放置区域也可排序,则可以使用 connectWith 选项 使用通用选择器:

<div id="droppable1" class="droppable-area"></div>
<div id="droppable2" class="droppable-area"></div>
<div id="droppable3" class="droppable-area"></div>

您的 jQuery 代码将是:

$('.droppable-area').sortable({ connectWith: '.droppable-area' });

无论如何,这个解决方案对我来说效果很好。

If you can allow your other droppable areas to be sortable as well, you can use the connectWith option with a common selector:

<div id="droppable1" class="droppable-area"></div>
<div id="droppable2" class="droppable-area"></div>
<div id="droppable3" class="droppable-area"></div>

your jQuery code would then be:

$('.droppable-area').sortable({ connectWith: '.droppable-area' });

This solution worked beautifully for me anyways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文