我正在尝试在彼此旁边创建多个jquery droppable,其中某些部分可能会重叠,在这些情况下,我希望顶部的那个(z-index wise)是贪婪的。
我已尝试在droppable中设置greedy: true
选项,但这似乎没有帮助。我还尝试在drop事件上return false
并使用了event.stopPropagation();
。
以下是基于jquery的jsfiddle的demo page。
有没有办法阻止drop事件传播,如果有另一个droppable触发它,最好是具有最高z-index的那个?
答案 0 :(得分:7)
使用document.elementFromPoint
直接检查光标下的元素。如果不是你的辍学,不要做任何事情。
将以下内容添加到drop:
处理程序的顶部:
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
忽略拖动的东西,只检查下面的内容。我已updated你的jsFiddle进行快速演示。请注意,突出显示仍会影响这两个元素。您应该能够通过不让jQuery UI进行突出显示来改变它,而是在draggables drag:
事件上自己编写。但是,我发现这在实践中无法使用,因为此检查(和禁用指针事件)非常慢并且还可能导致闪烁。
答案 1 :(得分:2)
您需要一个函数来检查元素是否是最高的可见元素。
时可以看到最高的东西以下函数可用于查看当前元素(在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<zi) {
HighestEl=$el;
HighestZI = zi;
}
});
//if the highest found active element, return true;
if (HighestEl.attr('id')==cEl.attr('id')) {
console.log(cEl.attr('id'));
return true;
}
//if all else fails, return false
return false;
}
答案 2 :(得分:0)
如果我有这个问题,我会使用jQuery的.addclass
.droppablewidgetforce {
z-index: 1000 !important;
}
如此制作一个类,这样无论如何,图层都会保持在顶部..这应该可以解决问题。
答案 3 :(得分:0)
贪婪选项仅适用于具有可放置父级的嵌套元素。
在你的代码中,2个droppable元素是兄弟姐妹,所以贪婪的选项不起作用:
<div id="droppable3" class="ui-widget-header">
<p>Outer droppable</p>
</div>
<div id="droppable3-inner" class="ui-widget-header">
<p>Inner droppable (greedy)</p>
</div>
如果您仍然想要使用兄弟姐妹而不是父母和孩子,那么这是一个混乱的解决方法。
实时代码example。
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'));
}
}
};
答案 4 :(得分:0)
如果只是希望它看起来一样,你可以将#droppable3设置为position:relative并将child#droppable3-inner设置为position:absolute。
HTML:
<div id="droppable3" class="ui-widget-header">
<p>Outer droppable</p>
</div>
<div id="droppable3-inner" class="ui-widget-header">
<p>Inner droppable (greedy)</p>
</div>
这是实时example