Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [HTML][jQuery] Wczytywanie wiadomości - przewijanie
Forum PHP.pl > Forum > Przedszkole
desavil
Witam, piszę sobie taki mini czat, wszystko działa poprawnie lecz denerwuje mnie jedna rzecz, której nie umiem naprawić.
Wczytuję wiadomości za pomocą:
  1. <script type="text/javascript">
  2. function messages_load(){
  3. $.get('messages.php?' + Math.random(), function(data){
  4. $('#messages').html(data);
  5. });
  6. }
  7. $(function(){
  8. setInterval('messages_load()', 3000);
  9. });
  10. messages_load();
  11. <div id="messages">Trwa ładowanie wiadomości...</div>


Przykład pliku messages.php:
  1. <div id="messages2">
  2. wiadomość 1<br />
  3. wiadomość 2<br />
  4. wiadomość 3<br />
  5. ...
  6. </div>
  7. <script type="text/javascript">document.getElementById('messages2').scrollTop=1e6</script>


Kod CSS:
  1. #messages2{
  2. width: 749px;
  3. max-height: 400px;
  4. overflow: auto;
  5. }

Oczywiście ostatnia linijka w pliku messages.php świadczy o tym, że wiadomości są przewinięte w dół, tutaj wszystko działa.
Problem pojawia się podczas przewijania w górę, jak chce się podejżeć wiadomośc np. poprzednika która już znikła z pola widzenia. Polega on na tym, że jak widać w skrypcie wiadomości są wczytywane co 3 sekundy, jeżeli ja sobie przewinę scroll na górę to po wczytaniu (odświeżeniu) wiadomości (co 3 sekundy) on jest przesuwany w dół, co jest bardzo denerwujące jeżeli czyta się starsze wiadomości np. innych osób. Tak samo jest z zaznaczaniem tekstu, jakiś zaznaczę, a po odświeżeniu zaznaczenie znika.

W jaki sposób mógłbym to naprawić?
Pozdrawiam.
maniana
Przed wstawieniem pobraniem danych zapamiętaj pozycje scrolla, jak jest max do dołu to po wstawieniu przesuwaj diva maksymalnie w dół. Jeśl;i pozycja nie jest przesunięta max w dół to nic nie rób, ew podświetl jakąś kontrolkę.
desavil
Dzięki smile.gif
A mógłbym poprosić o jakiś przykład?
sh3d2
tak na szybko:
  1. <div id="container" style="width: 300px; height: 300px; overflow-y: scroll; border: 1px solid red;"></div>
  2. <script>
  3. $(document).ready(function(){
  4. var c = 0, offset = 20;
  5.  
  6. setInterval(function(){
  7. var newline = $('<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum adipiscing magna non lectus malesuada non fermentum turpis adipiscing.' + (c++) + ' </p>')
  8.  
  9. $('#container').append(newline)
  10. if( $("#container").prop('scrollTop') + $("#container").height() + $(newline).height() + offset >= $("#container").prop("scrollHeight")){
  11. $("#container").prop({scrollTop: $("#container").prop("scrollHeight") });
  12. }
  13. },1000)
  14. })
  15. </script>
  16.  


nowe wiadomosci "symulowane" za pomoca setinterval()
desavil
Dzięki!
Działa idealnie tak jak chciałem smile.gif

Dało by się jeszcze to przeronbić, aby wczytywało wiadomości z pliku tak jak to podałem w pierwszym poście? ;>
sh3d2
Cytat(desavil @ 20.04.2012, 14:54:12 ) *
Dało by się jeszcze to przeronbić, aby wczytywało wiadomości z pliku tak jak to podałem w pierwszym poście? ;>


to juz jest bardzo latwe, probuj sam.
jesli nie bedziesz potrafil, to cos pomyslimy
desavil
Właśnie próbowałem to zrobić oczywiście najpierw, ale niestety nie wychodzi mi tak jak bym chciał, czyli zamiast odświeżać to za każdym razem plik jest dodawany do całości. Niestety w Javascript/jQuery jestem słaby.
sh3d2
zamien .append() na .html().

btw ladowanie calego contentu za kazdym razem to chyba nie jest najlepszy pomysl, wg mnie to powinno dzialac tak, ze klient (js) ajaxowo odpytuje serwer o nowe wiadomosci, i jesli takowe sa,
dolacza je (stad append()) na koniec diva z contentem.

mozesz tez wyrzucic scrolltop() ze swojego messages.php

