JQuery: получить высоту скрытого элемента в jQuery
Мне нужно получить высоту элемента, который находится внутри div, который скрыт. Прямо сейчас я показываю div, получаю высоту и скрываю родительский div. Это кажется немного глупым. Есть ли лучший способ?
Я использую jQuery 1.4.2:
$select.show();
optionHeight = $firstOption.height(); //we can only get height if its visible
$select.hide();
Ответы
Ответ 1
Вы можете сделать что-то вроде этого, хотя и немного странно, забыть position
если она уже абсолютна:
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 : "");
Ответ 2
Я столкнулся с той же проблемой с получением ширины скрытого элемента, поэтому я написал этот плагиновый вызов jQuery Actual, чтобы исправить это. Вместо использования
$('#some-element').height();
использовать
$('#some-element').actual('height');
даст вам правильное значение для скрытого элемента или элемент имеет скрытый родительский элемент.
Полная документация смотрите здесь . На странице также есть демо.
Надеюсь, что эта помощь:)
Ответ 3
Вы смешиваете два стиля CSS, стиль и видимость стиль.
Если элемент скрыт, установив стиль css видимости, вы должны иметь возможность получать высоту независимо от того, является ли элемент видимым или нет, поскольку элемент по-прежнему занимает пробел на странице.
Если элемент скрыт, изменив стиль отображения CSS на "none", тогда элемент не займет пробела на странице, и вам придется придать ему стиль отображения, который заставит элемент визуализировать в некоторых пространство, с которого вы можете получить высоту.
Ответ 4
Я на самом деле прибегал к немного обману, чтобы справляться с этим время от времени. Я разработал виджет прокрутки 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 для определения соответствующей ширины родительского элемента.
Ответ 5
Следуя дальше, ответьте Нику:
$("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
optionHeight = $("#myDiv").height();
$("#myDiv").css({'position':'static','visibility':'visible', 'display':'none'});
Мне было лучше сделать это:
$("#myDiv").css({'position':'absolute','visibility':'hidden', 'display':'block'});
optionHeight = $("#myDiv").height();
$("#myDiv").removeAttr('style');
Настройка атрибутов CSS будет вставлять их в строку, которая перезапишет любые другие атрибуты, которые у вас есть в вашем файле CSS. Удалив атрибут стиля в элементе HTML, все возвращается в нормальное состояние и все еще скрыто, поскольку оно было спрятано в первую очередь.
Ответ 6
Основываясь далее на пользовательском ответе Ника и пользовательском плагине hitautodestruct на JSBin, я создал аналогичный плагин jQuery, который получает ширину и высоту и возвращает объект, содержащий эти значения.
Его можно найти здесь: http://jsbin.com/ikogez/3/
Обновить
Я полностью переработал этот крошечный плагин, так как оказалось, что предыдущая версия (упомянутая выше) не была реально применима в реальных условиях, где происходило много манипуляций с DOM.
Это работает отлично:
/**
* getSize plugin
* This plugin can be used to get the width and height from hidden elements in the DOM.
* It can be used on a jQuery element and will retun an object containing the width
* and height of that element.
*
* Discussed at StackOverflow:
* http://stackoverflow.com/a/8839261/1146033
*
* @author Robin van Baalen <[email protected]>
* @version 1.1
*
* CHANGELOG
* 1.0 - Initial release
* 1.1 - Completely revamped internal logic to be compatible with javascript-intense environments
*
* @return {object} The returned object is a native javascript object
* (not jQuery, and therefore not chainable!!) that
* contains the width and height of the given element.
*/
$.fn.getSize = function() {
var $wrap = $("<div />").appendTo($("body"));
$wrap.css({
"position": "absolute !important",
"visibility": "hidden !important",
"display": "block !important"
});
$clone = $(this).clone().appendTo($wrap);
sizes = {
"width": $clone.width(),
"height": $clone.height()
};
$wrap.remove();
return sizes;
};
Ответ 7
Вы также можете поместить скрытый div с экрана с отрицательным полем, а не с помощью дисплея: none, очень похожим на метод замены текста в отступом.
например.
position:absolute;
left: -2000px;
top: 0;
Таким образом, высота() все еще доступна.
Ответ 8
Следующее решение Nick Craver, настройка видимости элемента позволяет получать точные размеры. Я использовал это решение очень часто. Однако, имея reset стили вручную, я пришел, чтобы найти это громоздко, учитывая, что изменение начального позиционирования/отображения элемента в моем css через разработку часто забываю обновить связанный код javascript. Следующий код не содержит reset стилей за отзыв, но удаляет встроенные стили, добавленные javascript:
$("#myDiv")
.css({
position: 'absolute',
visibility: 'hidden',
display: 'block'
});
optionHeight = $("#myDiv").height();
optionWidth = $("#myDiv").width();
$("#myDiv").attr('style', '');
Единственное предположение здесь состоит в том, что не может быть других встроенных стилей, иначе они также будут удалены. Преимущество здесь, однако, в том, что стили элементов возвращаются к тому, что они были в таблице стилей css. Как следствие, вы можете записать это как функцию, в которой проходит элемент, и возвращается высота или ширина.
Еще одна проблема, связанная с установкой стилей inline через js, заключается в том, что при работе с переходами через css3 вы вынуждены адаптировать весы правил стиля, чтобы быть сильнее, чем встроенный стиль, который иногда может быть неприятным.
Ответ 9
Я пытаюсь найти рабочую функцию для скрытого элемента, но я понимаю, что CSS очень сложный, чем все думают. В CSS3 есть много новых методов компоновки, которые могут не работать для всех предыдущих ответов, таких как гибкий ящик, сетка, столбец или четный элемент внутри сложного родительского элемента.
пример flexibox
![enter image description here]()
Я думаю, что единственным устойчивым и простым решением является рендеринг в реальном времени. В то время браузер должен предоставить вам правильный размер элемента.
К сожалению, JavaScript не предоставляет никакого прямого события для уведомления, когда элемент отображается или скрыт. Тем не менее, я создаю некоторую функцию, основанную на DOM Attribute Modified API, которая будет выполнять функцию обратного вызова при изменении видимости элемента.
$('[selector]').onVisibleChanged(function(e, isVisible)
{
var realWidth = $('[selector]').width();
var realHeight = $('[selector]').height();
// render or adjust something
});
За дополнительной информацией, пожалуйста, посетите мой проект GitHub.
https://github.com/Soul-Master/visible.event.js
demo: http://jsbin.com/ETiGIre/7
Ответ 10
По определению элемент имеет высоту, если он виден.
Просто любопытно: зачем вам высоту скрытого элемента?
Один из вариантов заключается в том, чтобы эффективно скрыть элемент, поместив его (используя z-index) наложение какого-то типа).
Ответ 11
В моих обстоятельствах у меня также был скрытый элемент, который мешал мне получить значение высоты, но это был не сам элемент, а скорее один из его родителей... поэтому я просто поставил чек на один из моих плагинов посмотрите, скрыта ли она, и найдите ближайший скрытый элемент. Вот пример:
var $content = $('.content'),
contentHeight = $content.height(),
contentWidth = $content.width(),
$closestHidden,
styleAttrValue,
limit = 20; //failsafe
if (!contentHeight) {
$closestHidden = $content;
//if the main element itself isn't hidden then roll through the parents
if ($closestHidden.css('display') !== 'none') {
while ($closestHidden.css('display') !== 'none' && $closestHidden.size() && limit) {
$closestHidden = $closestHidden.parent().closest(':hidden');
limit--;
}
}
styleAttrValue = $closestHidden.attr('style');
$closestHidden.css({
position: 'absolute',
visibility: 'hidden',
display: 'block'
});
contentHeight = $content.height();
contentWidth = $content.width();
if (styleAttrValue) {
$closestHidden.attr('style',styleAttrValue);
} else {
$closestHidden.removeAttr('style');
}
}
На самом деле, это объединение ответов Ника, Грегори и Безумие, чтобы дать вам использование улучшенного метода Грегори, но использует оба метода в случае, если предполагается, что что-то есть в атрибуте стиля, который вы хотите вернуть, и ищет родительский элемент.
Моя единственная проблема с моим решением заключается в том, что цикл через родителей не совсем эффективен.
Ответ 12
Одним из способов является создание родительского div вне элемента, который вы хотите получить высоту, применить высоту '0' и скрыть любое переполнение. Затем возьмите высоту дочернего элемента и удалите свойство переполнения родителя.
var height = $("#child").height();
// Do something here
$("#parent").append(height).removeClass("overflow-y-hidden");
.overflow-y-hidden {
height: 0px;
overflow-y: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent" class="overflow-y-hidden">
<div id="child">
This is some content I would like to get the height of!
</div>
</div>
Ответ 13
Здесь script я написал для обработки всех методов измерения 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);
Ответ 14
Если вы уже показывали элемент на предыдущей странице, вы можете просто взять высоту непосредственно из элемента DOM (доступного в jQuery с .get(0)), поскольку он установлен даже тогда, когда элемент скрыт:
$('.hidden-element').get(0).height;
одинаково для ширины:
$('.hidden-element').get(0).width;
(спасибо Skeets O'Reilly за исправление)
Ответ 15
$('#idOfElement').height();
//, чтобы найти высоту