【问题标题】:jQueryUI droppable, stop propagation to overlapped siblingjQueryUI droppable,停止传播到重叠的兄弟
【发布时间】:2012-08-13 09:16:18
【问题描述】:

如您所见:http://jsfiddle.net/rA4CB/6/

当我在重叠区域中放置它时,它会在两个 droppables 中接收,当项目是兄弟时,贪婪不起作用。有什么办法可以阻止接收 zIndex 较低的 droppables 吗?

顺便说一句,mouseOver 不会为可放置元素触发,因为鼠标实际上是在可拖动元素上方。

相关JS:

$(function() {
    $( "#draggable" ).draggable();
    $( "#droppable" ).droppable({
        tolerance:'pointer',
        drop: function( event, ui ) {
            $( this )
                .addClass( "ui-state-highlight" )
                .find( "p" )
                    .html( "Dropped!" );
        }
    });
    $( "#droppable2" ).droppable({
        tolerance:'pointer',
        greedy:true,
        drop: function( event, ui ) {
            $( this )
                .addClass( "ui-state-highlight" )
                .find( "p" )
                    .html( "Dropped!" );
        }
    });
});

【问题讨论】:

    标签: jquery-ui jquery-ui-droppable


    【解决方案1】:

    好的,所以我花了一个小时试图弄清楚,然后我一问就找到答案

    http://jsfiddle.net/rA4CB/7/

    将JS修改为:

    $(function() {
        $( "#draggable" ).draggable();
        $( "#droppable" ).droppable({
            tolerance:'pointer',
            drop: function( event, ui ) {
                $( this )
                    .addClass( "ui-state-highlight" )
                    .find( "p" )
                        .html( "Dropped!" );
            }
        });
        $( "#droppable2" ).droppable({
            tolerance:'pointer',
            greedy:true,
            drop: function( event, ui ) {
                $( this )
                    .addClass( "ui-state-highlight" )
                    .find( "p" )
                        .html( "Dropped!" );
            },
            over: function(event, ui){
                $( "#droppable" ).droppable( "disable" )
            },
            out: function(event, ui){
                $( "#droppable" ).droppable( "enable" )
            }
        });
    });
    

    【讨论】:

    • 聪明 - 花了我一段时间看看你在那里做了什么:-)。过度/禁用和退出/启用是赢家。谢谢
    • 不错的技巧,但不适用于兄弟姐妹的数量。所以请参阅我上面对这个问题的回答。
    • 您知道如何使重叠区域不可删除吗?
    • 如果drop 被调用,则out 不会被调用,因此在删除后#droppable 将保持禁用状态。我已将 drop 更改为以与 out 相同的方式重新启用,并且在 1.8 中有效,但在 1.11 中它会导致传播再次发生。
    • 好吧,上面的评论并不完全正确......它大部分时间都有效,但在某些特殊情况下,我无法完全弄清楚它不再有效。在这些情况下,第二个“drop”处理程序在第一次重新启用然后完成时被调用。
    【解决方案2】:
    $( "#droppable" ).droppable({
        greedy: true,
        drop: function( event, ui ) {
           if(ui.helper.is(".dropped")) {
               return false;
           }
           ui.helper.addClass(".dropped");
        }
    });
    

    只需在可拖动的 ui.helper 上设置一个 css 类。如果draggable 被接受过一次,它将被所有其他droppables 拒绝(也可以使用droppable "accept" 参数来完成,例如accept : ":not(.dropped)" 和添加到ui.draggable 的类)。

    【讨论】:

    • 这应该是被接受的答案。唯一的问题是您需要从 addClass 调用中删除句点: addClass("dropped");我使用类名“接受”。唯一有效的东西。
    • 删除activate 中的dropped 类也将允许再次拖动它。
    • 如果您在可拖动对象上使用helper: "clone",这将非常有用,但如果它是默认设置(即"original"),那么可拖动对象将始终被标记为“已丢弃”并且不会起作用更多。
    • 这项技术很可靠,但我没有使用类,而是向event.originalEvent 添加了一个属性,然后对其进行了测试。无论helper 设置如何,这都将起作用。不幸的是,调用的 order drop 方法与 z-index 无关,因此如果首先调用它很重要,即使该解决方案也可能不够。
    【解决方案3】:

    如果您在容器区域中有 可放置的数量,那是什么????

    你必须重新考虑这个问题。 贪婪仅适用于父子关系,不适用于兄弟姐妹。所以你必须编辑 droppable js 或者为它添加你自己的逻辑。

    因此,如果您有多个可放置对象,那么您必须编写一些额外的代码来处理完美可放置对象的放置,就像在本示例中一样 A number of siblings droppables

    为了制作完美的 siblings droppable 修改你的 droppbale 如下

            var topElement = undefined;
            var topElementArray = Array();
    
            $( "#draggable" ).draggable();
            $( ".droppableBox" ).droppable({
                activeClass: "active-droppable",
                tolerance:'pointer',
                over: function( event, ui ) { 
                    // This is for only show a message that z-index must be required for proppable
                    // you can remove it after testing or after development
                    if ($(this).css("z-index") == 'auto') {
                        alert("Please provide z-index for every droppable.");
                        return;
                    }
                    //
    
                    topElement = undefined;
                    topElementArray = Array();
                    // Change it as you want to write in your code
                    // For Container id or for your specific class for droppable or for both
                    $('#demo > .droppableBox').each(function(){                     
                        _left = $(this).offset().left, _right = $(this).offset().left + $(this).width();
                        _top = $(this).offset().top, _bottom = $(this).offset().top + $(this).height();
                        if (event.pageX >= _left && event.pageX <= _right && event.pageY >= _top && event.pageY <= _bottom) {   
                              topElementArray.push($(this).attr('id'));
                        }
                    });
                },
                drop: function( event, ui ) {
                    if (!topElement) {
                        topElement = determineTopElement(topElementArray);
                    }                   
                    if ($(this).attr('id') == $(topElement).attr('id')) {
                        $( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
                      // Your code after successful dropped element on specific siblings
                      // Start writing code for dropped element & perfect droppable
                    }
    
                }
            });
    
            determineTopElement = function(_array) {
                var topElement;
                var zIndexHighest = 0;
                for (i = 0; i < _array.length; i++){
                   var element = $("#"+ _array[i]);
                   var z_index = $(element).css("z-index");
                   if( z_index > zIndexHighest){
                       zIndexHighest = z_index;
                       topElement = element;
                   }
                }
                return topElement;       
            }
    

    【讨论】:

    • 您知道如何使重叠区域不可删除吗?
    【解决方案4】:

    在某些情况下:

    myjQuery.droppable({
      over:function(evt,ui){
        ui.draggable.attr('drg_time', this.drg_time = evt.timeStamp)
      },
      accept:function(draggeds){
        if(draggeds.attr('drg_time'))
        {
          return draggeds.attr('drg_time') == this.drg_time
        }
        return draggeds.hasClass('acceptable_classes_here')
      },
      out:function(evt,ui){
        // useless but cleaner
        ui.draggable.removeAttr('drg_time')
      }
      drop:...,
    })
    

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题,做了一个小插件:)

      检查一下:

      https://stackoverflow.com/a/16720944/1308461

      【讨论】:

        【解决方案6】:

        我发现使用#invertedSpear 的方法会导致UI 状态发生变化,这在某些情况下是不可取的。这是代码。

        var lastOpertion = new Date().getTime();
        
        drop: function (event, ui) {
                if (new Date().getTime() - lastOpertion < 100) return;
                lastOpertion = new Date().getTime();
                ....
        }
        

        【讨论】:

          【解决方案7】:

          所以,当我试图找到简单的解决方案时,我想出了这个(它对我有用):

                      window.overNowOnThis = "";
                      window.olderOnes = [];
                      $obj.droppable({
                          accept: ".draggable_imgs",
                          drop: function(e, ui) {
                              if(window.overNowOnThis == this){
                                  // Do whatever
                              }
                          },
                          over: function(event, ui){
                              window.olderOnes.push(window.overNowOnThis);
                              window.overNowOnThis = this;
                          },
                          out: function(){
                              var lastElem = window.olderOnes.pop();
                              window.overNowOnThis = lastElem;
                          }
                      });
          

          顶部元素会被选中,因为它“over”会触发最后一个元素。此外 - 如果有两个以上的兄弟姐妹 - 那么当移出元素时,我们将最后一个设置为当前。例如,使用全局“窗口”。更好的选择是使用类,因为它可以安全地保存数据。

          【讨论】:

            【解决方案8】:

            这与倒矛回答非常相似。我不得不稍微改变一下,因为在“over”/“out”内部启用/禁用对我不起作用。我必须在下面做

            $("#droppable2").droppable({
                greedy: true,
                drop: function (event, ui) {
                    $("droppable").droppable("disable");
                }
            }
            

            当我需要它时,我必须显式启用“droppable” div。例如,在启动拖动事件时启用它。例如

            $("#drageMe").draggable({
             start:function(event,ui){
               $("droppable").droppable("enable");  
            

            } })

            【讨论】:

              【解决方案9】:

              在 ui dropable 中尝试贪婪选项。请参阅下面的小提琴链接进行演示:

              http://jsfiddle.net/creators_guru/3vT5C/embedded/result/

              $( ".circles" ).droppable({
                  greedy: true,
                  drop: function( event, ui ) {
                      $_data  =   ('drgged class = ' + ui.draggable.attr('class'));
                      $_data1 =   ('droped id = #' + $(this).attr('id'));
                      $('#data').html($_data + '<br/>'+$_data1);
                      return false;
                  }
              });
              

              【讨论】:

              • 在我的问题中,我指出“当项目是兄弟姐妹时,贪婪不起作用”
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-07-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-12-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多