jQuery .hover() или .animate(), вызывающие пузырьковую анимацию в плагине Marquee

Я использую плагин Giva Labs jQuery Marquee. Пример jsFiddle здесь.

В примере есть две переключаемые строки текста: First line и Second row. Когда вы начинаете непрерывно перемещать курсор мыши по голубому прямоугольнику, текст сходит с ума: строки начинают перемещаться друг по другу как бы хаотично, не по порядку. Сумасшествие сильнее всего, когда вы меняете скорость движений мыши с медленной на быструю в цикле.

Я погуглил "jquery animate stop" и нашел .stop() и .clearQueue() эффектов. Я попытался прикрепить их к эффекту выделения следующим образом:

$("#marquee").marquee().stop();

и это:

$("#marquee").marquee().clearQueue();

а еще вот так:

$("#marquee").marquee()
    .hover(function() {
        $(this).clearQueue();
    });

Я также пробовал использовать встроенные в плагин методы:

$("#marquee").marquee()
    .hover(function() {
        $(this).marquee("pause");
    })
    .mouseout(function() {
        $(this).marquee("resume");
    });

Ни один из них не работал.

Как избавиться от этого глюка?


person Taz    schedule 05.07.2012    source источник
comment
В каком браузере проявляются проблемы? Я добавил последний фрагмент кода, который вы разместили, в свой jsfiddle и попробовал быстрое движение мыши, и текст остановился/приостановился, как и ожидалось. Я использую Хром.   -  person Lowkase    schedule 06.07.2012
comment
@Локейс Хром. Также проверено в IE8 и Firefox - реплицировано в обоих.   -  person Taz    schedule 06.07.2012


Ответы (2)


ОБНОВЛЕНИЕ/РЕШЕНО:

Код: jsFiddle


Обзор решения:

  • добавил var timedout
  • установить timedout внутри scroll()
  • позвони clearTimeout(timedout) внутрь pause()

Ошибка не возникает, когда вы ставите очень низкое значение pauseSpeed (например, 2), что наводит меня на мысль, что ошибка возникает из-за взаимодействия между pause() и resume().

Конкретно, этот фрагмент кода в pause():

if( $marquee.data("marquee.showing") != true ){
    // we must dequeue() the animation to ensure that it does indeed stop animation
    $lis.filter("." + options.cssShowing).dequeue().stop();
}

этот бит кода в resume():

if ($marquee.data("marquee.showing") != true) scroll($lis.filter("." + options.cssShowing), 1);

и этот фрагмент кода в scroll():

setTimeout(function() {
    // if paused, stop processing (we need to check to see if the pause state has changed)
    if (paused == true) return false;

    // scroll the message down
    $li.animate({
        top: (options.yScroll == "top" ? "+" : "-") + $marquee.innerHeight() + "px"
    }, options.showSpeed, options.fxEasingScroll);
    // finish showing this message
    finish($li);
}, delay);​

Насколько я вижу, проблема возникает из-за того, что dequeue().stop() [что имеет смысл] происходит немедленно, а scroll(...) имеет некоторый код, который происходит с задержкой (pauseSpeed).

Итак, происходит следующее:

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

Чтобы исправить это, я бы предложил отредактировать код jquery.marquee.js и фактически вызывать clearTimeout() каждый раз, когда вы останавливаете анимацию.

person ryuusenshi    schedule 15.07.2012
comment
на самом деле, мне кажется, я даже знаю, как это происходит, но мой мозг слишком напряжен, чтобы объяснять сейчас. Подсказка: эту ошибку можно будет воспроизвести каждый раз, когда pausespeed будет больше, чем showspeed. Предложенное мной решение должно работать. - person ryuusenshi; 15.07.2012
comment
ха-ха, это все равно происходит, но это должно быть из-за всех функций с истекшим временем ожидания, которые помещаются в очередь. Они проделали хорошую работу, чтобы остановить анимацию, но не события с истекшим временем ожидания. Если вы ищете clearTimeout в их коде, их нет. - person ryuusenshi; 15.07.2012
comment
вот обновленная скрипта: jsfiddle.net/YtdAS Теперь она работает. Я только что добавил тайм-аут, установил его в scroll(), а затем вызвал clearTimeout(timedout) в pause(). - person ryuusenshi; 15.07.2012
comment
Самое отличное исправление ошибок. :-D Спасибо за отслеживание. Ваше здоровье! - person arttronics; 15.07.2012

Я обновил ваш код в JSFiddle здесь. http://jsfiddle.net/AkQgH/7/

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

setTimeout(
  function() 
  {
  }, 5000);

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

Обновлен URL. Удалены ошибки JS, поскольку в вашем коде должно быть «выделено», а не «выделено». -- также другая ошибка вместо "over", вам нужно использовать "mouseover"

person user1269989    schedule 05.07.2012
comment
Спасибо, но ни один из них не работал. Скрипка очень похожа на одно из решений, которые я уже пробовал (вы привязались к mouseover, я сделал к hover). setTimeout похоже не исправляет. Я обнаружил, что глюк сильнее всего, когда я меняю скорость движений мыши с медленной на быструю. - person Taz; 06.07.2012