diff --git a/src/Sortable.js b/src/Sortable.js index 7a8c779b8..8147c97d5 100644 --- a/src/Sortable.js +++ b/src/Sortable.js @@ -34,7 +34,8 @@ import { throttle, scrollBy, clone, - expando + expando, + getContentRect } from './utils.js'; @@ -1788,21 +1789,23 @@ function _unsilent() { } function _ghostIsFirst(evt, vertical, sortable) { - let rect = getRect(getChild(sortable.el, 0, sortable.options, true)); + let firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true)); + const sortableContentRect = getContentRect(sortable.el); const spacer = 10; return vertical ? - ((evt.clientX < rect.left - spacer) || (evt.clientY < rect.top && evt.clientX < rect.right)) : - ((evt.clientY < rect.top - spacer) || (evt.clientY < rect.bottom && evt.clientX < rect.left)) + (evt.clientX < sortableContentRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right) : + (evt.clientY < sortableContentRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left) } function _ghostIsLast(evt, vertical, sortable) { - let rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + const lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable)); + const sortableContentRect = getContentRect(sortable.el); const spacer = 10; return vertical ? - (evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left) : - (evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer); + (evt.clientX > sortableContentRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left) : + (evt.clientY > sortableContentRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top); } function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { diff --git a/src/utils.js b/src/utils.js index cdb8cc774..b7649629e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -254,6 +254,26 @@ function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoS }; } +/** + * Returns the content rect of the element (bounding rect minus border and padding) + * @param {HTMLElement} el + */ +function getContentRect(el) { + let rect = getRect(el); + const paddingLeft = parseInt(css(el, 'padding-left')), + paddingTop = parseInt(css(el, 'padding-top')), + paddingRight = parseInt(css(el, 'padding-right')), + paddingBottom = parseInt(css(el, 'padding-bottom')); + rect.top += paddingTop + parseInt(css(el, 'border-top-width')); + rect.left += paddingLeft + parseInt(css(el, 'border-left-width')); + // Client Width/Height includes padding only + rect.width = el.clientWidth - paddingLeft - paddingRight; + rect.height = el.clientHeight - paddingTop - paddingBottom; + rect.bottom = rect.top + rect.height; + rect.right = rect.left + rect.width; + return rect; +} + /** * Checks if a side of an element is scrolled past a side of its parents * @param {HTMLElement} el The element who's side being scrolled out of view is in question @@ -552,5 +572,6 @@ export { clone, setRect, unsetRect, + getContentRect, expando };