#jquery #animation #delay #timing
#jquery #Анимация #задержка #синхронизация
Вопрос:
У меня есть простой фрагмент кода jQuery, который скрывает группу объектов галереи при нажатии на элементы управления, а затем показывает отфильтрованные объекты один за другим.
Проблема в том, что некоторые задержки непоследовательны и неравномерны по времени. Задержка увеличивается каждый раз, когда объект начинает исчезать, чтобы они появлялись один за другим, но один или два появляются одновременно в случайных случаях?
Вот код:
$(document).ready(function() {
var controls = $('#portfolio-nav');
var gallery = $('#gallery');
$('a', controls).click(function(){
/* setup variables */
var nav = $(this).closest('ul');
var listItem = $(this).parent();
var current = 'current';
var classes = listItem.attr("class").split(/s/);
var elementsToShow = new Array();
var allElements = gallery.children();
/* filter classes to excude .current */
classes = jQuery.grep(classes, function(value){
return value != current;
});
var sector = classes[classes.length -1];
/* remove all .current classes */
nav.children('.current').each(function() {
$(this).removeClass('current');
});
/* add the .current class to the clicked li */
$(this).parent().addClass('current');
/* define which elements to show */
$(allElements).each(function() {
var element = $(this);
var elementSectors = element.attr("class").split(/s/);
if(sector !== 'all'){
if(jQuery.inArray(sector, elementSectors) !== -1){
elementsToShow.push(element);
}
} else {
elementsToShow.push(element);
}
});
/* log the elements */
//console.log(elementsToShow);
/* hide/show all the elements */
animateThem(allElements, elementsToShow);
/* clear the array for the next click */
elementsToShow.length = 0;
return false;
});
function animateThem(allElements, elementsToShow){
$(allElements).fadeOut('fast').delay(200);
$(elementsToShow).each(function(index) {
$(this).delay(100*index).fadeIn('normal');
});
}
});
Вот краткий фрагмент html:
<nav id="portfolio-nav">
<ul>
<li class="all current"><a href="#all">All</a></li>
<li class="branding"><a href="#branding">Branding</a></li>
</ul>
</nav>
<div id="gallery">
<div class="grid-3 media-holder branding">
...
</div>
<div class="grid-3 media-holder marketing">
...
</div>
</div>
Вероятно, это легко исправить, поскольку мой jQuery не очень хорош, но если кто-нибудь знает причину, по которой это произойдет, я хотел бы знать.
Приветствия,
Дэйв
Редактировать: Возникли проблемы с объявлением элементов массива и получал необъявленную ошибку … после некоторой настройки его работы, как ожидалось (благодаря Дэнни Хансену), JSFiddle ниже, если кому-то интересно:
Комментарии:
1. В общем, я бы предпочел использовать метод обратного вызова вместо расчетной задержки.
Ответ №1:
Не совсем уверен, может быть какая-то проблема с синхронизацией.
Почему бы вам не попробовать использовать интервал:
var intCount = 0;
var interval = setInterval(function () {
if(typeof elementsToShow[intCount] != undefined) {
if(elementsToShow[intCount] != "fired") {
elementsToShow[intCount].fadeIn('normal');
elementsToShow[intCount] = "fired";
intCount ;
}
} else {
//End of array, clear the interval
clearInterval(interval);
}
}, 100);
Вот как это можно было бы сделать, используя интервал для определения времени событий. Попробуйте и сообщите, сработало ли это 🙂
Edit1 Отредактирован, чтобы исправить ошибку. — (Благодаря Brighty)
Edit2 Исправлена функция fadeIn. Попробуйте сейчас.
Комментарии:
1. привет, Дэнни, спасибо за быстрый ответ! Я получаю сообщение об ошибке «elementsToShow[intCount] не определено»? Есть идеи?
2. Убедитесь, что вы заменили текущий $.each на новый метод интервала. Насколько я вижу, ваш массив с элементами поставляется с параметрами функции. Это означает, что если вы используете это вне функции, это приведет к неопределенным ошибкам. Попробуйте записать в консоль elementsToShow и убедитесь, что он проиндексирован 0-999, также убедитесь, что строка «if (typeof elementsToShow[intCount] !== undefined) {» работает правильно, если нет, попробуйте использовать следующее: «if (elementsToShow[intCount] != undefined) {»
3. да, я заменил старую функцию .each () на указанную выше внутри функции. Я продолжу смотреть, не является ли это чем-то очевидным (обычно так и есть)
4. У вас должна быть неопределенная часть без кавычек. Иначе это не сработает. Причина этого в том, что мы считаем наш путь вверх по массиву, и когда он достигает неопределенного индекса (что означает, что массив завершен), он завершает интервал. Но попробуйте другой пример неопределенной проверки и посмотрите, работает ли он. Еще одна вещь, которую вы могли бы сделать, если это отнимает слишком много вашего времени, — это удалить метод задержки из вашего $.each и вместо ‘normal’ в качестве времени вы могли бы просто продлить время, необходимое для его затухания. Так что у него все еще есть этот вид события trail 🙂
5. Было внесено несколько исправлений. Попробуйте новый пример 🙂