Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.09.2011, 12:17
Аватар для Duda.Ml1986@gmail.com
Профессор
Отправить личное сообщение для Duda.Ml1986@gmail.com Посмотреть профиль Найти все сообщения от Duda.Ml1986@gmail.com
 
Регистрация: 01.09.2011
Сообщений: 263

Не предсказуемые тормоза в слайдере.
Всем привет.
Возник такой вопрос:
Есть слайдер контента, как фон у дивов используются фото 1900 * 600 , при загрузке страницы слайды начинают автоматом прокручиваться, если находится на этой странице и глупо следить за их сменой все ок! А вот если перейти на другие вкладки, просто погулять (серфинг) нета, то вернувшись на страницу со слайдами они начинаю прыгать. В чем причина такого поведения?

Чтобы устранить это, ограничил количество прокруток слайдов, до 10.

Сам слайдер не привожу(код), много букаф. Вот ссылка на готовый вариант http://duvanov.net/slider.html

P.S. Иногда этого и не происходит!
Ответить с цитированием
  #2 (permalink)  
Старый 29.09.2011, 13:14
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Я плохо знаком с проблемой таймеров, анимацией пока не приходилось заниматься. Но всё же выскажу предположение. Насколько я знаю обработчики событий находятся в специальной очереди, общей для всех событий. Так как javascript язык однопоточный то и события обрабатываются строго по очереди. Если предположить что на закрытой вкладке обработчики только накапливаются а на открытой и накапливаются и исполняются, то при переходе от закрытой вкладки к открытой ты получишь исполнение всех накопленных обработчиков практически сразу,точнее без временных промежутков. Это будет выглядеть как ускоренная анимация. Либо если твои обработчики сами запускают jquery анимацию, ты получешь несколько анимаций сразу.

Как решение в голову приходят два варианта,

1й - задавать вызов следующего обработчик события, непосредственно в самом обработчике. В этом случае гарантированно небудут накапливаться обработчики. Если я правильно понимаю, делать это надо через setTimeout, ибо вызывается он однократно.
setTimeout(function(){
    /* полезный код... */
    setTimeout(arguments.callee, 20);//задаём следующий вызов обработчика в самом обработчике
  }, 20);


2й) В обработчике проверять время между вызовами обработчика(последним и текущим) и если оно меньше положенного, не исполняем полезный код.
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 29.09.2011 в 13:58.
Ответить с цитированием
  #3 (permalink)  
Старый 29.09.2011, 13:16
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

Сообщение от Duda.Ml1986@gmail.com
Вот ссылка на готовый вариант http://duvanov.net/slider.html
Для помощи в твоей проблеме (бесплатно) нужен не ссылка на "готовый вариант"... А простенький тестовый пример и тут.
Ответить с цитированием
  #4 (permalink)  
Старый 29.09.2011, 13:34
Аватар для Duda.Ml1986@gmail.com
Профессор
Отправить личное сообщение для Duda.Ml1986@gmail.com Посмотреть профиль Найти все сообщения от Duda.Ml1986@gmail.com
 
Регистрация: 01.09.2011
Сообщений: 263

DjDiablo спасибо за исчерпывающий ответ. В действительности это так , накапливание черт его бери. Так что теперь все ок.
Ответить с цитированием
  #5 (permalink)  
Старый 07.05.2012, 16:53
Интересующийся
Отправить личное сообщение для aphextwin Посмотреть профиль Найти все сообщения от aphextwin
 
Регистрация: 10.04.2012
Сообщений: 11

Сообщение от DjDiablo
1й - задавать вызов следующего обработчик события, непосредственно в самом обработчике. В этом случае гарантированно небудут накапливаться обработчики. Если я правильно понимаю, делать это надо через setTimeout, ибо вызывается он однократно.

setTimeout(function(){
    /* полезный код... */
    setTimeout(arguments.callee, 20);//задаём следующий вызов обработчика в самом обработчике
  }, 20);
А вы не могли бы пояснить, в данной ситуации setTimeout переопределяется, или как? Не могу понять как прикрутить это к своему обработчику. Что такое arguments.callee тоже не совсем понятно. Я в js неопытен, не могли бы вы помочь найти решение проблемы?
Ответить с цитированием
  #6 (permalink)  
Старый 07.05.2012, 19:32
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

aphextwin я не очень понял что вам конкретно непонятно.

f=function(){
     //полезный код
     setTimeout(f, 20);
}
f();//первый вызов.

алгоритм примерно такой
1) вы вызываете функцию f
2) начинается исполнение функции
2) в функции f есть функция setTimeout которой передаётся два параметра, 1 - это функция, 2 - это время по истечению которого нужно вызвать функцию в первом параметре
3) завершается исполнение функции.
4) проходит 20 мс, и теперь уже не вы а таймер вызывает функцию переданную в первом параметры, а дальше смотрите шаг два (только не повисните )


setTimeout вызывает указанную функцию только один раз по истечению указанного временного промежутка.

так как вызванной функции находится setTimeout, функция будет постоянно заставлять таймер вызывать саму себя

Всё что вам нужно для запуска это просто вызвать функцию f первый раз.

так как следующий отсроченный таймером запуск следующий функции происходит только после обработки
предыдущей, то и не происходит накопления событий.

что касается arguments.callee, нужно же как то указать setTimeout какую функцию вызывать через 20мс.
думаю уместно говорить о трёх способах.
f=function c (){
   setTimeout(f,20);                          // первый способ
   setTimeout(c,20);                         // второй способ
   setTimeout(arguments.callee,20);    // третий способ
}
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 07.05.2012 в 20:04.
Ответить с цитированием
  #7 (permalink)  
