Как я могу оживить элемент до его естественной высоты, используя jQuery
Я пытаюсь получить элемент, чтобы оживить его "естественную" высоту, то есть высоту, если бы она имела height: auto;
.
Я придумал это:
var currentHeight = $this.height();
$this.css('height', 'auto');
var height = $this.height();
$this.css('height', currentHeight + 'px');
$this.animate({'height': height});
Есть ли лучший способ сделать это? Он чувствует себя немного взломанным.
Изменить:
Здесь полный script, чтобы играть с тем, кто хочет протестировать.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>jQuery</title>
<style type="text/css">
p { overflow: hidden; background-color: red; border: 1px solid black; }
.closed { height: 1px; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript">
$().ready(function()
{
$('div').click(function()
{
$('p').each(function()
{
var $this = $(this);
if ($this.hasClass('closed'))
{
var currentHeight = $this.height();
$this.css('height', 'auto');
var height = $this.height();
$this.css('height', currentHeight + 'px');
$this.animate({'height': height});
}
else
{
$this.animate({'height': 1});
}
$this.toggleClass('closed');
});
});
});
</script>
</head>
<body>
<div>Click Me</div>
<p>Hello - I started open</p>
<p class="closed">Hello - I started closed</p>
</body>
</html>
Ответы
Ответ 1
Я мог бы предложить такое же хакерское решение... Клонировать элемент, позиционировать его вне поля зрения и получить его высоту... затем удалить его и оживить оригинал.
В стороне, вы также можете использовать $.slideUp() и $.slideDown():
$this.hasClass('closed') ? $(this).slideDown() : $(this).slideUp() ;
Если вам нужно сохранить строку 1px, вы можете применить ее к родительскому элементу:
<div style='border-top:1px solid #333333'>
<div class='toggleMe'>Hello World</div>
</div>
И примените slideUp/Down на div.toggleMe.
Ответ 2
Я разрешаю себе ответить на эту тему, даже если на это уже давно ответили, потому что это просто помогло мне.
На самом деле, я не понимаю первый ответ: зачем открывать полузакрытый элемент, чтобы получить его высоту, а затем снова закрыть его?
В начале вы скрываете элемент так, чтобы отображалась только часть его, не так ли? Лучший способ (я полагаю) сделать это уже, с javascript. Таким образом, когда вы скрываете элемент onready, просто сохраняйте высоту orig в var, поэтому вам не нужно скрывать (onready) -show-save height-hide, чтобы иметь возможность переключать видимость элементов.
Посмотрите, что я сделал, он отлично работает:
$(document).ready(function(){
var origHeight = $("#foo").css('height');
$("#foo").css({"height" : "80px"});
$("#foo .toggle").bind("click", function(event){ toggleFoo(event, lastSearchesMidHeight); });
});
Здесь, когда вы вызываете свою функцию переключения, вы знаете, какова ваша первоначальная высота элемента без зависания.
Я написал это быстро, надеясь, что это может помочь кому-то в будущем.
Ответ 3
Самое простое решение, которое я нашел, - просто обернуть элемент контента с помощью div, который ограничен по высоте и установлен в overflow: hidden. Это обрезает внутренний элемент содержимого на высоту оберточного div. когда пользователь нажимает, наводит и т.д., чтобы показать всю высоту элемента содержимого - просто анимируйте обертывающий div на высоту внутреннего содержимого div.
Ответ 4
Я также хотел бы прослушивать этот старый поток, если можно, на случай, если мое решение поможет кому угодно. Моя конкретная ситуация такова: у меня есть div, которые заданы с максимальным значением высоты, которое ограничивает их тремя строками, и когда пользователь навешивает их, я хочу, чтобы они расширялись до их естественной высоты; и когда курсор мыши покидает div, я хочу, чтобы они сжимались до обрезанной высоты с максимумом в три строки. Мне нужно использовать свойство max-height CSS, а не height, потому что у меня есть div, содержащий только одну или две строки текста, и я не хочу, чтобы они были неоправданно высокими.
Я пробовал много решений в этом потоке, и тот, который работал у меня, был "хакерским предложением", включающим клонированные элементы, предложенные Джонатаном Сампсоном. Я перевел его идею в следующий код. Пожалуйста, не стесняйтесь предлагать улучшения.
Функции делегируются родительскому элементу для обработки div, созданного с помощью вызова Ajax. Класс div.overflow_expandable
имеет следующее объявление: { max-height: 5em; overflow: hidden; }
$('#results').delegate('div.overflow_expandable', 'mouseenter', function() {
var $this = $(this);
// Close any other open divs
$('#results div.overflow_expandable').not($(this)).trigger('mouseleave');
// We need to convert the div current natural height (which is less than
// or equal to its CSS max-height) to be a defined CSS 'height' property,
// which can then animate; and we unset max-height so that it doesn't
// prevent the div from growing taller.
if (!$this.data('originalHeight')) {
$this.data('originalHeight', $this.height());
$this.data('originalMaxHeight', parseInt($this.css('max-height')));
$this.css({ 'max-height':'none',
height: $this.data('originalHeight') });
}
// Now slide out if the div is at its original height
// (i.e. in 'closed' state) and if its original height was equal to
// its original 'max-height' (so when closed, it had overflow clipped)
if ($this.height() == $this.data('originalHeight') &&
$this.data('originalMaxHeight') == $this.data('originalHeight')) {
// To figure out the new height, clone the original element and set
// its height to auto, then measure the cloned element new height;
// then animate our div to that height
var $clone = $this.clone().css({ height: 'auto', position: 'absolute',
zIndex: '-9999', left: '-9999px', width: $this.width() })
.appendTo($this);
$this.animate({ height: $clone.height() }, 'slow');
$clone.detach();
}
}).delegate('div.overflow_expandable', 'mouseleave', function() {
var $this = $(this);
// If the div has 'originalHeight' defined (it been opened before) and
// if it current height is greater than 'originalHeight' (it open
// now), slide it back to its original height
if ($this.data('originalHeight') &&
$this.height() > $this.data('originalHeight'))
$this.animate({ height: $this.data('originalHeight') }, 'slow');
});
Ответ 5
Нашел этот пост и в конечном итоге использовал оригинальное предложение 1px от Greg - отлично работает!
Просто добавлен обратный вызов функции animate, чтобы установить высоту элемента в "auto", когда анимация заканчивается (в моем случае содержимое этого конкретного элемента может меняться и быть больше).
Ответ 6
$('div').click(function() {
if($('p').is(':hidden')) {
$('p').slideUp();
} else {
$('p').slideDown(function() { $('p').css('height','1px'); });
}
}
Это должно установить, что высота p-тегов будет равна 1px после того, как они закончатся.
Ответ 7
Это сработало для меня.
<div class="product-category">
<div class="category-name">
Cars
</div>
<div class="category-products" style="display: none; overflow: hidden;">
<div class="product">Red Car</div>
<div class="product">Green Car</div>
<div class="product">Yellow Car</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('.product-category .category-name').click(function() {
if ($(this).parent().hasClass('active')) {
$(this).parent().removeClass('active');
var height = $(this).parent().find('.category-products').height();
$(this).parent().find('.category-products').animate({ height : '0px' }, 600, function() {
$(this).parent().find('.category-products').height(height).hide();
});
} else {
$(this).parent().addClass('active');
var height = $(this).parent().find('.category-products').height();
$(this).parent().find('.category-products').height(0).show().animate({ height : height + 'px' }, 600);
}
});
});
</script>
Ответ 8
Мое решение состоит в том, чтобы сохранить в атрибуте data
кнопки закрытия оригинальный размер контейнера (может быть сохранен также в самом контейнере, если вы не используете ту же кнопку, чтобы снова отобразить контейнер)
$(document).ready(function(){
$('.infoBox .closeBtn').toggle(hideBox, showBox);
});
function hideBox()
{
var parent = $(this).parent();
$(this).text('Show').data('originalHeight', parent.css('height'));
parent.animate({'height': 20});
return false;
}
function showBox()
{
var parent = $(this).parent();
$(this).text('Hide');
parent.animate({
'height': $(this).data('originalHeight')
});
return false;
}
Ответ 9
Я хотел указать на этот ответ, который предлагает установить высоту для "show" с помощью функции animate(). Мне пришлось изменить стиль "slideUp", чтобы использовать высоту: "скрыть", чтобы работать с ней.