2010-09-13 6 views

ответ

59

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

Update: не

Поскольку этот вопрос получил какое-то действие снова я полагал, что я мог бы также обновить его с расширением JQuery, который добавляет scrollEnd события

// extension: 
 
$.fn.scrollEnd = function(callback, timeout) {   
 
    $(this).scroll(function(){ 
 
    var $this = $(this); 
 
    if ($this.data('scrollTimeout')) { 
 
     clearTimeout($this.data('scrollTimeout')); 
 
    } 
 
    $this.data('scrollTimeout', setTimeout(callback,timeout)); 
 
    }); 
 
}; 
 

 
// how to call it (with a 1000ms timeout): 
 
$(window).scrollEnd(function(){ 
 
    alert('stopped scrolling'); 
 
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div style="height: 200vh"> 
 
    Long div 
 
</div>

+3

1000 мса долгое время лучше всего 250 – WantToDo

0

Существует нет такого события как 'scrollEnd'. Я рекомендую вам периодически проверять значение, возвращаемое scroll() (скажем, 200 мс) с использованием setInterval, и записывать дельта между текущим и предыдущим значениями. Если дельта становится равной нулю, вы можете использовать ее как свое событие.

+0

таким образом, вы будете выполнением setInterval бесконечно. – vsync

+1

Если вы не указали ссылку на свой обработчик и не вызвали 'clearInterval', когда дельта обратилась в нуль или вместо этого просто использовала' setTimeout'. – dpq

+0

downvote этот ответ по инциденту, и он [заблокирован] (https://meta.stackexchange.com/questions/75477/idea-behind-your-vote-is-now-locked-in-unless-this-answer-is -edited) теперь ... извините за это – blackmiaool

0

Я вытащил какой-то код из быстрой части, которую я объединил, что делает это в качестве примера (обратите внимание, что scroll.chain - это объект, содержащий два массива, начало и конец которых являются контейнерами для функций обратного вызова). Также обратите внимание, что я использую jQuery и подчеркивание здесь.

$('body').on('scroll', scrollCall); 
scrollBind('end', callbackFunction); 
scrollBind('start', callbackFunction); 

var scrollCall = function(e) { 
    if (scroll.last === false || (Date.now() - scroll.last) <= 500) { 
     scroll.last = Date.now(); 
     if (scroll.timeout !== false) { 
      window.clearTimeout(scroll.timeout); 
     } else { 
      _(scroll.chain.start).each(function(f){ 
       f.call(window, {type: 'start'}, e.event); 
      }); 
     } 
     scroll.timeout = window.setTimeout(self.scrollCall, 550, {callback: true, event: e}); 
     return; 
    } 
    if (e.callback !== undefined) { 
     _(scroll.chain.end).each(function(f){ 
      f.call(window, {type: 'end'}, e.event); 
     }); 
     scroll.last = false; 
     scroll.timeout = false; 
    } 
}; 

var scrollBind = function(type, func) { 
    type = type.toLowerCase(); 
    if (_(scroll.chain).has(type)) { 
     if (_(scroll.chain[type]).indexOf(func) === -1) { 
      scroll.chain[type].push(func); 
      return true; 
     } 
     return false; 
    } 
    return false; 
} 
55

Вот простой пример использования SetTimeout огонь функцию, когда пользователь прекращает прокрутку:

(function() {   
    var timer; 
    $(window).bind('scroll',function() { 
     clearTimeout(timer); 
     timer = setTimeout(refresh , 150); 
    }); 
    var refresh = function() { 
     // do stuff 
     console.log('Stopped Scrolling'); 
    }; 
})(); 

Таймер сбрасывается в то время как событие прокрутки стрельбы. После прокрутки останавливается функция обновления.

Или как плагин:

$.fn.afterwards = function (event, callback, timeout) { 
    var self = $(this), delay = timeout || 16; 

    self.each(function() { 
     var $t = $(this); 
     $t.on(event, function(){ 
      if ($t.data(event+'-timeout')) { 
       clearTimeout($t.data(event+'-timeout')); 
      } 
      $t.data(event + '-timeout', setTimeout(function() { callback.apply($t); },delay)); 
     }) 
    }); 
    return this; 
}; 

Чтобы запустить обратный вызов после 100мс последнего события прокрутки на DIV (с пространством имен):

$('div.mydiv').afterwards('scroll.mynamespace', function(e) { 
     // do stuff when stops scrolling 
     $(this).addClass('stopped'); 
    }, 100 
); 

Я использую это для прокрутки и изменения размера.

+2

Это называется подходом «debounce». Дополнительная информация (и функция многократного использования) здесь: http://davidwalsh.name/function-debounce – allicarn

8

Вот другой, более общее решение на основе одних и тех же идей, отметил:

var delayedExec = function(after, fn) { 
    var timer; 
    return function() { 
     timer && clearTimeout(timer); 
     timer = setTimeout(fn, after); 
    }; 
}; 

var scrollStopper = delayedExec(500, function() { 
    console.log('stopped it'); 
}); 

document.getElementById('box').addEventListener('scroll', scrollStopper); 
+0

без накладных расходов. благодаря! – Besnik

2

Почему так сложно? Как указывает документация, это работает http://jsfiddle.net/x3s7F/9/!

$('.frame').scroll(function() { 
$('.back').hide().fadeIn(100); 
} 

http://api.jquery.com/scroll/.


Примечание:scroll событие на Windows, Chrome является по-разному для всех остальных. Вам нужно быстро прокрутить, чтобы получить то же самое, что и результат. FF. Посмотрите на https://liebdich.biz/back.min.js «X».

Некоторые выводы из моего how many ms a scroll event теста:

  • Safari, Mac FF, Mac Chrome: ~ 16ms событие.
  • Windows FF: ~ 19 мс событие.
  • Windows Chrome: до ~ 130 мс событие при медленном прокрутке.
  • Internet Explorer: до ~ 110 мс событие.

http://jsfiddle.net/TRNCFRMCN/1Lygop32/4/.

+0

На самом деле, это работает очень хорошо. К сожалению, использование полосы прокрутки в демо не работает, хотя я считаю, что это происходит только из-за функции «fadeIn». Придется проводить больше испытаний, чтобы узнать, есть ли больше ошибок, но хорошо сделано, работает очень хорошо! Другие решения были сложными для такой небольшой задачи. – Fizzix

+0

Приятно, что это хорошо работает! –

+0

Спасибо. Неодобренному второстепенному: «Лучше сейчас?» %) P – loveNoHate

1

Существуют функции scrollstart и scrollstop, которые являются частью jQuery mobile.

Пример использование scrollstop:

$(document).on("scrollstop",function(){ 
    alert("Stopped scrolling!"); 
}); 

Надеется, что это поможет кому-то.

+0

Это, кажется, не срабатывает для меня :( –

+0

@RatherNotsay Это не работает для вас? У меня есть это в производстве, и, похоже, все работает отлично. Вы включили мобильную версию jquery? Это не то же самое, что jquery – Dima

+0

У меня определенно был JQuery Mobile, но, возможно, это была некорректная сборка, отсутствующая в этом компоненте? Я сейчас перешел, но если я перейду, я обновлю. –

1

Мне понадобилось реализовать onScrollEnd Обсуждаемое событие также обсуждается. Идея использования таймера работает для меня.

я реализую это с помощью модуля JavaScript Pattern:

var WindowCustomEventsModule = (function(){ 

    var _scrollEndTimeout = 30; 

    var _delayedExec = function(callback){ 
     var timer; 
     return function(){ 
      timer && clearTimeout(timer); 
      timer = setTimeout(callback, _scrollEndTimeout); 
     } 
    }; 

    var onScrollEnd = function(callback) { 
     window.addEventListener('scroll', _delayedExec(callback), false);   
    }; 

    return { 
     onScrollEnd: onScrollEnd 
    } 
})(); 

// usage example 
WindowCustomEventsModule.onScrollEnd(function(){ 
    // 
    // do stuff 
    // 
}); 

Надеется, что это поможет/вдохновить кого-то

Смежные вопросы