【问题标题】:When using jquery-ui Droppable, why does the accept event fire right when someone starts dragging a draggable?使用 jquery-ui Droppable 时,为什么当有人开始拖动可拖动对象时会立即触发接受事件?
【发布时间】:2013-11-16 22:53:53
【问题描述】:

我有一个包含大量jquery UI draggables and a large number of droppables 的页面。我想要一些自定义逻辑来确定 droppable 是否会接受某个可拖动对象,所以我编写了一些逻辑 in the "accept" event of the droppable。它起作用了,但我注意到的一件事是,当您开始拖动项目时,此事件会立即触发,并且当时会为所有可放置对象触发。

这似乎非常低效。我认为当你悬停时它会适合一个单独的droppable,但情况似乎并非如此。您是否有任何理由认为它以这种方式编码(因为它似乎非常低效,好像我有 100 个可放置对象,即使用户仅尝试拖动到单个可放置对象,它也会触发 100 次)而且,有什么方法可以有我想要的行为。

我想将逻辑放入放置事件中以简单地检查并删除可拖动项目(以模拟不接受它),但问题是你没有得到任何漂亮的“还原”动画所以它看起来有点不一致(与基于接受事件的结果相比)

关于我如何仍然可以插入一些自定义逻辑但不浪费循环在我移动某些东西时触发每个可放置的东西(并且仍然获得还原动画)的任何想法?

【问题讨论】:

  • 我看到你描述的 droppable 但没有接受事件的接受选项。
  • accept "event" 不只是一个过滤器来决定某些项目是否应该是可拖动的吗?
  • @megawac - 是的,但如果我有 100 个 droppable,当我拖动一个 draggable 时它会触发 100 次。 .也许我高估了它的开销
  • 你能创建一个小小提琴来演示一遍又一遍地触发的事件吗?我不知道您描述的accept 事件。谢谢
  • 你能提供一个jsfiddle吗?

标签: jquery jquery-ui-droppable


【解决方案1】:

我认为开销不是很大,但如果您确实想要一个替代解决方案:在开始时抓取可拖动元素的开始位置并将其保存在元素的 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>

【讨论】:

    【解决方案2】:

    也许这会有所帮助:

    查看这个小提琴代码(模拟不接受或接受)

    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");
            }
        });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 2014-05-21
      相关资源
      最近更新 更多