这是该选项的 jQuery UI 文档中的部分tolerance
:
这是拖动期间重新排序的行为方式。可能的值:“相交”、“指针”。在某些设置中,“指针”更自然。
intersect: draggable 与 droppable 重叠至少 50%
默认值为intersect
,但如果鼠标指针不在可排序项目上方,则不会发生排序,无论拖动的元素至少超过另一个可排序项目的 50%(我期望的功能)这发生在演示页面上好(上面链接)
这是 jQuery UI 中的错误,还是我理解错误?
这是该选项的 jQuery UI 文档中的部分tolerance
:
这是拖动期间重新排序的行为方式。可能的值:“相交”、“指针”。在某些设置中,“指针”更自然。
intersect: draggable 与 droppable 重叠至少 50%
默认值为intersect
,但如果鼠标指针不在可排序项目上方,则不会发生排序,无论拖动的元素至少超过另一个可排序项目的 50%(我期望的功能)这发生在演示页面上好(上面链接)
这是 jQuery UI 中的错误,还是我理解错误?
对于那些有同样问题的人,这是我使用的解决方法:
$('#sortable').sortable({
axis: 'x',
sort: function (event, ui) {
var that = $(this),
w = ui.helper.outerWidth();
that.children().each(function () {
if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder'))
return true;
// If overlap is more than half of the dragged item
var dist = Math.abs(ui.position.left - $(this).position().left),
before = ui.position.left > $(this).position().left;
if ((w - dist) > (w / 2) && (dist < w)) {
if (before)
$('.ui-sortable-placeholder', that).insertBefore($(this));
else
$('.ui-sortable-placeholder', that).insertAfter($(this));
return false;
}
});
},
});
这适用于水平排序,垂直变化到outerWidth
任何地方。outerHeight
position.left
position.top
我有大小不均的可分类项目,这让事情变得更糟。我已经修改了 dioslaska 的代码,以在处理程序的底部通过孩子的底部(向下移动时)和顶部相同的情况下更改顺序......
sort: function (event, ui) {
var that = $(this),
draggedHeight = ui.helper.outerHeight(),
originalTop = ui.originalPosition.top,
draggedTop = ui.helper.position().top,
draggedBottom = draggedTop + draggedHeight;
that.children().each(function () {
if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder')) {
return true;
}
var childTop = $(this).position().top,
childHeight = $(this).outerHeight(),
childBottom = childTop + childHeight,
isChildAfter = originalTop < childTop,
largeTop,largeBottom,smallTop,smallBottom;
if (childHeight > draggedHeight) {
largeTop = childTop;
largeBottom = childTop + childHeight;
smallTop = draggedTop;
smallBottom = draggedBottom;
} else {
smallTop = childTop;
smallBottom = childTop + childHeight;
largeTop = draggedTop;
largeBottom = draggedBottom;
}
if (smallBottom > largeTop || smallTop < largeBottom) {
if (isChildAfter && draggedBottom >= childBottom) {
$('.ui-sortable-placeholder', that).insertAfter($(this));
} else if (!isChildAfter && draggedTop <= childTop) {
$('.ui-sortable-placeholder', that).insertBefore($(this));
return false;
}
}
});
}
您可以看到重叠检测比以前有点棘手,因为您可能将大项目拖到小项目上,反之亦然。
它并不完美,但它是对默认功能的巨大改进。
这是@dioslaska 功能的补充。如果您需要在网格中排序(例如,您的元素是浮动的),您可以检查子元素的顶部位置,看看它是否在同一个“行”中,如下所示:
sort: function (event, ui) {
var self = $(this),
width = ui.helper.outerWidth(),
top = ui.helper.position().top;//changed to ;
self.children().each(function () {
if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder')) {
return true;
}
// If overlap is more than half of the dragged item
var distance = Math.abs(ui.position.left - $(this).position().left),
before = ui.position.left > $(this).position().left;
if ((width - distance) > (width / 2) && (distance < width) && $(this).position().top === top) {
if (before) {
$('.ui-sortable-placeholder', self).insertBefore($(this));
} else {
$('.ui-sortable-placeholder', self).insertAfter($(this));
}
return false;
}
});
}
这是我基于勾股定理和比较元素中心之间的距离的网格布局sort
方法的实现:
$("#sortable").sortable({
...
sort: sort_jQueryBug8342Fix
});
function sort_jQueryBug8342Fix(e, ui) {
// ui-sortable-helper: element being dragged
// ui-sortable-placeholder: invisible item on the original place of dragged item
var container = $(this);
var placeholder = container.children('.ui-sortable-placeholder');
var draggedCenterX = ui.helper.position().left + ui.helper.outerWidth()/2;
var draggedCenterY = ui.helper.position().top + ui.helper.outerHeight()/2;
container.children().each(function () {
var item = $(this);
if(!item.hasClass( 'ui-sortable-helper' ) && !item.hasClass( 'ui-sortable-placeholder' ) ) {
var itemCenterX = item.position().left + item.outerWidth()/2;
var itemCenterY = item.position().top + item.outerHeight()/2;
// Pythagorean theorem
var distanceBetweenCenters = Math.sqrt(Math.pow(itemCenterX - draggedCenterX, 2) + Math.pow(itemCenterY - draggedCenterY, 2));
var minDimension = Math.min(item.outerWidth(), item.outerHeight(), ui.helper.outerWidth(), ui.helper.outerHeight());
var overlaps = distanceBetweenCenters < (minDimension / 2);
if (overlaps) {
if (placeholder.index() > item.index()) {
placeholder.insertBefore(item);
} else {
placeholder.insertAfter(item);
}
container.sortable('refreshPositions');
return false;
}
}
});
}
它适用于网格布局和宽度和高度尺寸接近的项目,例如 4:3 或 16:10 比例的图像缩略图。在这种情况下,它需要 50-60% 的重叠来触发排序。如果您有非常宽的元素,例如 300x50 像素(或不同大小的元素),那么我想它也可以,但是您必须将它们与 X 轴重叠更多,例如 90%。
注意:如果您正在对 Dropzone.js 元素进行排序,&& item.hasClass('dz-preview')
则应将其添加到第一条if
语句中。
这与您在 IE9、FF11 和 Chrome18 中描述的完全一样。
当鼠标至少高于 50% 时相交重叠。
我认为这是不正确的文档。
编辑:我在 JQuery Bugtracker 中没有发现与此相关的错误。
稍微扩展 dioslaska 的答案。这是一个示例(我称之为)125% 重叠http://jsfiddle.net/yj1wwtsd/4/。
这只会在您超过 25% 时翻转一个元素。在我的情况下,我结合了 droppable 和 sortable,当拖动的项目在翻转之前可以完全重叠另一个(以允许放置)时感觉更好。
特别值得注意的是最后一行的 jQueryUI hack。如果没有这个,它总是默认为相交容差,即使排序方法试图做一些不同的事情。这可能会与 jQueryUI 的未来版本(使用 1.11.2 测试)中断。
$('#sortable').sortable({
axis: 'x',
sort: function (event, ui) {
var that = $(this);
var w = ui.helper.outerWidth();
var centreOfDraggedItem = ui.position.left + w/2;
that.children().each(function () {
if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder'))
return true;
var centreOfThisItem = $(this).position().left + w/2;
var dist = centreOfDraggedItem - centreOfThisItem;
var before = centreOfDraggedItem > centreOfThisItem;
if (Math.abs(dist) < w/2) {
if (before && dist > w/4) { // moving right
$('.ui-sortable-placeholder').insertAfter($(this));
return false;
}
if (!before && dist < -(w/4)) { // moving left
$('.ui-sortable-placeholder').insertBefore($(this));
return false;
}
}
});
},
});
$('#sortable').data('ui-sortable')._intersectsWithPointer = function () {return false;};