Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [JavaScript] Timer odliczający 2 daty, Problem z reakcją na przeglądarkach na Windowsie i Androidzie
shpaque
post 1.04.2020, 05:07:04
Post #1





Grupa: Zarejestrowani
Postów: 651
Pomógł: 3
Dołączył: 31.01.2011
Skąd: Warszawa

Ostrzeżenie: (10%)
X----


Witajcie w ten piękny zimowy dzień smile.gif
Od razu napiszę, że z JS mam najmniej do czynienia, dlatego wrzuciłem to do przedszkola, być może rozwiązanie jest tak proste.

OPIS PROBLEMU
O ile na przeglądarkach (Chrome, Safari, Friefox) na macOs i iPhone oraz iPad wszystko działa bez zarzutu, tak na większości kompów na Windowsie (niezależnie wtedy od przeglądarek) i niektórych Androidach (również niezależnie od przeglądarek), po odliczeniu czasu (następuje przeładowanie strony) zapętlają się, strona jakby próbuje się kilkanaście razy przeładować, jak w ońcu się przełąduje to nie jest to efekt klawisza F5 (bo nie leci php od nowa)... Jak można to rozwiązać? Teraz spiąłem to w jeden skrypt, wcześniej były dwa oddzielne każdy w warunku (if nextTest lub if currentTest) - do obejrzenia na test.coloplus.pl - pytanie czy ma znaczenie i różnicę, gdybym spiął to w funkcję i uruchomił ją w body.onload..?

  1. <script type="text/javascript">
  2. var nextCountDownTime = <?php echo isset($nextTest['timeStart']) ? 'new Date("'.date('c', strtotime($nextTest['timeStart'])).'")' : '\'\''; ?>;
  3. var currentCountDownTime = <?php echo isset($currentTest['timeEnd']) ? 'new Date("'.date('c', strtotime($currentTest['timeEnd'])).'")' : '\'\''; ?>;
  4. var countDownTime = '';
  5.  
  6. if (currentCountDownTime !== '') {countDownTime = currentCountDownTime;}
  7. else {countDownTime = nextCountDownTime;}
  8.  
  9. var x = setInterval(function() {
  10. var now = new Date().getTime();
  11. var distance = countDownTime - now;
  12. var days = Math.floor(distance / (1000 * 60 * 60 * 24));
  13. var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  14. var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  15. var seconds = Math.floor((distance % (1000 * 60)) / 1000, 2);
  16. var documentTitleTimer = ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2);
  17.  
  18. var getTest = "<?php echo isset($getTest) ? $getTest : ''; ?>";
  19. var getUser = "<?php echo isset($getUser) ? $getUser : ''; ?>";
  20. var getInTime = "<?php echo isset($getInTime) ? $getInTime : ''; ?>";
  21.  
  22. document.getElementById('days').innerHTML = ('0' + days).slice(-2);
  23. document.getElementById('hours').innerHTML = ('0' + hours).slice(-2);
  24. document.getElementById('minutes').innerHTML = ('0' + minutes).slice(-2);
  25. document.getElementById('seconds').innerHTML = ('0' + seconds).slice(-2);
  26.  
  27. if (days > 1) {
  28. document.getElementById('days').style = 'display: table-cell;';
  29. document.getElementById('days-th').style = 'display: table-cell;';
  30. }
  31. if (days < 1) {
  32. document.getElementById('days').style = 'display: none;';
  33. document.getElementById('days-th').style = 'display: none;';
  34. }
  35. if (days < 1 && hours < 1) {
  36. document.getElementById('days').style = 'display: none;';
  37. document.getElementById('days-th').style = 'display: none;';
  38. document.getElementById('hours').style = 'display: none;';
  39. document.getElementById('hours-th').style = 'display: none;';
  40. }
  41.  
  42. // Opcje dla licznika najbliższego testu
  43. if (nextCountDownTime !== '') {
  44. if (distance > 60000 && distance < 300000) {document.getElementById('alert').style = 'color: var(--dark-grey); background-color: var(--yellow);';}
  45. if (distance < 60000) {
  46. document.getElementById('alert').style = 'color: var(--white); background-color: var(--green);';
  47. document.getElementById('table-title-th').innerHTML = 'Otwarte zapisy na test';
  48.  
  49. if (getTest !== '' && getUser !== '') {document.getElementById('bloc-button-join').style = 'display: none;';}
  50. else {document.getElementById('bloc-button-join').style = 'display: block; background-color: var(--green);';}
  51. }
  52. }
  53. // Opcje dla licznika trwającego testu
  54. else if (currentCountDownTime !== '') {
  55.  
  56. if (getTest !== '' && getUser !== '') {document.getElementById('bloc-button-join').style = 'display: none;';}
  57. else {
  58. document.getElementById('bloc-button-join').style = 'display: block; background-color: var(--green);';
  59. document.getElementById('button-join').innerHTML = 'Dołącz do trwającego testu';
  60. document.getElementById('button-join').href = './index.php?t=<?php echo isset($currentTest['id']) ? $currentTest['id'] : ''; ?>&u=<?php echo isset($newUserId) ? $newUserId : ''; ?>';
  61. }
  62.  
  63. if (distance > 300000) {document.getElementById('alert').style = 'color: var(--white); background-color: var(--green);';}
  64. else if (distance > 60000 && distance < 300000) {
  65. document.getElementById('alert').style = 'color: var(--dark-grey); background-color: var(--yellow);';
  66. if (getTest === '' && getUser === '') {document.getElementById('bloc-button-join').style = 'display: block; background-color: var(--yellow);';}
  67. }
  68. else if (distance < 60000) {
  69. document.getElementById('alert').style = 'color: var(--white); background-color: var(--rose);';
  70. document.getElementById('minutes').style = 'color: var(--rose);';
  71. document.getElementById('seconds').style = 'color: var(--rose);';
  72. document.getElementById('bloc-button-join').style = 'background-color: var(--rose);';
  73. document.getElementById('bloc-button-join').style = 'display: none;';
  74. }
  75. }
  76.  
  77. // Ostatnia sekunda
  78. if (distance < 0) {
  79. clearInterval(x);
  80. document.getElementById('days').innerHTML = '00';
  81. document.getElementById('hours').innerHTML = '00';
  82. document.getElementById('minutes').innerHTML = '00';
  83. document.getElementById('seconds').innerHTML = '00';
  84.  
  85. // Opcje dla licznika najbliższego testu
  86. if (nextCountDownTime !== '') {setTimeout(function() {location.reload(true)}, 90);}
  87. // Opcje dla licznika trwającego testu
  88. else if (currentCountDownTime !== '') {
  89. document.getElementById('table-head').innerHTML = 'Test zakończony';
  90. documentTitleTimer = 'Zakończony';
  91.  
  92. if (getTest !== '' && getUser !== '') {document.getElementById('rowButtonShowResults').style = 'display: block;';}
  93. setTimeout(function() {location.reload(true)}, 90);
  94. }
  95. document.title = documentTitleTimer + ' <?php echo isset($currentTest['title']) ? $currentTest['title'] : ''; ?> / Test OnLine';
  96. }
  97. }, 1);
  98. </script>


