poniedziałek, 9 maja 2011

Pozycja myszy w JavaScript i dynamiczne ustawianie pojemnika

Czasami zachodzi potrzeba aby pojemnik z wygenerowaną zawartością (na przykład Ajaxową) pojawił się w okolicach kursora myszy. Można to wykonać na różny sposób, ale że dużo piszę Ruby on Rails, które używa biblioteki Prototype, to opiszę na tej właśnie drodze.
Aby zapoznać się z działaniem mechanizmów można wypróbować ten kod:
<script type="text/javascript" >
  function getcords(e){
    mouseX = Event.pointerX(e);
    mouseY = Event.pointerY(e);
    //dla celów testowych
    $('debug').innerHTML = 'mouseX:' + mouseX + '-- mouseY:' + mouseY;
  }
  Event.observe(document, 'mousemove', getcords);
</script>
<div id="debug">
  tu za chwilę pojawią się koordynaty kursora myszy
</div> 

Kluczowym jest tu obserwator (albo donosiciel) zdarzeń Event.observe, który w tym przypadku obserwuje cały dokument i śledząc położenie myszy "donosi" do kontenera <div id="debug">.
Jak wcześniej wspomniałem, opisuję to jedynie aby pokazać mechanizm. Nam chodzi o coś innego.
Potrzeba była taka: po prawej stronie ekranu jest lista pytań skróconych $('question_list'). Zajmuje ona całą wysokość ekranu. Klikniesz sobie na pytanie skrócone, a Rails przeszuka bazę i dostarczy pełną treść pytania. Treść tę umieści w kontenerze $('question_long'). Kontener ten wisi sobie spokojnie w jednym miejscu strony, a nam chodziło o to, aby pokazywał się na wysokości klikniętego pytanka na liście, i aby wszystko było pod ręką i przed oczami.
No to trzask:
<script type="text/javascript">
  function getcords(e) {
    mouseY = Event.pointerY(e);
    $('question_long').setStyle('top: ' + mouseY + 'px;');
  }
  Event.observe($('question_list'), 'click', getcords);
</script>
czary mary i działa!

Krótki opis:

Linijka 4:
Element.setStyle nadaje styl CSS wybranemu elementowi na stronie. W naszym przypadku kontenerowi z wygenerowaną pełną treścią pytania. Ustawiamy mu pozycję patrząc od góry strony. Uwaga nie zapomnij mu nadać odpowiedniego pozycjonowania:
#question_long {
  position: fixed;
  right: 200px;
  width: 300px;
  /* tra ta ta, kolory, zaokrąglenia rogów itp. */
}

Linijka 6:
Obserwujemy teraz nie cały dokument, a jedynie listę z pytaniami skróconymi. Nie interesują nas też oczywiście wszystkie ruchy myszy w zakresie tej listy, ale konkretne kliknięcia.

Oczywiście można to wszystko zrobić bez Prototype, ale skoro już jest... to dlaczego nie użyć?

1 komentarz:

  1. Przekombinowane, w jQuery to będzie tak:
    $('#question_list').mouseenter(function(ev)
    {
    $('#question_long').css('top', event.pageY + 'px');
    });
    I bez żadnego dziwnego monitorowania.

    OdpowiedzUsuń