2013-04-19 20 views
6

tle:Jquery resize() powoduje migotanie ekranu i div przesunięcie

Staram się stworzyć system, który pozwala na przewijanie rodzaj mapie za pomocą myszy przewijać w górę i myszy przewijać tak:

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

Każde z powyższych pól jest resetowane w javascript na wysokość i szerokość przeglądarki. Po przewinięciu myszy w górę lub w dół przeglądarka przewiń do równej pozycji na mapie, zaczynając od div 1, a następnie 2 i tak dalej. Ta pozycja jest ustawiana za pomocą mojej funkcji przewijania, która słucha zwojów myszy i dodaje odpowiednie dopełnienie do góry i margines w lewo, aby stworzyć iluzję powyższej mapy.

Oto codepen do niego:

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

A oto JavaScript, żeby go:

$(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'); 

}); 

Problem:

Zmiana rozmiaru okna tworzy dziwne przesunięcie div, które naprawia się, gdy funkcja przewijania jest wywoływana w przypadku elementów div od 2 do 5. Przy zmianie rozmiaru o pl w tych elementach div, wydają się równoważyć, a następnie są naprawiane tylko wtedy, gdy wywoływana jest funkcja przewijania.

.trigger ("zmiana rozmiaru"); należy zawsze dzwonić, tak? Nie wiem, dlaczego wywoływana jest tylko po wywołaniu funkcji przewijania.

Jak można temu zaradzić?

+0

debounce to prawdopodobnie to, co robisz po https://github.com/cowboy/jquery-throttle-debounce – epascarello

+0

Zdarzenie resize jest wywoływane poprawnie. Problem leży w twoim kodzie, a nie w wysyłce. –

Odpowiedz

3

Korzystanie czasomierza powinno być tylko tyle:

$(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

Jeśli masz moduł obsługi zdarzeń, który jest uruchomiony zbyt często, można udusić go tak:

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

Następnie zdać obsługi do throttle kiedy przypisać go. Zwróci funkcję, która będzie działać co najwyżej raz na tysiąc sekund, w oparciu o pierwszy podany argument.

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

Problem nie ma absolutnie żadnego związku z wydarzeniami, które są uruchamiane zbyt często. Czy przeczytałeś to pytanie? –

+0

@DiegoNunes: Pytanie zostało zaktualizowane długo po tym, jak odpowiedziałem. Pierwotne pytanie brzmiało: * "Jak mogę zoptymalizować $ (okno) .resize(), aby nie było ciągle przeliczane, gdy użytkownik przewija moją mapę elementów div?" * –

+0

O, widzę.Miło mieć to odnotowane tutaj w komentarzach, a potem :) –

2

. . Należy wziąć pod uwagę, że ilekroć użytkownik zmieni rozmiar okna w pionie, pozycja przewijania zostanie zmieniona i będzie miała wpływ na przewijanie w tle (ponieważ jest ono oparte na bieżącej pozycji przewijania).

. . Najprostszą poprawką będzie po prostu wywołanie $(window).trigger('scroll'); na końcu kodu obsługi zmiany rozmiaru, więc zachowujesz go SUCHA. Wprowadziłem tę zmianę na my CodePen fork. Sprawdź to.

Powiązane problemy