Решение setTimeOut () в Твиттере - PullRequest
0 голосов
/ 12 апреля 2011

Я читал пост блога Джона Ресига: http://ejohn.org/blog/learning-from-twitter/ и я не понял проблемы с setTimeOut () там.

Вопрос 1:

Джох поделился этим кодом:

var outerPane = $details.find(".details-pane-outer"),
    didScroll = false;

$(window).scroll(function() {
    didScroll = true;
});

setInterval(function() {
    if ( didScroll ) {
        didScroll = false;
        // Check your page position and then
        // Load in more results
    }
}, 250);

Где здесь используется кэширование?Я предполагаю, что когда didScroll имеет значение true, тогда вместо повторного поиска в DOM будет использоваться переменная externalPane, я прав?


Вопрос 2:

Всекция комментариев Майкл поделился кодом:

var timer = 0;

$(window).scroll(function () {
if (timer) {
clearTimeout(timer);
}

// Use a buffer so we don't call myCallback too often.
timer = setTimeout(myCallback, 100);
});

и сказал: " Вместо установки интервала обратный вызов запускается только тогда, когда это необходимо. Сохраняет несколько дополнительных вызовов вобратный вызов и любые накладные расходы из дополнительной логики внутри обработчика прокрутки должны быть довольно минимальными."

Мой вопрос: setTimeOut () вернет timerID, который будет использоваться clearTimeOut для очистки.Теперь с этой функцией setTimeout (myCallback, 100) после каждых 100 миль секунд будет использоваться функция myCallBack, не так ли?Более того, когда событие прокрутки сработает, таймер будет очищен и никогда не будет установлен снова, так какова цель его использования?


Извините за мои заблуждения.Хорошего дня.

Ответы [ 3 ]

3 голосов
/ 12 апреля 2011

Вопрос 1:

outerPane выбирается только один раз, независимо от любого другого значения.В закомментированных строках будет указана эта переменная.Суть его в том, что $(selector) несколько раз всегда будет медленнее, если просто повторно использовать результат и вызывать его только один раз.Приведенный выше код всегда будет иметь переменную outerPane везде, где это необходимо, и это будет очень быстро.

Вопрос 2:

Ну, этот код добрыйнеправильно.Позвольте мне исправить это:

var timer = null;

$(window).scroll(function () {
  if (timer) {
    clearTimeout(timer);
  }

  timer = setTimeout(function() {
    timer = null; // Added this line.
    mycallback();
  }, 100);
});

Смысл этого в том, чтобы выполнять ваш большой кусок JavaScript (в mycallback()) только тогда, когда пользователь фактически прекратил прокрутку.mycallback() будет вызываться только в том случае, если в течение 100 мс не произошло ни одного события прокрутки.

Поэтому, когда происходит прокрутка, сначала она проверяет, существует ли необработанное время ожидания, и есть ли его отмена.Это произойдет, если несколько событий прокрутки происходят на расстоянии менее 100 мс.Затем он устанавливает новый таймер для запуска через 100 мсек, который очистит timer и сработает mycallback().

Это предотвращает запуск mycallback() до тех пор, пока в течение 100 мс не произойдет никаких событий прокрутки.Преимущество состоит в том, что если mycallback() занимает много времени, оно никогда не прервет плавную прокрутку браузера.

Однако в случае с Twitter (как объясняет Ресиг) этот подход не будет работать.В случае с Twitter им нужно перемещать объекты по экрану при каждом событии прокрутки, потому что они перемещают объекты на экране во время прокрутки.Таким образом, они нуждаются в таком расчете каждый раз, когда запускается событие прокрутки, чтобы окно выглядело правильно при прокрутке вниз.Но также, когда вы делаете это таким образом, вы должны убедиться, что ваш JS работает очень быстро, потому что он будет выполняться много раз, пока пользователь выполняет прокрутку (отсюда и объяснение кэширования элементов jQuery).

0 голосов
/ 12 апреля 2011

@ Вопрос 1:

Я прочитал вашу связанную ссылку и думаю, что ответ на ваш вопрос if ( didScroll ) {. Этот запрос предотвращает выполнение вашего кода все время, даже если в этом нет необходимости. Но я не уверен на 100%.

0 голосов
/ 12 апреля 2011

@ Вопрос 2:

Код if (timer) { clearTimeout(timer); } легко понять, потому что используемый синтаксис, по моему скромному мнению, неверенЯ думаю, что код должен быть следующим:

if (timer != null) { clearTimeout(timer); }

, потому что после clearTimeout, переменная 'timer' будет очищена.Вы можете попробовать это, если вы сделали alert(timer); после 'clearTimeout ()'.

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