Задача использования на сайте различных анимированных объектов, как то меню или фотогалерея, уже давно не является редкостью. И здесь на помощь разработчикам приходит замечательный jquery-метод animate(). Этот метод позволяет манипулировать различными свойствами css, но имеет один довольно существенный недостаток – в качестве значения свойства может использоваться только число, либо значения hide, show и toggle. Например, height:20 – верно, а вот height:auto будет работать не всегда и не везде.
Рассмотрим конкретный пример.
Допустим, необходимо разработать вертикальное двухуровневое меню. По умолчанию открыты только пункты первого уровеня, а при клике на соответствующую ссылку, сначала скрывается открытый подуровень, а затем открывается нужный скрытый. Но не просто открываются, а анимировано с увеличением высоты и прозрачности контейнера.
То есть, в итоге нужно получить вот такое меню:

Пишем HTML код нашего будущего меню:
«magic1» class=«magic»>Меню 2
«2» class=«menu»>Меню 1<br/>
«magic2» class=«magic»>Меню 2<br/>Меню 2<br/>Меню 2
«3» class=«menu»>Меню 1<br/>
«magic3» class=«magic»>Меню 2
Css:
И javascript:
При клике по пункту меню, мы скрываем все блоки класса «magic», и раскрываем тот из них, который содержит нужные нам подпункты.
Казалось бы, все должно работать, но это совсем не так. Вместо значения свойства height «auto» Firefox, Google Chrome и Opera устанавливают для контейнера высоту в 10px, которая была прописана нами в css, а IE7 и вовсе выдает ошибку: недопустимый аргумент.
Как же с этим бороться?
С одной стороны, можно вместо метода animate() применить методы hide() и show() с длительностью в те же самые 500 миллисекунд. Однако, во-первых, появление одних пунктов при клике и скрывание других будет происходить параллельно, а не последовательно, как необходимо нам. А во-вторых, при использовании методов hide() и show() плавно изменяются все стили объекта, то есть, необходимый нам padding так же будет меняться от 0 до 10 и обратно. Эффект, конечно, красивый, но в данном случае не нужный.
Идея состоит в том, чтобы предварительно, до начала работы с меню, записать в массив значения высот всех необходимых контейнеров, а потом вместо «auto» подставлять значение элемента этого массива. То есть, новый javascript-код будет выглядеть следующим образом.
Таким образом, мы избавимся от использования устанавливаемого значения высоты, равного «auto», и заменим его конкретным числовым значением. Это поможет нам избавиться от ошибки в IE, но, как оказалось, не решит проблемы с истинным значением высоты контейнера, ведь все браузеры продолжат выставлять в качестве нового значения 10px. То есть, на экране мы увидим вот что:

Для того, чтобы справиться с этой проблемой, уберем из свойств класса «magic» значение высоты, а устанавливать его будем динамически после записи истинного значения высоты в массив.
Новый css-файл будет выглядеть так:
А javascript так:
Ну и для полного счастья, можно добавить некую переменную «first», которая будет равна 0 после загрузки страницы, и примет значение 1 после первого клика по пункту меню. Она нужна для того, чтобы избавиться от задержки в 500 миллисекунд на скрывание открытого подуровня меню, когда все подуровни скрыты.
Окончательно javascript будет выглядеть так:
Рабочий пример можно скачать здесь.
Рассмотрим конкретный пример.
Допустим, необходимо разработать вертикальное двухуровневое меню. По умолчанию открыты только пункты первого уровеня, а при клике на соответствующую ссылку, сначала скрывается открытый подуровень, а затем открывается нужный скрытый. Но не просто открываются, а анимировано с увеличением высоты и прозрачности контейнера.
То есть, в итоге нужно получить вот такое меню:

