Я должен получить высоту элемента, который является в отделении, которое скрыто. Прямо сейчас я показываю отделение, получаю высоту и скрываю родительское отделение. Это кажется немного глупым. Существует ли лучший путь?
Я использую jQuery 1.4.2:
$select.show();
optionHeight = $firstOption.height(); //we can only get height if its visible
$select.hide();
Вы можете сделать что-то вроде этого, хотя и немного взломать, забыв позицию
, если она уже абсолютна:
var previousCss = $("#myDiv").attr("style");
$("#myDiv").css({
position: 'absolute', // Optional if #myDiv is already absolute
visibility: 'hidden',
display: 'block'
});
optionHeight = $("#myDiv").height();
$("#myDiv").attr("style", previousCss ? previousCss : "");
По определению, элемент имеет высоту, только если он видим.
Просто любопытно: зачем вам высота скрытого элемента?
Одна из альтернатив - эффективно скрыть элемент, поместив его позади (с помощью z-индекса) какого-либо наложения) .
Вы путаете два стиля CSS: стиль отображения и стиль видимости . .
Если элемент скрыт путем установки стиля css видимости, вы сможете получить высоту независимо от того, виден элемент или нет, поскольку элемент все еще занимает место на странице .
Если элемент скрыт путем изменения стиля отображения css на «none», то элемент не занимает места на странице, и вам придется задать ему стиль отображения, который приведет к тому, что элемент будет отображаться в некоторых пространство, в этот момент вы можете получить высоту.
Я действительно прибег к немного уловки, чтобы справиться с этим время от времени. Я разработал виджет полосы прокрутки jQuery, где я столкнулся с проблемой, о которой я не знаю заранее, является ли прокручиваемый контент частью скрытого фрагмента разметки или нет. Вот что я сделал:
// try to grab the height of the elem
if (this.element.height() > 0) {
var scroller_height = this.element.height();
var scroller_width = this.element.width();
// if height is zero, then we're dealing with a hidden element
} else {
var copied_elem = this.element.clone()
.attr("id", false)
.css({visibility:"hidden", display:"block",
position:"absolute"});
$("body").append(copied_elem);
var scroller_height = copied_elem.height();
var scroller_width = copied_elem.width();
copied_elem.remove();
}
По большей части это работает, но есть очевидная проблема, которая потенциально может возникнуть. Если контент, который вы клонируете, оформлен с помощью CSS, который включает ссылки на родительскую разметку в своих правилах, клонированное содержимое не будет содержать соответствующий стиль и, вероятно, будет иметь немного другие размеры. Чтобы обойти это, вы можете убедиться, что к клонируемой разметке применяются правила CSS, которые не включают ссылки на родительскую разметку.
Кроме того, это не подошло мне с моим виджетом скроллера, но чтобы получить подходящую высоту клонированного элемента, вам нужно установить ширину, равную ширине родительского элемента. В моем случае ширина CSS всегда применялась к фактическому элементу, поэтому мне не приходилось об этом беспокоиться, однако, если к элементу не применена ширина, вам может потребоваться выполнить какую-то рекурсивную обход предков DOM элемента, чтобы найти соответствующую ширину родительского элемента.
Вот сценарий, который я написал для обработки всех методов измерения jQuery для скрытых элементов, даже потомков скрытых родителей. Обратите внимание, что использование этого, конечно же, снижает производительность.
// Correctly calculate dimensions of hidden elements
(function($) {
var originals = {},
keys = [
'width',
'height',
'innerWidth',
'innerHeight',
'outerWidth',
'outerHeight',
'offset',
'scrollTop',
'scrollLeft'
],
isVisible = function(el) {
el = $(el);
el.data('hidden', []);
var visible = true,
parents = el.parents(),
hiddenData = el.data('hidden');
if(!el.is(':visible')) {
visible = false;
hiddenData[hiddenData.length] = el;
}
parents.each(function(i, parent) {
parent = $(parent);
if(!parent.is(':visible')) {
visible = false;
hiddenData[hiddenData.length] = parent;
}
});
return visible;
};
$.each(keys, function(i, dimension) {
originals[dimension] = $.fn[dimension];
$.fn[dimension] = function(size) {
var el = $(this[0]);
if(
(
size !== undefined &&
!(
(dimension == 'outerHeight' ||
dimension == 'outerWidth') &&
(size === true || size === false)
)
) ||
isVisible(el)
) {
return originals[dimension].call(this, size);
}
var hiddenData = el.data('hidden'),
topHidden = hiddenData[hiddenData.length - 1],
topHiddenClone = topHidden.clone(true),
topHiddenDescendants = topHidden.find('*').andSelf(),
topHiddenCloneDescendants = topHiddenClone.find('*').andSelf(),
elIndex = topHiddenDescendants.index(el[0]),
clone = topHiddenCloneDescendants[elIndex],
ret;
$.each(hiddenData, function(i, hidden) {
var index = topHiddenDescendants.index(hidden);
$(topHiddenCloneDescendants[index]).show();
});
topHidden.before(topHiddenClone);
if(dimension == 'outerHeight' || dimension == 'outerWidth') {
ret = $(clone)[dimension](size ? true : false);
} else {
ret = $(clone)[dimension]();
}
topHiddenClone.remove();
return ret;
};
});
})(jQuery);
Вы также можете расположить скрытый div за пределами экрана с отрицательным полем вместо использования display: none, что очень похоже на технику замены изображения с отступом текста.
например.
position:absolute;
left: -2000px;
top: 0;
Таким образом, высота () все еще доступна.