Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Остановка выполнения функции (https://javascript.ru/forum/jquery/11887-ostanovka-vypolneniya-funkcii.html)

Woody 19.09.2010 14:19

Остановка выполнения функции
 
Добрый день!

На странице пользователя 2 ссылки перемещения по картотеке "Назад" и "Вперед". Нажатие на ссылку генерирует запрос к серверу и получает в формате json табличные данные. JQuery рисует таблицу. Меня интересует ситуация когда пользователь несколько раз быстро нажимает ссылки. Сейчас скрипт последовательно начнет прорисовку всех страниц (выглядит это довольно неприглядно), а нужно чтобы все предыдущие запросы были сброшены и выполнился только последний. Возможно ли такое? Вот функция для ссылки "Назад":

jQuery('#prev')
  .bind('click', (function(event){
    jQuery('#page_table').hide('normal');
    jQuery.post('/bib/list/prev', function(data) {
      var str = "<table class='list'>";
      jQuery.each(data,function(index,rec){ str += "<tr><td>"+rec.name+"</td></tr>" });
      str += "</table></div>";
      jQuery('#page_table').html(str);
      jQuery('#page_navi').show('normal');
      }
    );
  })
);

micscr 19.09.2010 14:38

Флаг поставь. Пришел ответ на второй запрос и он(2-й запр.) проверяет - действительно ли текущий - 2-й? Если третий например - то ничего не делать.

Woody 19.09.2010 16:57

Цитата:

Сообщение от micscr (Сообщение 71264)
Флаг поставь. Пришел ответ на второй запрос и он(2-й запр.) проверяет - действительно ли текущий - 2-й? Если третий например - то ничего не делать.

Сказанное решил сделать так:
- Событие щелчка по ссылке изменяет поле номера страницы и запускает функцию построения таблицы generate_page(number)
- В generate_page(number) проверяется заказанный номер страницы с текущим и запускается обработка.
Проверку добавил в двух местах, но это не помогает. По времени зависона видно что все обработки запускаются, единственный положительный эффект то что таблицы не мелькают. Не совсем то что хотелось ...

jQuery('#prev')
  .bind('click', (function(event){
    jQuery('#page_table').hide('normal');
    var number = parseInt(jQuery('#number_page').attr('value')) - 1;
    jQuery('#number_page').attr('value', number);
    generate_page(number);
  })
  );

jQuery('#next')
  .bind('click', (function(event){
    jQuery('#page_table').hide('normal');
    var number = parseInt(jQuery('#number_page').attr('value')) + 1;
    jQuery('#number_page').attr('value', number);
    generate_page(number);
  })
  );

function generate_page(n) {
  if (parseInt(jQuery('#number_page').attr('value')) == n) {
    jQuery.post('/bib/list/'+n, function(data) {
      if (parseInt(jQuery('#number_page').attr('value')) == n) {
        var str = "<table class='list'>";
        jQuery.each(data,function(index,rec){
          str += "<tr><td>"+rec.name+"</td></tr>"
        });
        str += "</table>";
      
        jQuery('#page_table').html(str);
        jQuery('#page_table').show('normal');
      }
    });
  }
}  // END function generate_page(n)

micscr 19.09.2010 17:12

Я имел ввиду следующее:
var flag = o; // глобальная переменная - вне функций

jQuery('#prev')
  .bind('click', (function(event){
   var flag2 = parseInt(Math.random()*10000) // уникальная характеристика щелчка
   flag = flag2; // устанавливаем
   
    jQuery.post('/bib/list/prev', function(data) {
    if (flag != flag2) return; 
    jQuery('#page_table').hide('normal'); // тут наверное этой строке находиться ???
      var str = "<table class='list'>";
      jQuery.each(data,function(index,rec){ str += "<tr><td>"+rec.name+"</td></tr>" });
      str += "</table></div>";
      jQuery('#page_table').html(str);
      jQuery('#page_navi').show('normal');
      }
    );
  })
);

Woody 19.09.2010 18:14

Тоже самое. Получается все запросы уходят на сервер, на это и тратится основное время. Тут надо как-то стек сообразить и через интервал его анализировать. Пойду кумекать ...

inGray 20.09.2010 18:03

а может задержку поставить?? Не сразу отсылать запрос на сервер а по истечении некоего интервала после последнего клика?

Woody 21.09.2010 11:40

Цитата:

Сообщение от inGray (Сообщение 71373)
а может задержку поставить?? Не сразу отсылать запрос на сервер а по истечении некоего интервала после последнего клика?

Вариант с задержкой работает, только он мне не нравится. Пришлось эту самую задержку подбирать, например если поставить 400мс, то страницы "листаются", на 600мс получается то что нужно. Что будет в реальных интернет условиях незнаю. Хочется большей четкости, но за неимением лучшего пока этот вариант буду использовать.

inGray 21.09.2010 11:50

Сбрасывайте таймер ожидания клика каждый раз когда пользователь нажимает на ссылку?
var timer;

timer = setTimeout(foo(),400);

А при клике делать
clearTimeout(timer);
timer = setTimeout(foo(),400);
?

Kolyaj 21.09.2010 12:03


Ну и советики у вас. А вроде не первый день замужем на форуме.

Хотя месяц всего, можно пока :)

timer = setTimeout(foo,400);

inGray 21.09.2010 14:33

Пардон )) Женюсь исправлюсь)) Не знал сбросится ли таймер и подстраховался)

Kolyaj 21.09.2010 14:43

Вы вроде не поняли вашей ошибки. Скобочки после foo не нужны.

inGray 21.09.2010 14:53

:thanks:

DemonWather 18.01.2011 13:00

Доброго дня Вам, коллеги.

Я в цейтноте и в той области, в которой совсем новичок. Прошу вашей помощи.

Есть слайдинг, организованный с промощью slideDown, slideUp. Проблема состоит так же как и у автора темы - при частом наведении курсора создается длиннющая очередь событий и все это дергается и "всплывает" крайне неприглядно, пока не очистится весь стек событий.

Использовалось следующее решение:
$this.hover(
function () {
	if((navigator.appVersion).indexOf('MSIE 7.0') > 0)
	$('.overlay',$(this)).show();
	else
	$('.overlay',$(this)).fadeTo(250, 0.3);
	if(!o.showcaption)
		$(this).find('.ic_caption').slideDown(500);
	else
	{
		$('.ic_text',$(this)).slideDown(500);
		$('.ic_caption',$(this)).fadeTo(250, 1);
		}
},
function () {
	if((navigator.appVersion).indexOf('MSIE 7.0') > 0)
	$('.overlay',$(this)).hide();
	else
	$('.overlay',$(this)).fadeTo(250, 0);
	if(!o.showcaption)
		$(this).find('.ic_caption').slideUp(200);
	else
	{
		$('.ic_text',$(this)).slideUp(200);
		$('.ic_caption',$(this)).fadeTo(250, 0.7);
		}
}
);


Подскажите куда и как вставить таймер и его сброс, чтобы при наведении на объект курсора отработка событий наступала только если курсор над объектом дольше 0,3 с. Если меньше - события не обрабатывались.

Простите, если не сумел корректно объяснить суть вопроса.


Часовой пояс GMT +3, время: 10:07.