2013-04-19 20 views
6

Bối cảnh:Jquery thay đổi kích thước() gây ra màn hình nhấp nháy và div bù đắp

tôi đang cố gắng để tạo ra một hệ thống cho phép di chuyển qua một loại bản đồ sử dụng chuột di chuyển lên và chuột di chuyển xuống như vậy:

------- 
|  | 
| 1 | 
|  | 
------- 
------- ------- ------- ------- 
|  | |  | |  | |  | 
| 2 | | 3 | | 4 | | 5 | 
|  | |  | |  | |  | 
------- ------- ------- ------- 
           ------- 
           |  | 
           | 6 | 
           |  | 
           ------- 

Mỗi hộp ở trên được đặt lại trong javascript là chiều cao và chiều rộng của trình duyệt. Khi bạn di chuyển chuột lên và xuống, trình duyệt sẽ cuộn đến vị trí bằng nhau trong bản đồ, bắt đầu bằng div 1 và sau đó là 2, v.v. Vị trí này được thiết lập thông qua funciton cuộn của tôi, mà lắng nghe cho cuộn chuột và thêm đệm thích hợp vào đầu và lề bên trái để tạo ảo ảnh của bản đồ ở trên.

Đây là codepen với nó:

http://codepen.io/lorenzoi/pen/mxejJ

Và đây là javascript với nó:

$(function(){ 

    $(window).on('resize', function(){ 
     var $divs = $('.vertical, .horizontal > div'), 
     ww = $(this).width(), 
     wh = $(this).height(); 

     $divs.css({ 
      height : wh, 
      width : ww 
     }); 

     $('.horizontal').each(function(){ 
      var $container = $(this), 
      nbChildren = $container.children().length; 
      posY = $container.offset().top, 


      $container.css({ 
       height: ww*(nbChildren-1) + wh, 
       width: ww*(nbChildren) 
      }); 
     }); 
    }).trigger('resize'); 

    $(window).on('scroll', function(){ 
     var wh = $(window).height(), 
     scroolTop = $(window).scrollTop(); 

     $('.horizontal').each(function(){ 
      var $container = $(this), 
      posY = $container.offset().top, 
      height = $container.height(), 
      nbChildren = $container.children().length, 
      marginMax = $container.width()/nbChildren*(nbChildren-1), 
      marginL = scroolTop - posY; 

      if(marginL<0) marginL = 0; 
      else if (marginL>marginMax) marginL = marginMax; 
      $container.css('marginLeft', -marginL); 
      $container.css('paddingTop', marginL); 
     }); 
    }).trigger('scroll'); 

}); 

Vấn đề:

Thay đổi kích thước cửa sổ tạo ra một kỳ lạ div offset tự sửa lỗi khi chức năng cuộn được gọi cho divs 2 đến 5. On resizing wh vi trong những div đó, chúng dường như tự bù đắp và sau đó chỉ được sửa khi chức năng cuộn được gọi.

.trigger ('thay đổi kích thước'); nên luôn luôn được gọi, phải không? Tôi không biết tại sao nó chỉ được gọi khi chức năng cuộn được thực hiện.

Làm cách nào để khắc phục sự cố này?

+0

debounce có lẽ là những gì bạn đang có sau khi https://github.com/cowboy/jquery-throttle-debounce – epascarello

+0

Sự kiện thay đổi kích thước đang được gọi chính xác. Vấn đề nằm trong mã của bạn, không phải trong công văn. –

Trả lời

3

Sử dụng một bộ đếm thời gian chỉ nên là đủ:

$(function(){ 
    var timeoutResize; 

    $(window).on('resize', function(){ 
     clearTimeout(timeoutResize); 
      timeoutResize = setTimeout(function(){ 
      var $divs = $('.vertical, .horizontal > div'), 
      ww = $(this).width(), 
      wh = $(this).height(); 

      $divs.css({ 
       height : wh, 
       width : ww 
      }); 

      $('.horizontal').each(function(){ 
       var $container = $(this), 
       nbChildren = $container.children().length; 
       posY = $container.offset().top, 


       $container.css({ 
        height: ww*(nbChildren-1) + wh, 
        width: ww*(nbChildren) 
       }); 
      }); 
     },100); 
    }).trigger('resize'); 

    ... 

}); 
0

Nếu bạn có một xử lý sự kiện đang chạy quá thường xuyên, bạn có thể tăng tốc nó như thế này:

function throttle(ms, fn) { 
    var allow = true; 
    function enable() { 
     allow = true; 
    } 
    return function(e) { 
     if (allow) { 
      allow = false; 
      setTimeout(enable, ms); 
      fn.call(this, e); 
     } 
    } 
} 

Sau đó vượt qua xử lý của bạn để throttle khi bạn gán nó. Nó sẽ trả về một hàm sẽ chạy tối đa sau mỗi n mili giây, dựa trên đối số đầu tiên bạn cung cấp.

$(window).resize(throttle(100, function(e) { 
    // do heavy work 
})); 
+0

Vấn đề hoàn toàn không liên quan đến các sự kiện chạy quá thường xuyên. Bạn đã đọc câu hỏi chưa? –

+0

@DiegoNunes: Câu hỏi đã được cập nhật lâu sau khi tôi trả lời. Câu hỏi ban đầu là: * "Làm cách nào tôi có thể tối ưu hóa $ (cửa sổ) .resize() để không phải tính toán lại liên tục khi người dùng cuộn qua bản đồ div của tôi?" * –

+0

Ồ, tôi hiểu rồi.Rất vui được ghi chú ở đây trong phần bình luận, sau đó :) –

2

. . Bạn cần phải xem xét rằng bất cứ khi nào người dùng thay đổi kích thước cửa sổ theo chiều dọc, vị trí cuộn sẽ bị ảnh hưởng và nó cũng sẽ ảnh hưởng đến cuộn nền của bạn (vì nó dựa trên vị trí cuộn hiện tại).

. . Việc sửa chữa đơn giản nhất sẽ chỉ đơn giản là gọi $(window).trigger('scroll'); ở cuối mã xử lý thay đổi kích thước, vì vậy bạn giữ nó DRY. Tôi đã thực hiện thay đổi này trên my CodePen fork. Kiểm tra nó ra.