Пишем HTML код нашего будущего меню:
"1" class="menu">Меню 1<br/>
«magic1» class=«magic»>Меню 2
«2» class=«menu»>Меню 1<br/>
«magic2» class=«magic»>Меню 2<br/>Меню 2<br/>Меню 2
«3» class=«menu»>Меню 1<br/>
«magic3» class=«magic»>Меню 2
Css:
div.magic{
filter:alpha(opacity=0);
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 0;
overflow:hidden;
padding-left:10px;
}
И javascript:
$(document).ready(function(){
$("a.menu").click(
function(){
$("div.magic").animate({
opacity: 0,
height: "10px"
}, 500);
$("div#magic"+ this.id).animate({
opacity: 1,
height: "auto"
}, 500);
}
);
})
При клике по пункту меню, мы скрываем все блоки класса «magic», и раскрываем тот из них, который содержит нужные нам подпункты.
Казалось бы, все должно работать, но это совсем не так. Вместо значения свойства height «auto» Firefox, Google Chrome и Opera устанавливают для контейнера высоту в 10px, которая была прописана нами в css, а IE7 и вовсе выдает ошибку: недопустимый аргумент.
Как же с этим бороться?
С одной стороны, можно вместо метода animate() применить методы hide() и show() с длительностью в те же самые 500 миллисекунд. Однако, во-первых, появление одних пунктов при клике и скрывание других будет происходить параллельно, а не последовательно, как необходимо нам. А во-вторых, при использовании методов hide() и show() плавно изменяются все стили объекта, то есть, необходимый нам padding так же будет меняться от 0 до 10 и обратно. Эффект, конечно, красивый, но в данном случае не нужный.
Идея состоит в том, чтобы предварительно, до начала работы с меню, записать в массив значения высот всех необходимых контейнеров, а потом вместо «auto» подставлять значение элемента этого массива. То есть, новый javascript-код будет выглядеть следующим образом.
$(document).ready(function(){
var height_element= new Array();
for(i=1;i<=$("div.magic").length;i++)
{
height_element[i]=$("div#magic"+i).height();
}
$("a.menu").click(
function(){
$("div.magic").animate({
opacity: 0,
height: "10px"
}, 500);
$("div#magic"+ this.id).animate({
opacity: 1,
height: height_element[this.id]+'px'
}, 500);
}
);
})
Таким образом, мы избавимся от использования устанавливаемого значения высоты, равного «auto», и заменим его конкретным числовым значением. Это поможет нам избавиться от ошибки в IE, но, как оказалось, не решит проблемы с истинным значением высоты контейнера, ведь все браузеры продолжат выставлять в качестве нового значения 10px. То есть, на экране мы увидим вот что:

Для того, чтобы справиться с этой проблемой, уберем из свойств класса «magic» значение высоты, а устанавливать его будем динамически после записи истинного значения высоты в массив.
Новый css-файл будет выглядеть так:
div.magic{
filter:alpha(opacity=0);
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 0;
padding-left:10px;
overflow:hidden;
}
А javascript так:
$(document).ready(function(){
var height_element= new Array();
for(i=1;i<=$("div.magic").length;i++)
{
height_element[i]=$("div#magic"+i).height();
}
$("div.magic").css("height","10px");
$("a.menu").click(
function(){
$("div.magic").animate({
opacity: 0,
height: "10px"
}, 500);
$("div#magic"+ this.id).animate({
opacity: 1,
height: height_element[this.id]+”px”
}, 500);
}
);
})
Ну и для полного счастья, можно добавить некую переменную «first», которая будет равна 0 после загрузки страницы, и примет значение 1 после первого клика по пункту меню. Она нужна для того, чтобы избавиться от задержки в 500 миллисекунд на скрывание открытого подуровня меню, когда все подуровни скрыты.
Окончательно javascript будет выглядеть так:
$(document).ready(function(){
var height_element= new Array();
var first=0;
for(i=1;i<=$("div.magic").length;i++)
{
height_element[i]=$("div#magic"+i).height();
}
$("div.magic").css("height","10px");
$("a.menu").click(
function(){
if(first!=0)
{
$("div.magic").animate({
opacity: 0,
height: "10px"
}, 500);
}
else
{
first=1;
}
$("div#magic"+ this.id).animate({
opacity: 1,
height: height_element[this.id]+'px'
}, 500);
}
);
})
Рабочий пример можно скачать здесь.