2012-06-10 7 views
26

Tôi đang cố gắng để chặn nội dung luôn được hiển thị cho người dùng, ngay cả khi anh cuộn xuống dưới trang. Anh ta cũng có thể di chuyển lên và xuống khối nội dung. Đây là một fiddle với một phiên bản rút gọn xuống để cho bạn thấy những gì tôi có nghĩa là:Sự kiện cuộn Choppy/Laggy trên Chrome và IE

http://jsfiddle.net/9ehfV/2/

Người ta phải chú ý khi di chuyển xuống, cho đến khi đạt dưới cùng của các khối màu đỏ, nó sẽ sửa chữa các khối trên cửa sổ, và khi cuộn trở lại, nó sẽ đặt nó trở lại.

Trong Firefox, người dùng có thể cuộn lên và xuống và sửa chữa/cố định mô tả ở trên là không thể nhận thấy - mịn như lụa.

Khi một người cố gắng cuộn trong Chrome hoặc IE, mặc dù, có vẻ như sự kiện cuộn bị trễ và người ta có thể thấy khối "trục trặc" trong một giây. Nó không phải là mã lag - nó có vẻ là một cái gì đó với các trình duyệt.

Có cách nào để sửa lỗi này không? Tôi đã tới giới hạn của mình rồi.

Tôi đánh giá cao đề xuất về làm thế nào tôi có thể đạt được tác dụng tương tự theo một cách khác ... nhờ

+0

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. –

Trả lời

42

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 
    }); 
}); 
+0

Tôi hiểu bạn đến từ đâu. Nhưng bạn có thể chỉ cho tôi một jsfiddle mà sẽ có chức năng tương tự như tôi, nhưng cung cấp những lợi thế mà bạn mô tả? –

+0

Tôi không hiểu chức năng cụ thể mà bạn đang đề cập đến. Bạn có muốn mã của bạn với lớp toggling và throttling? – gregers

+2

Ồ, tôi hiểu rồi. Các cuộn-logic là một chút phức tạp hơn tôi lần đầu tiên mặc dù. Hãy nghĩ rằng nó cần thiết để thực hiện một số tính toán ở giữa các vị trí cố định, nhưng các lớp sẽ đơn giản hóa cho các vị trí cố định. Cập nhật jsfiddle ở đây: http://jsfiddle.net/b5hU8/4/ – gregers

1

Bạn đã thử một số plugin jquery cho thanh cuộn hoặc sử dụng hình ảnh động để di chuyển xuống và lên? Nó sẽ buộc tất cả các trình duyệt hoạt động theo cùng một cách (hoặc đóng đủ) ..

Điều gì xảy ra là firefox (ít nhất là v12) có hoạt ảnh cuộn "gốc". Khi bạn điều hướng cho bất kỳ URL nào, bạn có thể nhận thấy độ mượt cho hành động cuộn và điều này không được triển khai trong các trình duyệt khác, như Chrome hoặc IE.

Ví dụ cho jquery scroller plugins:

+0

Không giúp được gì. Các plugin này sử dụng cùng một sự kiện cuộn, không thực sự cho phép cuộn trơn tru đến các trình duyệt không có nó. Cũng không sửa lỗi. –

+0

Các plugin này chỉ là một ví dụ. Có rất nhiều khác trong một searh google đơn giản cho jquery cuộn plugin. Những gì bạn cần là sử dụng các plguins mà không có sự kiện di chuyển defaul ... bạn sẽ cần phải "loại bỏ" scrollbar và làm cuộn của riêng bạn với scrollTo hoạt hình và nới lỏng plguin ... như thế này http://stackoverflow.com/questions/ 4710438/how-to-use-easing-in-the-jquery-plugin-jquery-scrollto bạn có cần một ví dụ về mã không? –

-6

tại sao bạn không sử dụng style = "position: fixed; top: 00px; ngay; 00px;"

sau đó nó luôn luôn có thể nhìn thấy mà không choppyness

+0

Vì phần tử cao hơn khung nhìn nên phần dưới của nó không hiển thị cho đến khi bạn cuộn. – gregers