Что не так с этой функцией рекурсии?(проблема setTimeout) - PullRequest
1 голос
/ 19 октября 2010

Я пишу сценарий выделения, потому что мне не нравится тот факт, что в большинстве сценариев выделения, когда выделение достигает последнего элемента (думая, используя ul, поэтому последний элемент является последним li), он ждет, пока этот элемент не будет выключен.screen, а затем сбрасывает позицию ul и запускает прокрутку по всему agian.

Мой подход - создать клон ul, добавить его после текущей ul, запустить прокрутку и удалитьоригинальный ul, когда он полностью скрыт.

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

Это отлично работает для первого цикла, но затем глючит.

Это немного сложно объяснить, но кажетсячтобы во второй раз вызывать тайм-аут, вместо того, чтобы ждать времени, он просто вызывает себя мгновенно.Пожалуйста, см. http://webspirited.com/marquee.html для примера

Для рабочего примера.Javascript код выглядит следующим образом:

var count = 0;
$('document').ready(function () {
    //generate some random rows
    for (var i = 0; i <= 20; i++)
    $('.ulscroll').append('<li>Content ' + i + '</li>');
    //add one row so we can see its the last
    $('.ulscroll').append('<li>Last Item</li>');

    //set the ul's width
    var width = 0;
    $('.ulscroll').children('li').each(function () {
        width += $(this).outerWidth();
    });
    log('ul width: ' + width);
    $('.ulscroll').width(width);

    //activate the marquee              
    marquee('.ulscroll', 1, false);
});

function marquee(id, speed, sub) {
    //next two lines debugging purposes only
    count += 1;
    log('Marquee ran ' + count + ' times');

    //store copy of speed sent it(to pass for recursion)
    var s1 = speed;
    //set speed to 10*
    speed = speed * 10;

    //store parent width, and own width (if sub then add on width of parent div)
    var pwidth = $(id).parent('div').outerWidth();
    var width = (sub ? $(id).width() + pwidth : $(id).width());

    //set timeout
    var t = (width - pwidth) * speed;
    setTimeout(function () {
        var clone = $(id).clone().css('left', pwidth);
        $(id).addClass('oldul');
        $(id).after(clone);
        marquee(id + ':not(.oldul)', s1, true);
    }, t);

    $(id).animate({
        left: '-=' + width
    }, width * speed, 'linear', function () {
        $(this).remove();
    });
}

function log(text) {
    $('#log').append('<div>' + text + '</div>');
}

Решение Проблема была вызвана передачей селектора с: not (.ulold);Вот исправленный setTimeout

setTimeout(function(){
  var clone = $(id).clone().css('left', pwidth);
  $(id).addClass('oldul');
  var idx = id.split(':');
  idx = idx[0];
  log('idx: '+idx);
  $(idx).after(clone);
  marquee(idx+':not(.oldul)', s1, true);
},t);

Ответы [ 2 ]

0 голосов
/ 19 октября 2010

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

Проблема с кодом наПример страницы (но не в опубликованном коде): tout является локальным для каждого вызова marquee.Вызов clearTimeout(tout) ничего не делает.

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

0 голосов
/ 19 октября 2010

Проблема, скорее всего, заключается в этом коде ..

    var clone = $(id).clone().css('left', pwidth);
    $(id).addClass('oldul');

Тот факт, что вы повторно используете селектор, портит все, потому что оригинальный селектор во многом совпадает с течением времени..

При первоначальном вызове используйте marquee('.ulscroll:not(.oldul)', 1, false);

...