javascript - плохой алгоритм запуска параллельных циклов - PullRequest
0 голосов
/ 08 сентября 2011

Я создал относительно небольшой динамический скрипт поворота баннера с иконками внизу для фокусировки на конкретном баннере.Выстрел мышкой по баннеру приостанавливает показ, но иногда, когда я убираю мышку со своего баннера, задержка для некоторых баннеров сокращается.Я бы даже понял, произошло ли это только один раз, но тогда задержка устанавливается на это более короткое время каждый раз, когда баннер возвращается в поворот, и часто сокращение происходит в одном другом месте в списке баннеров, какЧто ж.Иногда это можно исправить с помощью пока еще не определенного набора действий.Я начинаю подозревать, что моя логика где-то ловит цикл посередине, и поэтому процесс разветвляется, запускает два цикла, которые, кажется, ускоряют вызов функции showNextBanner.Не уверен, как решить это.Я проверил тесты, чтобы увидеть, находится ли он в настоящее время в режиме воспроизведения, но безрезультатно.

Я включаю то, что я считаю соответствующими частями кода ниже.

        var firstRun = true;
        var play = true;
        var current = 0;

        var banners = $$( '.banner' ); 
        banners.invoke( 'hide' );
        var images = $$( '.image' );
        var icons = $$( '.icon' );
        //dynamically clones an initial icon to match the number of banners
        initIcons();

        banners.invoke( 'observe', 'mouseenter', function( field ) {
            play = false;
        });

        banners.invoke( 'observe', 'mouseleave', function( field ) {
            if( !play ) {
                play = true;
                showNextBanner().delay(3);
            }
        });

        icons.invoke( 'observe', 'click', function( field ) {
                play = false;
                hideBanner( current );
                showBanner( findObj( icons, field.findElement()));
        });


        showNextBanner().delay(3); 


        function hideBanner( which ) {
            icons[ which ].src = blankIconSRC;
            banners[ which ].hide();
        }


        function showBanner( which ) {
            icons[ which ].src = selectedIconSRC;
            banners[ which ].show();
            current = which;
        }


        // loops the hiding and showing of icons 
        // (mouseenter sets play to false)
        function showNextBanner() {
            if( play ) {
                if( !firstRun ) {
                    if( ++current == banners.length ) current = 0;    
                    var previous = 0;
                    ( current == 0 )? previous = banners.length - 1: previous = current - 1;
                    hideBanner( previous );
                } else {
                    icons[0].src = selectedIconSRC;
                    firstRun = false;
                }
                showBanner( current );
                showNextBanner.delay(3);
            }
        }
    }());

После всего этого клиенту требуется решение jQuery, чтобы он мог иметь эффект слайда, недоступный через scriptaculous.Так что вся эта работа на ветер.Хорошая новость в том, что я могу просто использовать jCarousel и настроить таблицу стилей.Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 10 сентября 2011

Я предполагаю, что, поскольку вы не "отменяете" функцию delay() 'ed, они слишком долго остаются без дела, но ничего не делают при запуске, потому что play - ложь. Но как только игра снова станет true, все снова начнут давать эффект.

Вы можете сохранить возвращенное значение для delay() и отменить таймер, используя clearTimeout() со значением.

Тем не менее, я бы также предложил вам использовать один контейнер для всех баннеров (и, возможно, также поместить туда иконки) и установить для этого события mouseenter / mouseleave, а не для отдельных баннеры. Тогда есть только один элемент, который запускает / останавливает вращение баннера. Если вы также разделите все на отдельные функции, которые воспроизводят и останавливают вращение, и одну, чтобы показать определенный баннер, вы можете получить более чистую структуру кода.

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

0 голосов
/ 09 сентября 2011

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

Когда я читаю документы, кажется, что .delay предназначен для того, чтобы поместить пробелы в конвейер событий jquery,вместо того, чтобы фактически задерживать вызовы функций.Вы можете воспользоваться переключением на вызов setTimeout вместо задержки, чтобы получить указатель на тайм-аут, который затем можно отменить перед установкой нового тайм-аута (или отменить, если для воспроизведения задано значение false, а затем сбросить, когда воспроизведение снова станет истинным)Это упоминается в документах JQuery для .delay

...