Từ JavaScript chạy trong cùng một thread như giao diện người dùng, một callback sự kiện cuộn có thể chặn các giao diện người dùng - và do đó gây lag. Bạn cần điều chỉnh trình xử lý sự kiện cuộn vì một số trình duyệt kích hoạt nhiều trình duyệt. Đặc biệt là nếu bạn đang sử dụng OS X với thiết bị cuộn tương tự. Vì bạn thực hiện nhiều phép tính chiều cao trong trình nghe của mình, it will trigger a reflow (rất tốn kém) cho mỗi sự kiện cuộn được kích hoạt.
Để điều tiết người nghe, bạn phải ngăn người nghe kích hoạt mỗi lần. Thông thường, bạn đợi cho đến khi trình duyệt không kích hoạt sự kiện cho x mili giây hoặc có thời gian tối thiểu giữa việc gọi lại cuộc gọi lại của bạn. Hãy thử điều chỉnh giá trị để xem hiệu ứng. Ngay cả 0 mili giây có thể giúp, vì nó sẽ trì hoãn việc thực hiện cuộc gọi lại cho đến khi trình duyệt có thời gian (thường là 5-40 ms).
Cũng là một cách hay để chuyển đổi một lớp để chuyển đổi giữa các trạng thái (vị trí tĩnh và cố định) thay vì mã hóa cứng trong JavaScript. Sau đó, bạn có một mối quan tâm rõ ràng hơn và avoid potential extra redraws by mistake (xem phần "Trình duyệt thông minh").(example on jsfiddle)
Chờ thời gian tạm ngừng x ms
// return a throttled function
function waitForPause(ms, callback) {
var timer;
return function() {
var self = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(self, args);
}, ms);
};
}
this.start = function() {
// wrap around your callback
$window.scroll(waitForPause(30, self.worker));
};
Chờ ít nhất x ms (jsfiddle)
function throttle(ms, callback) {
var timer, lastCall=0;
return function() {
var now = new Date().getTime(),
diff = now - lastCall;
console.log(diff, now, lastCall);
if (diff >= ms) {
console.log("Call callback!");
lastCall = now;
callback.apply(this, arguments);
}
};
}
this.start = function() {
// wrap around your callback
$window.scroll(throttle(30, self.worker));
};
jQuery Waypoints Vì bạn đã sử dụng jQuery, tôi sẽ xem xét jQuery Waypoints plugin có một giải pháp đơn giản và thanh lịch cho vấn đề của bạn. Chỉ cần xác định một cuộc gọi lại khi người dùng cuộn đến một điểm tham chiếu nhất định.
Ví dụ: (jsfiddle)
$(document).ready(function() {
// throttling is built in, just define ms
$.waypoints.settings.scrollThrottle = 30;
$('#content').waypoint(function(event, direction) {
$(this).toggleClass('sticky', direction === "down");
event.stopPropagation();
}, {
offset: 'bottom-in-view' // checkpoint at bottom of #content
});
});
tôi đoán nó là cái gì hơn để làm với cách Firefox có cuộn giảm bớt và làm thế nào Gecko/Rhino cháy/giải thích sự kiện cuộn khác so với các trình duyệt khác hơn bất cứ điều gì khác, vì vậy nó sẽ có thể là một cái gì đó khó khăn để sửa chữa vẫn bằng cách sử dụng phương pháp tiếp cận nghe 'scroll', và tôi không thấy bất kỳ cách tiếp cận khác có thể atm, nhưng tốt nhất của người đàn ông may mắn. –