jQuery – poziomy scroll

Kilka dni temu zajmowałem się prostą stroną. Nic wielkiego, większość statyczna, tylko na stronie głównej miał się znaleźć przewijalny boks z listą osób. Ruch miał się odbywać w poziomie, tak żeby strona była jak najniższa. Większość była już gotowa, jednakże samo przewijanie nie działało jak trzeba. Gotowiec ściągnięty z sieci dawał niezbyt ciekawe rezultaty. Trzeba było napisać coś własnego działającego prawidłowo.

Na początek sama konstrukcja takiego przewijanego boksu. Można zrobić go przy pomocy diva z określoną szerokością. Wewnątrz elementy z float: left. Będzie działało, ale szerokość diva trzeba będzie wyliczyć na podstawie szerokości wewnętrznych elementów. Do tego przewijanie nie będzie funkcjonować w przypadku ludzi z wyłączonym javascriptem (być może da się to obejść, ale miałem za mało czasu, żeby się z tym bawić). Dlatego też wybrałem inną konstrukcję. Główny boks (#scroller) ma szerokość ustawioną na 100% oraz jest położony względnie (width: 100%; position: relative;). Elementy umieszczone wewnątrz mają położenie bezwzględne, ze zmienną wartością przesunięcia względem lewej krawędzi (position: absolute; left: **px;). Po wyjściu elementów poza ekran pokaże się domyślny suwak, dlatego też potrzebny będzie overflow:hidden. Poniżej wstawiamy #scrollbar (width: 100%; position: relative; height: px; background: ….;) z umieszczonym w środku elementem #scroll_button (position:absolute;width: px; height: px;background …;). Na koniec trzeba napisać kilka linijek w javascript, dzięki którym #scroll_button zacznie się poruszać w poziomie, a tym samym zmieniać elementy widoczne w przewijanym boksie.

Całość będzie wyglądać mniej więcej tak:

 <div id="scroller">
   <div style="left: 0px;" class="scroll_in">
   </div>
   /** kolejne elementy **/
 </div>
 <div id="scrollbar">
   <div id="scroll_button"></div>
 </div>
<style type="text/css">
div#scroller {
  height: 356px;
  left: 0;
  overflow: hidden;
  position: relative;
  width: 100%;
}

div.scroll_in {
  position: absolute ; 
  top: 0 ;
  width: 200px ;
  height: 356px ;
}

#scrollbar {
  background: url("images/scroll_bg.jpg") repeat scroll 0 0 #DDDDDD;
  float: left;
  height: 18px;
  margin-bottom: 15px;
  position: relative;
  width: 100%;
}

#scroll_button {
  background: url("images/scroller.png") no-repeat scroll right top transparent;
  cursor: move;
  height: 18px;
  position: absolute;
  width: 166px;
}
</style>
<script type="text/javascript">
$(document).ready( function() {
 var actScroll = $("#scrollbar").width() ;
  var maxScroll = $("#scroller").attr("scrollWidth") - $("#scroller").width() ;
  var pos_left = 0 ;
  var multipler = 1.2 ;

 $("#scroll_button").draggable({
   axis: 'x',
	containment: 'parent',
	drag: function(event, ui) {
	    pos_left = ui.position.left * multipler / actScroll * (maxScroll) ;
     $("#scroller").attr({scrollLeft: pos_left });
   },
	stop: function(event, ui) {
	   pos_left = ui.position.left * multipler / actScroll * (maxScroll)  ;
	    $("#scroller").attr({scrollLeft: pos_left });
   }
 });

} ) ;
</script>

Skrypt określa stosunek liczbowy w szerokości przewijanego boksa do szerokości suwaka. Do diva #scroll_button przypięte zostaje drag&drop działające tylko po x i ograniczone do obszaru zajmowanego przez obiekt rodzicielski (dzięki temu nie da się wyjechać poza ekran). Na koniec ruch i zatrzymanie powodują wyliczenie o ile należy przewinąć zawartość boksa. Multipler dodałem, żeby zniwelować małą niedogodność: w skrajnej lewej pozycji suwak ma left:0, w skrajnej prawej wartość tą ogranicza szerokość suwaka. Jak znajdę wolną chwilę, to postaram się znaleźć rozwiązanie działające z punktem leżącym pośrodku suwaka.

W przypadku ludzi z wyłączonym javascriptem suwak nie będzie działać jak trzeba, dlatego warto zadbać o pokazanie domyślnego suwaka:

<noscript>
<style type="text/css">
#scrollbar {
  display: none ;
}
 
#scroller { 
  overflow: auto ;
}
</style>
</noscript>

2 Comments on “jQuery – poziomy scroll

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

*