@EDIT - może dać zwykły link ...href - dać na końcu &action=purge?
nie mam pomysłów jak to można zrobić i co zrobić żeby to się nie zapętlało - w zasadzie problem może być później jeszcze inny (i pewnie tu jedyna opcja to json) - minute przed rozpoczeciem testu (co wynika ze skryptu) pojawia się button "dołącz" wywołujący modala. Jeśli ktoś nie wypełni modala i nie prześle w trakcie tej ostatniej muinuty, po zakończeniu odliczania skrypt nakaże przeładować stronę i wartości oraz cały modal zniknie - uzytkownik po rozpoczęciu testu będzie musiał znów do niego dołączyć i przesłać formularz z modala...

Nawet jak zmieniłem (znalazłem w necie) na :
  1. const x = setInterval(function() {
  2. ...
  3. // Ostatnia sekunda
  4. if (distance <= 0) {
  5. clearInterval(x);
  6. document.getElementById('days').innerHTML = '00';
  7. document.getElementById('hours').innerHTML = '00';
  8. document.getElementById('minutes').innerHTML = '00';
  9. document.getElementById('seconds').innerHTML = '00';
  10.  
  11. // Opcje dla licznika trwającego testu
  12. if (currentCountDownTime !== '') {
  13. document.getElementById('table-head').innerHTML = 'Test zakończony';
  14. documentTitleTimer = 'Zakończony';
  15. if (getTest !== '' && getUser !== '') {document.getElementById('rowButtonShowResults').style = 'display: block;';}
  16. }
  17. reload = setTimeout(location.reload(true), 1000);
  18. }
  19. }, 10);
  20. let reload;


to i tak nie zmienia to nic...

@EDIT
Może zadam jeszcze dwa pytania które to obejdą. Jak zrobić żeby licznik po odliczeniu do rozpoczecia zaczal sam liczyc do zakonczenia, ale po zakonczeniu znow wzial (jesli takowy jest) kolejna date do nasteopnego rozpoczecia innego wydarzenia i liczyl (czyli bez przerwy jesli tylko jest kolejne zdarzenie) - czyli teoretycznie wziac czasy rozpoczecia i zakonczenia jako tablice z php i nie zatrzymywac timera tylko zmieniac wartosc klucza..? W dobra strone mysle?
- i pytanie czy lepiej to zrobic w pure JS czy jQuery?

