Correct positioning issues for statically positioned elements
There was a commit that landed in 4.0.1 that fixed positioning for
non-static elements, which are commonly used for the custom
`dropdownParent` option, but broke positioning for statically positioned
elements, commonly used in almost every other case. That commit was
c9216b4b96
This fixes the positioning issues caused by that commit by properly
calculating the offsets for statically positioned parents. Statically
positioned parents are unique, because the offset for the dropdown must
be calculated based on the closest element that is non-statically
positioned. Otherwise, the offset for any statically positioned parent
other than the body will be considerably higher than it should be,
resulting in the dropdown being offset by a large amount.
The offset parent for the body element is the html element, which is why
this works for both the body element and any custom parents for the
dropdown. This would not be needed if the parent wasn't customizable (as
seen in Select2 3.x) because you will never need to offset the body
element if it is statically positioned, because the html element almost
never has an offset.
This also fixes JSHint issues within the tests added in the last commit.
This closes https://github.com/select2/select2/issues/3970
This closes https://github.com/select2/select2/issues/3639
This commit is contained in:
parent
b5a4698250
commit
e260860789
16
src/js/select2/dropdown/attachBody.js
vendored
16
src/js/select2/dropdown/attachBody.js
vendored
@ -157,14 +157,20 @@ define([
|
|||||||
top: container.bottom
|
top: container.bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fix positioning with static parents
|
// Determine what the parent element is to use for calciulating the offset
|
||||||
if (this.$dropdownParent[0].style.position !== 'static') {
|
var $offsetParent = this.$dropdownParent;
|
||||||
var parentOffset = this.$dropdownParent.offset();
|
|
||||||
|
|
||||||
css.top -= parentOffset.top;
|
// For statically positoned elements, we need to get the element
|
||||||
css.left -= parentOffset.left;
|
// that is determining the offset
|
||||||
|
if ($offsetParent.css('position') === 'static') {
|
||||||
|
$offsetParent = $offsetParent.offsetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentOffset = $offsetParent.offset();
|
||||||
|
|
||||||
|
css.top -= parentOffset.top;
|
||||||
|
css.left -= parentOffset.left;
|
||||||
|
|
||||||
if (!isCurrentlyAbove && !isCurrentlyBelow) {
|
if (!isCurrentlyAbove && !isCurrentlyBelow) {
|
||||||
newDirection = 'below';
|
newDirection = 'below';
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,12 @@ test('appends to the dropdown parent', function (assert) {
|
|||||||
test('dropdown is positioned with static margins', function (assert) {
|
test('dropdown is positioned with static margins', function (assert) {
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var $select = $('<select></select>');
|
var $select = $('<select></select>');
|
||||||
var $parent = $('<div style="position: static; margin-top: 5px; margin-left: 10px;"></div>');
|
var $parent = $('<div></div>');
|
||||||
|
$parent.css({
|
||||||
|
position: 'static',
|
||||||
|
marginTop: '5px',
|
||||||
|
marginLeft: '10px'
|
||||||
|
});
|
||||||
|
|
||||||
var $container = $('<span></span>');
|
var $container = $('<span></span>');
|
||||||
var container = new MockContainer();
|
var container = new MockContainer();
|
||||||
@ -111,7 +116,12 @@ test('dropdown is positioned with static margins', function (assert) {
|
|||||||
test('dropdown is positioned with absolute offsets', function (assert) {
|
test('dropdown is positioned with absolute offsets', function (assert) {
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var $select = $('<select></select>');
|
var $select = $('<select></select>');
|
||||||
var $parent = $('<div style="position: absolute; top: 10px; left: 5px;"></div>');
|
var $parent = $('<div></div>');
|
||||||
|
$parent.css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: '10px',
|
||||||
|
left: '5px'
|
||||||
|
});
|
||||||
|
|
||||||
var $container = $('<span></span>');
|
var $container = $('<span></span>');
|
||||||
var container = new MockContainer();
|
var container = new MockContainer();
|
||||||
|
Loading…
Reference in New Issue
Block a user