创建位于彼此顶部的多个可放置的兄弟姐妹

我试图在彼此旁边创建多个jquery droppable,其中一些部分可能重叠,在这些情况下,我希望顶部的那个(z-index wise)是贪婪的。

我已尝试在droppable中设置greedy: true选项,但这似乎没有帮助。 我还尝试在drop事件上return false并使用event.stopPropagation();

这是一个基于jquery 演示页面的jsfiddle 。

有没有办法阻止drop事件传播,如果有另一个droppable触发它,最好是具有最高z-index的那个?

使用document.elementFromPoint直接检查光标下的元素。 如果不是你的辍学者,不要做任何事情。 将以下内容添加到drop: handler的顶部:

 var droppable = $(this); ui.helper.css({pointerEvents: 'none'}); var onto = document.elementFromPoint(event.clientX, event.clientY); ui.helper.css({pointerEvents: ''}); if(!droppable.is(onto) && droppable.has(onto).length === 0) { return; } 

对于document.elementFromPoint ,在helper上禁用指针事件是必要的,可以忽略拖动的东西,只检查下面的内容。 我已经更新了你的jsFiddle以进行快速演示。 请注意,突出显示仍会影响这两个元素。 您应该能够通过不让jQuery UI执行突出显示来改变它,而是自己在draggables drag: event上编写它。 但是,我发现这在实践中无法使用,因为此检查(和禁用指针事件)非常慢并且还可能导致闪烁。

您需要一个函数来检查元素是否是最高的可见元素。 有些东西是最明显的

  1. 该项目稍后在dom列表中
  2. 它具有更高的z指数集

以下函数可用于查看当前元素(在droppable设置中的over方法或drop方法中)是否实际上是最高可见元素。

 function isHighestVisible(cEl) { cEl = $(this); //use this if you want to use it in the over method for draggable, else just pass it to the method //get all active droppable elements, based on the classes you provided var $list = $('.ui-widget-header.ui-state-active'); var listCount = $list.length; var HighestEl = null; var HighestZI = -1; //one element is always highest. if (listCount<=1) { console.log(cEl.attr('id')); return true; } //check each element $list.each(function(i) { var $el = $(this); var id = $el.attr('id'); //try to parse the z-index. If its 'auto', return 0. var zi = isNaN(parseInt($el.css('z-index'))) ? 0 : parseInt($el.css('z-index')); if (zi>0) { //z-index is set, use it. //I add the listCount to prevent errors when a low z-index is used (eg z-index=1) and there are multiple elements. //Adding the listCount assures that elements with a z-index are always later in the list then elements without it. zi = zi + listCount; } else { //z-index is not set, check for z-index on parents $el.parents().each(function() { $par = $(this); var ziParent = isNaN(parseInt($par.css('z-index'))) ? 0 : parseInt($par.css('z-index')); if (ziParent>0) { zi = ziParent; return false; } }); } //add the current index of the element to the zi zi += i; //if the calculated z-index is highest, change the highest element. if (HighestEl==null || HighestZI 

如果我有这个问题,我会使用jQuery的.addclass

 .droppablewidgetforce { z-index: 1000 !important; } 

这样做一个类,所以无论如何,这个层都保持在顶部..这应该解决问题。

贪婪的选项仅适用于具有可放置父级的嵌套元素。

在你的代码中,2个droppable元素是兄弟姐妹,所以贪婪的选项不起作用:

 

Outer droppable

Inner droppable (greedy)

如果您仍然想要使用兄弟姐妹而不是父母和孩子,这是一个混乱的解决方法。

实时代码示例 。

 function normalDraggedOver() { $( this ).addClass( "ui-state-highlight" ) .find( "> p" ) .html( "Droppeeeed!" ); } var options = { activeClass: "ui-state-hover", hoverClass: "ui-state-active", greedy: true, drop: normalDraggedOver }; var options2 = { activeClass: "ui-state-hover", hoverClass: "ui-state-active", disabledClass: "ui-state-disabled", hoverStateClass: "ui-state-hover", greedy: true, greedyWithSibligs: true, drop: normalDraggedOver, over: function () { /* if we have previous siblings of the inner element we handle them as parents */ if(options2.greedyWithSibligs && $(this).prev().length > 0) { $(this).siblings().slice(0, $(this).index()) .removeClass(options2.hoverClass) .droppable('disable') .removeClass(options2.disabledClass) .removeClass(options2.hoverStateClass); } }, out: function () { /* all the siblings of the inner element that were handled as parents act as one*/ if(options2.greedyWithSibligs && $(this).prev().length > 0) { $(this).siblings().slice(0, $(this).index()) .droppable('enable') .addClass(options2.hoverClass); console.log($(this).attr('id')); } } }; 

如果只是希望它看起来一样,你可以将#droppable3设置为position:relative并将child#droppable3-inner设置为position:absolute。

HTML:

 

Outer droppable

Inner droppable (greedy)

这是现场的例子