edit: pisalem kiedys cos podobnego, i tam to dzialalo tak, ze js odpytujac wysylal timestamp poprzedniego zapytania, i jesli serwer znalazl cos mlodszego niz odebrany timestamp, to wlasnie to zwracal
desavil
Nawet ciekawy pomysł z tym pytaniem smile.gif
Bo jak zrobiłem niedawno test i na taki czat weszło ponad 100 osób i wiadomości odświeżały się co 2s to serwer WWW nie wyrabiał i sypał: 500 Internal Server Error tongue.gif

Tylko to, to już wyższa szkoła jazdy... :]
sh3d2
jakims pomyslem na pseudo optymalizacje byloby tez zwiekszanie interwalu w momencie, kiedy serwer nie zwrocil zadnej nowej wiadomosci.

edit: niekoniecznie wyzsza, zakladajac, ze zapisujesz niedostarczone wiadomosci w db, wystarczy ze odpytasz o nieprzeczytane wiadomosci mlodsze niz timestamp
desavil
No i nie chce działać:
  1. $(document).ready(function(){
  2. var offset = 20;
  3.  
  4. setInterval(function(){
  5. $.get('sources/messages.php?' + Math.random(), function(data){
  6. newline=data;
  7. $('#container').append(newline)
  8. if( $("#container").prop('scrollTop') + $("#container").height() + $(newline).height() + offset >= $("#container").prop("scrollHeight")){
  9. $("#container").prop({scrollTop: $("#container").prop("scrollHeight") });
  10. }
  11. });
  12. },3000)
  13. })
sh3d2
  1. var newline = $(data)
desavil
Nie chce to działać, próbowałem z var itp.
sh3d2
jakies bledy?

edit: ew dodaj przed newline console.log(data), zobaczysz co ci serwer zwraca

no i czy masz element #container, on sie u ciebie chyba #messages nazywal...

edit:

wroc, twoim sposobem (zwracanie calego contentu za kazdym razem) to i tak bedzie kupa, bo przeciez zamieniasz cala zawartosc diva ktory scrollujesz.
jesli chcesz, zeby dzialalo, musisz zrobic metoda ktora pisalem wczesniej
desavil
Nie, tutaj jest wszystko dobrze.
Chodzi o to, że po prostu wczytywane wiadomości są dopisywane cały czas smile.gif
Czyli każde odświeżenie pliku to dodanie tekstu w polu diva z tego pliku:
  1. $(document).ready(function(){
  2. var offset = 20;
  3.  
  4. setInterval(function(){
  5. $.get('sources/messages.php?' + Math.random(), function(data){
  6. var newline = data;
  7. $('#container').append(newline)
  8. if( $("#container").prop('scrollTop') + $("#container").height() + $(newline).height() + offset >= $("#container").prop("scrollHeight")){
  9. $("#container").prop({scrollTop: $("#container").prop("scrollHeight") });
  10. }
  11. });
  12. },3000)
  13. })
Chyba, że jest to specjalnie tak zrobione, abym mógł zrobić to co pisałeś (jeśli mogę na Ty) o dopisywaniu tylko, a nie wczytywaniu wszystkiego.
Jeżeli tak, to chyba już wiem jak to zrobić, i nawet prosto. A jak będę miał jakoś problem (odpukać) to ew. napiszę.

@edit
Ta zmienna offset jest konieczna, czy można ją zrobić jakoś automatycznie?
sh3d2
sa dopisywane, bo uzywasz metody append(), ktora dodaje na koniec elementu.
uzywajac html() <tak jak miales wczesniej> content zostanie zastapiony, ale na dzialanie scrolla bym raczej wtedy nie liczyl.

sprobuj zaproponowana metoda, jak bedziesz mial problemy - pisz

edit: moglbys w ogole sprobowac napisac to jako jquery plugin, ladniej by wygladalo wink.gif
no i przede wszystkim przerob zwracane dane na jsony, wtedy bedziesz mogl sobie ladnie zwrocic status zapytania i inne ciekawe rzeczy

zmienna offset to ustawienie, jak daleko (mniej wiecej) od dolu diva scroll ma sie zachowywac jakby byl na samym dole.
kiedy offset byl 0 niebardzo chcialo dzialac (nie wiem czemu, stawiam na jakies marginy).
mozesz oczywiscie w warunku tam gdzie dodajesz offset dodac po prostu 20 i wyrzucic offset, ale chyba lepiej miec mozliwosc przekonfigurowania bez grzebania sie w kodzie, za duzo wtedy mozna napsuc wink.gif

tam gdzie zaczyna sie css i ogolnie "przegladarka' niewiele pomoge, to juz nie moja bajka jest, wiec w tych kwestiach moge sie mylic
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.