2012-02-19 31 views
5

Tôi có một phần tử có thể cuộn với nhiều trẻ em và một thẻ chọn với các tùy chọn tương ứng.Nghe JS .scroll() hiệu quả

Tôi muốn thay đổi giá trị chọn dựa trên các yếu tố .scrollTop()

Làm thế nào để làm điều đó một cách hiệu quả? Tôi nghĩ về việc lưu trữ các trẻ em .offset().top trong một mảng và lặp đi lặp lại nó. Tuy nhiên, trình duyệt không xử lý nó. Tôi có thể thử tạo cờ .setTimeout(), nhưng điều đó dường như không rõ ràng.

r = $('ul') 
    offsets = [] 
    r.find('li').each((index) -> 
     offsets[index] = $(this).offset().top 
    ) 
    r.bind('scroll', -> 
     // while loop checking .scrollTop() > offsets[n] is slow 
     // maybe spams to many .scroll events? 
    ) 

Trả lời

9

Làm thế nào về những gì @osoner đã nói + thay vì thực hiện tất cả phép tính trong trình xử lý cuộn ngay, bạn sẽ kích hoạt một sự kiện khác trong bộ xử lý sau một khoảng thời gian (ví dụ: 'fooscroll') và sau đó bạn có tất cả các phần tử con đăng ký sự kiện và tự cập nhật tùy thuộc vào điều kiện bạn đặt.

var scrollTimer; 
$(window).on('scroll', function(e) { 
    if (scrollTimer) { clearTimeout(scrollTimer); } 
    scrollTimer = setTimeout(function() { 
     $(window).trigger('fooscroll'); 
    }, 200); 
}); 

$('li').on('fooscroll', function() { 
    // Check scrollTop or whatever... 
}); 
+0

Tôi thích cái này tốt hơn (ghét 'setInterval'). Cảm ơn! – mreq

+0

Tôi có thấy rằng sự kiện "fooscroll" chỉ được kích hoạt nếu người dùng ngừng cuộn 200ms? – Simon

+0

@Simon: Có, bạn là chính xác. Để làm rõ, không có nó 'throttle' di chuyển. Nếu bạn muốn kích hoạt cuộn mỗi 200ms thay vì chỉ một khi người dùng đã thực hiện cuộn, bạn sẽ phải thực hiện theo cách khác. – hayavuk

6

Bạn nên đọc this suggestion from John Resig. Về cơ bản, bạn thiết lập một cờ mỗi khi người dùng cuộn và thực hiện hành động mà bạn muốn với một hàm khoảng thời gian để kiểm tra cờ này.