Старый 08.05.2012, 14:40
Интересующийся
Отправить личное сообщение для aphextwin Посмотреть профиль Найти все сообщения от aphextwin
 
Регистрация: 10.04.2012
Сообщений: 11

Сегодня переписал все по вашему совету, но нужного эффекта не достиг )

Код такой:

$(window).load(function(){
    autoAdvance();
});

function autoAdvance()
{
    $('#left').trigger('click',[true]);
    // тут я пробовал вставлять исполняемый код, роли не играет. Все равно очередь накапливается...
    setTimeout(autoAdvance,3000);
}


События все равно накапливаются, слайдер, при переключении табов так же пляшет. Может вы поймете что я не так делаю?

Рабочая проблема тут : test.digis.kz

Последний раз редактировалось aphextwin, 08.05.2012 в 15:38.
Ответить с цитированием
  #8 (permalink)  
Старый 08.05.2012, 23:18
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Проверил, нечего там не накапливается. Слайдер честно ждёт пока я выберу вкладку и только потом меняет слайд. Да и сам подумай как могут накапливаться события, если для генерации следующего события нужно обработать предыдущее. Тобиш если нет обработки то и события не генерируются, а если есть обработка это уже значит что не накапливаются )) говоря уже третьими словами, несколько ожидающих событий от одного setTimeout получить невозможно.

А вот ручное переключение между слайдеми у вас сударь работает как то через попу. Только накопление событий тут не причём.
Решить это можно так.
в случае нажатия, унечтожается старый таймер.
и создаётся новый, вызывающий autoAdvance через 20 секунд к примеру.

то есть мы попросту даём пользователю время рассмотреть тот слайд, на который он сам переключился.
А у вас сейчас получается что пользователь меняет слайд, и следом срабатывает таймер который меняет слайд обратно ))

Ещё один интересный момент, это смена кадра в момент переключения на вкладку.
Это происходит потому что обработчик ждёт возможности быть выполненным, и выполняется при первой возможности.
Это конечно и не баг, и можно оставить так. Но можно изменить модель поведения. К примеру замерять временной интервал между двумя вызовами обработчика, и если интервал окажется больше критического значения, то не вызывать trigger.
Когда пользователь вернется на вкладку он будет видеть три секунды тот слайд, который был на экране в момент когда пользователь уходил. То есть переключение слайда произойдет через три секунды, а не сразу после возвращения.
Однако я сомневаюсь что пользователи вообще заметят этот выпендреж.
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 09.05.2012 в 00:11.
Ответить с цитированием
  #9 (permalink)  
Старый 10.05.2012, 13:01
Интересующийся
Отправить личное сообщение для aphextwin Посмотреть профиль Найти все сообщения от aphextwin
 
Регистрация: 10.04.2012
Сообщений: 11

Возможно вы меня не правильно поняли.
Когда я открываю сайт - слайдер работает, меняет картинки. Правда, при ручном переходе между слайдерами и вправду стоит убивать таймер, спасибо за идею! Но стоит уйти на другую вкладку на пару минут и вернуться - как я думаю, события накапливаются, и слайдер начинает бешено листаться. Надо заметить, что это наблюдается в фф 701, хром 18.
В опере вроде все работает как надо.

Расскажу о принципе работы, верстку не трогаю, только скрипт:

Вот так происходит смена слайдов, все в принципе просто, конечно используем jq:
$('#left').click(
        function()
        {
            curr = $('.slider_container').find('.slider_item:visible');
            curr.fadeOut();
            if(curr.next().length)curr.next().fadeIn();
            else $('.slider_container').find('.slider_item:first').fadeIn();
        }
    );


Далее, первый вызов ф-ции происходит по событию document.ready т.е. при загрузке страницы.

А сама ф-ия autoAdvance() либо делает вид, что кликает по стрелочке
$('#left').trigger('click',[true]);

либо исполняет тот же код:
curr = $('.slider_container').find('.slider_item:visible');
curr.fadeOut();
if(curr.next().length)curr.next().fadeIn();
else $('.slider_container').find('.slider_item:first').fadeIn();

потом происходит вызов самой себя, через задержку в 7 секунд:
timeOut = setTimeout(autoAdvance,7000);

В обоих случаях происходит описанный мною глюк ) Вызовы накапливаются, и все летает, когда включишь нужную вкладку.

Я тоже хотел сделать проверку временного интервала, но чего то не нашел аналога php time() в js. Может вы подскажете, как это сделать.

Последний раз редактировалось aphextwin, 10.05.2012 в 13:05.
Ответить с цитированием
  #10 (permalink)  
Старый 10.05.2012, 13:16
Аватар для vadim5june
Студент
Отправить личное сообщение для vadim5june Посмотреть профиль Найти все сообщения от vadim5june
 
Регистрация: 30.04.2012
Сообщений: 1,113

почитайте вот здесь
http://habrahabr.ru/post/114358/
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Некорректное поведение браузера в слайдере контента deepslam jQuery 1 07.07.2011 15:55
Загадочные тормоза в скрипте. iam_weasel Ваши сайты и скрипты 10 13.11.2010 11:34
тормоза jquery.ui.sortable в IE8 varanio jQuery 0 02.06.2010 10:12
Тормоза при получении offsetHeight/clientHeight kidar2 Events/DOM/Window 2 18.05.2010 09:05
Тормоза в ИЕ раскрывающегося списка Bekass Элементы интерфейса 1 04.12.2009 16:38