当使用jquery-ui Droppable时,为什么当有人开始拖动拖动时,accept事件会触发?

时间:2013-11-16 22:53:54

标签: jquery jquery-ui-droppable

我有一个包含大量jquery UI draggables and a large number of droppable个页面的页面。我想要一些自定义逻辑来确定droppable是否会接受某个draggable,所以我编写了一些逻辑in the "accept" event of the droppable。它有效,但有一件事我注意到,当你开始拖动一个项目时,这个事件就会激发,并且当时它会触发所有的droppables。

这似乎非常低效。我认为当你悬停时,单个可放置的权利是正确的,但事实并非如此。有没有什么理由你认为它的编码方式(因为它看起来非常无效,好像我有100个droppables,即使用户只是试图拖入一个droppable也会发射100次)还有,有什么方法可以有我想要的行为。

我想把逻辑放入drop事件中以简单地做我的检查并删除可拖动的项目(以模拟不接受它),但问题是你没有得到任何一个很好的“revert”动画所以它看起来有点不一致(比较基于接受事件你会看到的)

我有什么想法仍然可以插入一些自定义逻辑,但是当我移动某些东西时(但仍然可以获得恢复动画),不会浪费周期来触发每一个可放置的东西?

2 个答案:

答案 0 :(得分:2)

我不认为开销很大,但是如果你想要一个替代解决方案:在开始时抓住可拖动元素的起始位置并将其保存在元素的data()中。在drop例程中进行逻辑检查。如果失败,则将元素设置为startPosition动画。这将确保事件仅特定于被拖动的元素和可放置的元素。

http://jsfiddle.net/samnunnally/sgy29/2/

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>droppable demo</title>
<link rel="stylesheet"
    href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<style>

#notAllowed {
    width: 100px;
    height: 100px;
    background: #ccc;
}

#allowed {
    width: 100px;
    height: 100px;
    background: red;
}

#droppable {
    position: absolute;
    left: 250px;
    top: 0;
    width: 125px;
    height: 125px;
    background: #999;
    color: #fff;
    padding: 10px;
}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
</head>
<body>
    <div id="droppable" >Drop here</div>
    <div id="notAllowed" >not allowed to drop</div>
    <div id="allowed">allowed to drop</div>
    <script>

        function capturePosition(event, ui) {

            ui.helper.data( 'startPosition', ui.position);
        }
$( document ).ready(function() {

        $("#notAllowed").draggable({
            start : capturePosition
        });

        $("#allowed").draggable({
            start : capturePosition
        });

        $("#droppable").droppable({
            drop : function(event, ui) {
                //do logic to determine if it can be dropped
                if(ui.draggable.attr('id') == 'notAllowed'){
                   var startPosition = ui.draggable.data('startPosition');
                   ui.draggable
                    .animate({ 
                    'left': 
                    '+='+ (startPosition.left - ui.draggable.offset().left + $('body').offset().left) + 'px' }, 
                    'slow' )

                    .animate({
                    'top': 
                    '+='+ (startPosition.top - ui.draggable.offset().top + + $('body').offset().top) + 'px' }, 
                    'slow' );
                }
            }
        });
}
    </script>
</body>
</html>

答案 1 :(得分:1)

也许这会有所帮助:

  

请参阅此小提琴代码(模拟不接受或接受)

http://jsfiddle.net/penjepitkertasku/VYQcW/8/

这将确保事件仅特定于被拖动的元素和可放置的

$(function() {

    //global
    var dname = "";

    //position
    var d1left = $("#droppable1").position().left + 20;
    var d1top = $("#droppable1").position().top + 30;
    $("#draggable1").css({'position': 'absolute', 'left': (d1left*1) + 'px', 'top': ((d1top*1)+15) + 'px'});
    $("#draggable2").css({'position': 'absolute', 'left': (d1left*1) + 'px', 'top': ((d1top*2)+20) + 'px'});

    //checkbox
    $(".checkbox").change(function(){
        $(this).next().text(this.checked === true ? 'invalid' : 'valid');
    });

    //drag
    $("#draggable1").draggable({ revert: 'valid' });
    $("#draggable2").draggable({ revert: 'invalid' });

    //event
    $(".draggable").mousedown(function(){
        dname = this.id;
    });

    //drop
    $("#droppable1, #droppable2").droppable({
        activeClass: 'ui-state-hover',
        hoverClass: 'ui-state-active',
        drop: function(event, ui) {
            console.log(dname);
            var _checboxid = $("#" + dname + ' input[type=checkbox]');
            var _revert = _checboxid.is(':checked') ? 'invalid' : 'valid';
            $("#" + dname).draggable("option", "revert", _revert);
        },
        out: function( event, ui ) {
            $("#" + dname).draggable("option", "revert", "invalid");
        }
    });
});