Задача использования на сайте различных анимированных объектов, как то меню или фотогалерея, уже давно не является редкостью. И здесь на помощь разработчикам приходит замечательный jquery-метод animate(). Этот метод позволяет анимировать различные свойства css, но имеет один довольно существенный недостаток – в качестве значения свойства может использоваться только число, либо значения hide, show и toggle. Например, height:20 – верно, а вот height:auto будет работать не всегда и не везде.
Попробуем решить эту проблему на конкретном примере
Допустим, необходимо разработать вертикальное двухуровневое меню. По умолчанию открыты только пункты первого уровеня, а при клике на соответствующую ссылку, сначала скрывается открытый подуровень, а затем открывается нужный скрытый. Но не просто открываются, а анимировано с увеличением высоты и прозрачности контейнера.
То есть, в итоге нужно получить вот такое меню:
Пишем HTML код нашего будущего меню:
Css:
И javascript:
При клике по пункту меню, мы скрываем все блоки класса «magic», и раскрываем тот из них, который содержит нужные нам подпункты.
Казалось бы, все должно работать, но это совсем не так. Вместо значения свойства height «auto» Firefox, Google Chrome и Opera устанавливают для контейнера высоту в 10px, которая была прописана нами в css, а IE7 и вовсе выдает ошибку: недопустимый аргумент.
Как же с этим бороться?
Способ 1.
Идея состоит в том, чтобы предварительно, до начала работы с меню, записать в массив значения высот всех необходимых контейнеров, а потом вместо «auto» подставлять значение элемента этого массива. То есть, новый javascript-код будет выглядеть следующим образом.
Таким образом, мы избавимся от использования устанавливаемого значения высоты, равного «auto», и заменим его конкретным числовым значением. Это поможет нам избавиться от ошибки в IE, но, как оказалось, не решит проблемы с истинным значением высоты контейнера, ведь все браузеры продолжат выставлять в качестве нового значения 10px. То есть, на экране мы увидим вот что:
Для того, чтобы справиться с этой проблемой, уберем из свойств класса «magic» значение высоты, а устанавливать его будем динамически после записи истинного значения высоты в массив.
Новый css-файл будет выглядеть так:
А javascript так:
Ну и для полного счастья, можно добавить некую переменную «first», которая будет равна 0 после загрузки страницы, и примет значение 1 после первого клика по пункту меню. Она нужна для того, чтобы избавиться от задержки в 500 миллисекунд на скрывание открытого подуровня меню, когда все подуровни скрыты.
Рабочий пример можно посмотреть здесь
Способ 2.
Вместо метода animate() применить методы hide() и show() с длительностью в те же самые 500 миллисекунд.
Однако, при использовании методов hide() и show() плавно изменяются все стили объекта, то есть, необходимый нам padding так же будет меняться от 0 до 10 и обратно. Эффект, конечно, красивый, но в данном случае не нужный. Поэтому padding нужно будет вынести в отдельный контейнер.
HTML-код для данного случая:
CSS:
И javascript:
Спасибо пользователю Voenniy за доработку второго способа.
А рабочий пример можно посмотреть здесь
И в качестве заключительного слова. Этот пост писался не ради того, чтобы создать меню на jQuery, ведь таких меню существует очень много. Главная цель здесь — показать, как двумя способами можно сымитировать значение свойства height:auto при использовании метода animate(). А ведь такая задача может встречаться не только при создании меню.
Попробуем решить эту проблему на конкретном примере
Допустим, необходимо разработать вертикальное двухуровневое меню. По умолчанию открыты только пункты первого уровеня, а при клике на соответствующую ссылку, сначала скрывается открытый подуровень, а затем открывается нужный скрытый. Но не просто открываются, а анимировано с увеличением высоты и прозрачности контейнера.
То есть, в итоге нужно получить вот такое меню:
Пишем HTML код нашего будущего меню:
<a id="1" class="menu">Меню 1</a><br/>
<div id="magic1" class="magic">Меню 2</div>
<a id="2" class="menu">Меню 1</a><br/>
<div id="magic2" class="magic">Меню 2<br/>Меню 2<br/>Меню 2</div>
<a id="3" class="menu">Меню 1</a><br/>
<div id="magic3" class="magic">Меню 2</div>
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 и вовсе выдает ошибку: недопустимый аргумент.
Как же с этим бороться?
Способ 1.
Идея состоит в том, чтобы предварительно, до начала работы с меню, записать в массив значения высот всех необходимых контейнеров, а потом вместо «auto» подставлять значение элемента этого массива. То есть, новый javascript-код будет выглядеть следующим образом.
$(document).ready(function(){
var height_element= new Array();
var array_length=$("div.magic").length;
for(i=1;i<=array_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();
var array_length=$("div.magic").length;
for(i=1;i<=array_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 миллисекунд на скрывание открытого подуровня меню, когда все подуровни скрыты.
Рабочий пример можно посмотреть здесь
Способ 2.
Вместо метода animate() применить методы hide() и show() с длительностью в те же самые 500 миллисекунд.
Однако, при использовании методов hide() и show() плавно изменяются все стили объекта, то есть, необходимый нам padding так же будет меняться от 0 до 10 и обратно. Эффект, конечно, красивый, но в данном случае не нужный. Поэтому padding нужно будет вынести в отдельный контейнер.
HTML-код для данного случая:
<a id="1" class="menu">Меню 1</a><br/>
<div id="magic1" class="magic"><div class="inner">Меню 2</div></div>
<a id="2" class="menu">Меню 1</a><br/>
<div id="magic2" class="magic"><div class="inner">Меню 2<br/>Меню 2<br/>Меню 2</div></div>
<a id="3" class="menu">Меню 1</a><br/>
<div id="magic3" class="magic"><div class="inner">Меню 2</div></div>
CSS:
div.magic{
overflow:hidden;
display:none;
}
a.menu{
cursor:pointer;
color:#0033CC;
text-decoration:underline;
margin-bottom:10px;
}
div.inner{
padding-left:10px;
}
И javascript:
$(document).ready(function(){
var first=0;
var last_id=0;
var id_now=0;
$("a.menu").click(
function(){
id_now=this.id;
if(first!=0)
{
$("div#magic"+ last_id).hide(500,function(){
$("div#magic"+ id_now).show(500);
});
}
else
{
first=1;
$("div#magic"+ this.id).show(500);
}
last_id=id_now;
}
);
})
* This source code was highlighted with Source Code Highlighter.
Спасибо пользователю Voenniy за доработку второго способа.
А рабочий пример можно посмотреть здесь
И в качестве заключительного слова. Этот пост писался не ради того, чтобы создать меню на jQuery, ведь таких меню существует очень много. Главная цель здесь — показать, как двумя способами можно сымитировать значение свойства height:auto при использовании метода animate(). А ведь такая задача может встречаться не только при создании меню.