Проблема с анимацией и большим количеством вызовов stop () в jQuery - PullRequest
2 голосов
/ 19 февраля 2011

вот что я пытаюсь сделать: У меня есть несколько div с ценами в них, и слайдер с фиксированным минимумом, где я могу установить максимальную цену. Благодаря этому я могу фильтровать div, поэтому будут отображаться только div с ценами в диапазоне ползунка.

Без анимации не было бы проблем, просто скрыть () и показать (), но я пытаюсь сделать это гладко.

vehicles[0] = { id: 1, price: 100 };
vehicles[1] = { id: 2, price: 250 };
vehicles[2] = { id: 3, price: 700 };
vehicles[3] = { id: 4, price: 300 };
... 
slide: function(event, ui) {
  for (i = 0; i < vehicles.length; i++) { 
    if (vehicles[i].price > ui.value && $('#vehicle'+vehicles[i].id).data('visible') == true) { 
      $('#vehicle'+vehicles[i].id).data('visible',false).stop(true).hide('blind',500); 
    } 
    if (vehicles[i].price <= ui.value && $('#vehicle'+vehicles[i].id).data('visible') == false) { 
      $('#vehicle'+vehicles[i].id).data('visible',true).stop(true).show('blind',500); 
    } 
  } 
}
...
<div id="vehicle1">100€</div>
<div id="vehicle1">250€</div>
<div id="vehicle1">700€</div>
<div id="vehicle1">300€</div>

Это мой код, и вот моя проблема: при перемещении ползунка в одну сторону или точку он работает нормально, но, к примеру, если установить значение 0 € и сразу же вернуться к 700 € (пока анимация hide () все еще работает), все элементы div скрыты (но их данные ('visible') установлены в true). Вы можете увидеть мой беговой код здесь: http://work4.bywulf.de/index.php?page=Vehicles Просто двигайте ползунок быстро влево и назад вправо.

Похоже, что метод stop () неправильно останавливает текущую анимацию "скрытия", а анимация "показа" не воспроизводится.

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

Надеюсь, вы знаете, что я имею в виду и что я пытаюсь сделать, спасибо за вашу помощь.

(jQuery 1.5, jQueryUI 1.8.9)

- Wulf

Ответы [ 3 ]

1 голос
/ 20 февраля 2011

Проблема решена, просто сделал собственную .animation (). Я думаю, проблема была в том, что show () и hide () видят элемент таким, какой он есть, и когда элемент отображается только на 50%, он борется. .animation () начнется с 50% и закончится с заданными размерами. Итак, что я сделал в деталях:

Сначала я инициализировал контейнер, поэтому высота сохраняется:

$(selector).data('visible',true)
  .data('initialHeight',$(selector).height())
  .data('initialOuterHeight',$(selector).outerHeight())
  .data('initialMarginBottom',$(selector).css('marginBottom'));

Затем, когда понадобилась анимация, выполняется эта часть:

function startAnimation(selector, show, duration) {
  $(selector).data('visible',show).stop(true);
  if (show) {
    $(selector).animate({ 
      height: $(selector).data('initialHeight'), 
      opacity: 1 , 
      marginTop: 0,
      marginBottom: $(selector).data('initialMarginBottom') 
    }, duration);
  } else {
    $(selector).animate({ 
      height: 0, 
      opacity: 0 , 
      marginTop: $(selector).data('initialHeight') - $(selector).data('initialOuterHeight'),
      marginBottom: 0 
    }, duration);
  }
}

Спасибо за ваш совет.

0 голосов
/ 19 февраля 2011

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

Код уже запущен, когда другое событие запускает его снова. Вы можете попробовать что-то вроде этого:

    function Sample(event, ui)
    {
        var running;  // prevent re-entrant code

        if (running == true)
            return;
        else
            running = true;

        // a bunch of code

        running = false;
    }

Вам все еще нужен способ убедиться, что представление синхронизировано с положением ползунка, когда пользователь наконец отпускает ползунок.

0 голосов
/ 19 февраля 2011

Я бы предложил:

if ((vehicles[i].price > priceRange || search == false || (category > 0 && vehicles[i].category != category) || ($('#availability').is(':checked') && vehicles[i].availability != 0)) && $('#vehicle'+vehicles[i].id).data('visible') == true) {
  $('#vehicle'+vehicles[i].id).data('visible',false).stop(true, true).fadeOut(function(){$(this).hide()});
}
if (vehicles[i].price <= priceRange && search == true && (category == 0 || vehicles[i].category == category) && (!$('#availability').is(':checked') || vehicles[i].availability == 0) && $('#vehicle'+vehicles[i].id).data('visible') == false) {
  $('#vehicle'+vehicles[i].id).data('visible',true).stop(true, true).show().fadeIn();
}

Или, может быть, slideUp / slideDown для другого эффекта:

if ((vehicles[i].price > priceRange || search == false || (category > 0 && vehicles[i].category != category) || ($('#availability').is(':checked') && vehicles[i].availability != 0)) && $('#vehicle'+vehicles[i].id).data('visible') == true) {
  $('#vehicle'+vehicles[i].id).data('visible',false).stop(true, true).slideUp();
}
if (vehicles[i].price <= priceRange && search == true && (category == 0 || vehicles[i].category == category) && (!$('#availability').is(':checked') || vehicles[i].availability == 0) && $('#vehicle'+vehicles[i].id).data('visible') == false) {
  $('#vehicle'+vehicles[i].id).data('visible',true).stop(true, true).slideDown();
}

show () и hide () кажутся действительно ошибочными

...