@EDIT [ostatni]
dziękuję za ogromne zainteresowanie tematem, jak rozumiem kod był w porządku i nikt z Was również nie wiedział w czym problem... Otóż jak podejrzewam w tym że pewnie JS nie dawał rady przy ładowaniu, jQuery jest jednak w tym lepszy, skorzystałem z gotowego api (jquery countdown) i za jego pomoca przerobiłem cały skrypt w taki sposób (opoznienie 5 sek wzielo sie stad ze kompy na WIndzie biora czas systemowy z jakichs dziwnych serwerow gdzie roznica miedzy zegarem serwera PHP a zegarem systemowym siegala nawet na testowanych kompach 7 sekund!!!!!) stad za kazdym razem potzebne przeladowanie, ktore po prostu dziala tym razem, i gotowiec wyglada tak:
  1. <script type="text/javascript">
  2. var nextTimeStart = <?php echo isset($nextTest['timeStart']) ? 'new Date("'.date('c', strtotime($nextTest['timeStart'])).'").getTime()' : '\'\''; ?>;
  3. var currentTimeEnd = <?php echo isset($currentTest['timeEnd']) ? 'new Date("'.date('c', strtotime($currentTest['timeEnd'])).'").getTime()' : '\'\''; ?>;
  4. var getTest = "<?php echo isset($getTest) ? $getTest : ''; ?>";
  5. var getUser = "<?php echo isset($getUser) ? $getUser : ''; ?>";
  6.  
  7. if (currentTimeEnd !== '') {countDownTime = currentTimeEnd;}
  8. else {countDownTime = nextTimeStart;}
  9.  
  10. $('#days, #hours, #minutes, #seconds').countdown(countDownTime)
  11. .on('update.countdown', function(event) {
  12. if (event.offset.totalHours < 24) {$('#days, #days-th').css('display', 'none');} else {$('#days').html(event.strftime('%D'));}
  13. if (event.offset.totalMinutes < 60) {$('#hours, #hours-th').css('display', 'none');} else {$('#hours').html(event.strftime('%H'));}
  14. $('#minutes').html(event.strftime('%M'));
  15. $('#seconds').html(event.strftime('%S'));
  16.  
  17. // Opcje dla licznika najbliższego testu
  18. if (currentTimeEnd === '') {
  19. if (event.offset.totalSeconds > 60 && event.offset.totalSeconds < 300) {$('#alert').css({'color': 'var(--dark-grey)', 'background-color': 'var(--yellow)'});}
  20. if (event.offset.totalSeconds < 60 && event.offset.totalSeconds > 0) {
  21. $('#alert').css({'color': 'var(--white)', 'background-color': 'var(--green)'});
  22. $('#table-title-th').html('Otwarte zapisy na test');
  23.  
  24. if (getTest !== '' && getUser !== '') {$('#bloc-button-join').css('display', 'none');}
  25. else {$('#bloc-button-join').css({'display': 'block', 'background-color': 'var(--green)'});}
  26. }
  27. }
  28. // Opcje dla licznika trwającego testu
  29. else {
  30. document.title = event.strftime('%H:%M:%S') + ' <?php echo isset($currentTest['title']) ? $currentTest['title'] : ''; ?> / Test OnLine';
  31.  
  32. if (getTest !== '' && getUser !== '') {$('#bloc-button-join').css('display', 'none');}
  33. else {
  34. $('#bloc-button-join').css({'display': 'block', 'background-color': 'var(--green);'});
  35. $('#button-join').html('Dołącz do trwającego testu');
  36. $('#button-join').attr('href', './index.php?t=<?php echo isset($currentTest['id']) ? $currentTest['id'] : ''; ?>&u=<?php echo isset($newUserId) ? $newUserId : ''; ?>');
  37. }
  38.  
  39. if (event.offset.totalSeconds > 300) {
  40. $('#alert').css({'color': 'var(--white)', 'background': 'var(--green)'});
  41. if (getTest === '' && getUser === '') {$('#bloc-button-join').css({'display': 'block', 'background': 'var(--green)'});}
  42. }
  43. if (event.offset.totalSeconds > 60 && event.offset.totalSeconds < 300) {
  44. $('#alert').css({'color': 'var(--dark-grey)', 'background-color': 'var(--yellow)'});
  45. if (getTest === '' && getUser === '') {$('#bloc-button-join').css({'display':'block', 'background-color': 'var(--yellow)'});}
  46. }
  47. if (event.offset.totalSeconds < 60) {
  48. $('#bloc-button-join').css({'display': 'none', 'background-color': 'var(--rose)'});
  49. $('#alert').css({'color': 'var(--white)', 'background-color': 'var(--rose)'});
  50. $('#minutes, #seconds').css('color', 'var(--rose)');
  51. }
  52. }
  53. })
  54. .on('finish.countdown', function(event) {
  55. $('#seconds').html(event.strftime('00'));
  56. $('#startTestInfo').html('<strong>Dołączam do testu...</strong>');
  57. $('#endTestInfo').html('<strong>Obliczam wyniki...</strong>');
  58. setTimeout(function() {window.location.reload(true);}, 5000);
  59. });


Ten post edytował shpaque 31.03.2020, 19:18:30
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 21:02