Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: XMLHttpRequest страдания и боль!
Форумы портала PHP.SU » » Хранение данных, их вывод и обработка » XMLHttpRequest страдания и боль!

Страниц (1): [1]
 

1. MikaBi - 11 Июля, 2014 - 17:44:25 - перейти к сообщению
Здравствуйте, Господа. И как всегда вы- последняя инстанция. Ситуация такова:
Делаю рейтинг пользователей на сайте, ну то есть величина индивидуальная для каждого пользователя, что-то типа кармы- не нравится тебе человек, нажимаешь минус- карма уменьшается, плюсик- наоборот.

Карма хранится в БД, при регистрации нового пользователя по дефолту устанавливается в ноль. Воздействие на карму реализую так: на странице выводятся переменные $karma и $login, которые передаются работающей сессией:
CODE (htmlphp):
скопировать код в буфер обмена
  1. session_start();
  2.  
  3. $login=$_SESSION['login'];
  4. $karma=$_SESSION['karma'];
  5.  
  6.  
  7. echo <<<HERE
  8. <h3 id='log'>$login</h3>
  9. Карма: <span id='karma'>$karma</span><br>
  10. HERE;
  11.  

ниже две картинки с плюсом и минусом, на картинки посажено событие onclick
CODE (htmlphp):
скопировать код в буфер обмена
  1. <img class='kplus' src='/images/plus.png' onmouseover="this.src ='/images/pluson.png'; " onmouseout="this.src ='/images/plus.png'"; onclick="vote('plus')">
  2. <img class='kminus' src='/images/minus.png' onmouseover="this.src ='/images/minuson.png'; " onmouseout="this.src ='/images/minus.png'" ; onclick="vote('minus')">
  3.  


По onclick запускается функция, в которую передается plus или minus в зависимости от нажтой кнопки, все эти данные,а так же логин пользователя, с помощью ajax отправляются php файлу, который увеличивает или уменьшает в БД значение кармы и ответом отдает текущее значение кармы. Полученое значение кармы с помощью innerHTML заменяет карму на странице :

CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. <script type="text/javascript">
  3.  
  4. // Создаем XMLHttpRequest
  5. var xmlhttp=false;
  6. /*@cc_on @*/
  7. /*@if (@_jscript_version >= 5)
  8. // JScript gives us Conditional compilation, we can cope with old IE versions.
  9. // and security blocked creation of the objects.
  10.  try {
  11.   xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  12.  } catch (e) {
  13.   try {
  14.    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  15.   } catch (E) {
  16.    xmlhttp = false;
  17.   }
  18.  }
  19. @end @*/
  20. if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  21.         try {
  22.                 xmlhttp = new XMLHttpRequest();
  23.         } catch (e) {
  24.                 xmlhttp=false;
  25.         }
  26. }
  27. if (!xmlhttp && window.createRequest) {
  28.         try {
  29.                 xmlhttp = window.createRequest();
  30.         } catch (e) {
  31.                 xmlhttp=false;
  32.         }
  33. }
  34.  
  35.  
  36.  
  37.  


И собственно сама функция, которая асинхронно передает php файлу обработчику логин и переменую $znak со значением (plus или minus) :
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. function vote(znak) {
  3.         var login= document.getElementById('log').innerHTML;
  4.        
  5.        
  6.         function stat ()
  7.         {if(xmlhttp.readyState == 4)
  8.                 {document.getElementById('karma').innerHTML=xmlhttp.responseText; }
  9.         }
  10.  
  11.     var url = "/insert.php?log="+login+'&znak='+znak;
  12.  
  13.         xmlhttp.onreadystatechange= stat();
  14.         xmlhttp.open("GET", url, true);
  15.          xmlhttp.send(null);
  16.  
  17.         }
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25. </script>
  26.  


Смотрим php файл обработчик insert.php:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. <?
  3.  
  4.  
  5. $login = $_REQUEST["log"];
  6. $znak = $_REQUEST["znak"];
  7.  
  8.  
  9. $connect=mysql_connect('localhost','***','***');
  10. $db=mysql_select_db('***',$connect);
  11. $login=mysql_real_escape_string($login);
  12.  
  13.        
  14.        
  15.          
  16. if ($znak=='plus') {
  17. $result=mysql_query("UPDATE `users`  SET `karm` = `karm`+1 WHERE login='$login'") or die('А потому, что: '.mysql_error());
  18.  
  19. }
  20.  
  21. if ($znak=='minus') {
  22. $result=mysql_query("UPDATE `users`  SET `karm` = `karm`-1 WHERE login='$login'") or die('А потому, что: '.mysql_error());
  23.  
  24. }
  25.  
  26.  
  27. $result=mysql_query("SELECT `karm` FROM `users` WHERE `login`='$login'") or die('А потому, что: '.mysql_error());
  28. while ($row=mysql_fetch_array($result)) {
  29.        
  30.         $otv=$row['karm'];
  31.         echo $otv;
  32. }
  33. ?>
  34.  


Теперь самое сложное: попробую объяснить, что происходит. Все это дело работает, но несколько странно. Во первых- при первом нажатии значение кармы не меняется, то есть страница загрузилась, делаешь клик на плюс или минус и ничего не происходит, а вот по второму клику значение кармы меняется как положено. Но, если допустим после минуса нажать плюс, то значение еще один раз уменьшится и только по следующему клику начнет как и положено увеличиваться. Вот приведу наглядный пример: "+" вот это значит, что я нажал плюс, "-" это нажал минус, справа значение кармы в цифрах.

//загрузилась страница, пусть карма изначально 0

"+" 0 ; "+" 1 ; "+" 2 ; "-" 3 ; "-" 2; "-" 1

то же самое и в обратную сторону. Короче, я в отчаянии Не понял если запускать напрямую php файл то видно, что все выводится как положено, и значения в базу пишутся верно, глюки начинаются только когда все это передается ajax-ом

Помогите, а то сойду с ума Ниндзя

з.ы. Боже, вот это Война и Мир получилась. Надеюсь хоть кто-то что-то понял...
2. mrKotik - 11 Июля, 2014 - 20:32:37 - перейти к сообщению
И так смотри, в консоле что выдает когда жмешь на +/- какую ошибку он выдаст) И смотри чальзом что отправляет ajax на php скрипт
3. MikaBi - 11 Июля, 2014 - 21:18:02 - перейти к сообщению
mrKotik пишет:

Спасибо ты появился) В консоле, это я так понимаю в отладчике хрома например? Смотрю, но там пусто вообще, на любые действия никаких сообщений в том числе и ошибок. А Чальз это, простите, что?

(Добавление)
Вот еще что, в отладчике хрома включил Call stack асинхронные запросы, так вот он показывает, что при первом нажатии на плюс или минус запрос отправляется. Но почему изменения начинаются только если второй раз нажать? Мистика...
(Добавление)
Побеседую пока еще сам с собой) Попробовал через IE запустить, там не работает вообще, браузер выдает ошибку "
Сообщение: Несоответствие типа
Строка: 42
Символ: 2
Код: 0
URI-код: http://mysite.com/ajax/ajax_framework.js"

строка 42 в моем коде это: xmlhttp.onreadystatechange= stat();

эт я так уж, от безысходности. Может кого-то подтолкнет на мысль какую-нибудь...
4. LIME - 11 Июля, 2014 - 23:03:26 - перейти к сообщению
нормальные люди юзают jquery
$.ajax(...);
5. MikaBi - 12 Июля, 2014 - 02:49:23 - перейти к сообщению
фуф... сделал. Спасибо, LIME. Но не оставляет ощущение костыля и быдло-кода. Посмотрите, как я впихнул PHP переменную в JQuery... за это в аду спец.котлы выдавать будут, я уверен.

В общем, скажите, как бы это можно было сделать поэлегантнее?

CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. <h3 id='log'>$login</h3>
  3. Карма: <span id='karma'>$karma</span><br>
  4.  
  5.  
  6. <img class='kplus' src='/images/plus.png' onmouseover="this.src ='/images/pluson.png'; " onmouseout="this.src ='/images/plus.png'">
  7. <img class='kminus' src='/images/minus.png' onmouseover="this.src ='/images/minuson.png'; " onmouseout="this.src ='/images/minus.png'">
  8.  
  9. <script>
  10.  
  11.  
  12.   $(".kplus").click(function(){
  13.    
  14.    var mu="<?echo $login?>";
  15. $.ajax({
  16.  type: 'GET',
  17.  url: 'insert.php',
  18.  data: "log="+mu+"&znak=plus",
  19.  success: function(data){
  20.    $('#karma').html(data);
  21.  }
  22. });
  23.  
  24.  
  25.   });
  26.  
  27.     $(".kminus").click(function(){
  28.    
  29.    var mu="<?echo $login?>";
  30. $.ajax({
  31.  type: 'GET',
  32.  url: 'insert.php',
  33.  data: "log="+mu+"&znak=minus",
  34.  success: function(data){
  35.    $('#karma').html(data);
  36.  }
  37. });
  38.  
  39.  
  40.   });
  41.  
  42.  
  43.         </script>
  44.  
  45.  
6. Viper - 12 Июля, 2014 - 08:59:02 - перейти к сообщению
MikaBi котлы за это не будут выдавать. В шаблоне вы иначе и не сделаете.

Иначе можно упростить код.

CODE (javascript):
скопировать код в буфер обмена
  1. $('.kplus').click(function(){
  2.         $.get('insert.php?log=<?php echo login; ?>&znak=plus', function(response){
  3.                 $('#karma').html(data);
  4.         });
  5. });


И чисто мое имхо. Я бы убрал onmouseover/onmouseout и заменил либо на css :hover либо обработал на jQuery[dot]hover()
7. DelphinPRO - 12 Июля, 2014 - 10:22:17 - перейти к сообщению
MikaBi пишет:
Посмотрите, как я впихнул PHP переменную в JQuery... за это в аду спец.котлы выдавать будут, я уверен.


обязательно Улыбка
вообще, яваскрипт следует вынести во внешний файл. А логин вполне можно передать через html-атрибуты

CODE (htmlphp):
скопировать код в буфер обмена
  1. <h3 id='log' data-login="<?=$login?>"><?=$login?></h3>


Внешний яваскрипт файл:
CODE (javascript):
скопировать код в буфер обмена
  1. function karmaChange(login, val){
  2.  
  3.         $.ajax({
  4.                 type: 'GET',
  5.                 url: 'insert.php',
  6.                 data: {
  7.                         log: login,
  8.                         znak: val
  9.                 }
  10.         }).done(function (response) {
  11.                 $('#karma').html(data);
  12.         }).fail(function (xhr, status, error) {
  13.                 alert('ERROR: ' + error);
  14.         });
  15.        
  16. }
  17.  
  18.  
  19. $(".kplus").click(function(){
  20.         var login = $('[data-login]').data('login');
  21.         karmaChange(login, 'plus');
  22. });
  23.  
  24. $(".kminus").click(function(){
  25.         var login = $('[data-login]').data('login');
  26.         karmaChange(login, 'plus');
  27. });


Можно еще укоротить, но я под вашу разметку подстраивался.
8. LIME - 12 Июля, 2014 - 10:25:12 - перейти к сообщению
Viper а копипаст убрать?
за это могут и выделить маленький котел
CODE (htmlphp):
скопировать код в буфер обмена
  1. <img class="karma-change" data-act="plus" src="/images/plus.png">
  2. <img class="karma-change" data-act="minus" src="/images/minus.png">
  3. <script>
  4.    $(".karma-change").click(function(){
  5.  
  6.        var mu="<?echo $login?>";
  7.        var act=$(this).data('act');
  8.        $.ajax({
  9.            url: 'insert.php',
  10.            data: "log="+mu+"&znak=" + act,
  11.            success: function(data){
  12.                $('#karma').html(data);
  13.            }
  14.        });
  15.    });
  16. </script>
9. DelphinPRO - 12 Июля, 2014 - 10:45:02 - перейти к сообщению
LIME, логин тоже через атрибут и почти идеально Улыбка
10. Viper - 12 Июля, 2014 - 10:47:44 - перейти к сообщению
LIME кого убрать?
В вашем коде вы забыли что у ТС меняется картинка при наведении.

DelphinPRO пишет:
А логин вполне можно передать через html-атрибуты

вот этого как раз таки делать и не стоит.
11. LIME - 12 Июля, 2014 - 11:33:19 - перейти к сообщению
Viper пишет:
LIME кого убрать?
повторение одинаковой ф-ции отличающейся лишь одним параметром
любое ее изменение повлечет за собой потенциальную возможность забыть скопипастить во вторую
я думал ты уж знаешь
Viper пишет:
вот этого как раз таки делать и не стоит.
как-раз таки очень стоит
чтоб вынести js в отдельный файл
либо как вариант сделать глобальную переменную в шаблоне
но это как-раз таки и не очень
(Добавление)
Viper пишет:
В вашем коде вы забыли что у ТС меняется картинка при наведении.
не забыли
решили что достаточно твоего поста и не стоит возвращаться к очевидному
DelphinPRO пишет:
LIME, логин тоже через атрибут и почти идеально
мне не интересно давать готовый законченный код
мой только демонстрирует мыслю
отвечать на этом ресурсе это как прыщи давить
хорошего ничего а остановиться сложно
так и тянет еще прыщик поискать))
12. DelphinPRO - 12 Июля, 2014 - 11:55:00 - перейти к сообщению
LIME пишет:
как-раз таки очень стоит
чтоб вынести js в отдельный файл
либо как вариант сделать глобальную переменную в шаблоне
но это как-раз таки и не очень

абсолютно согласен
Viper пишет:
вот этого как раз таки делать и не стоит.

но все же интересно, почему?
(Добавление)
и, блин, люди, зачем вы так пишете
CODE (javascript):
скопировать код в буфер обмена
  1. data: "log="+mu+"&znak=" + act,

это дико неудобно и нечитаемо. используйте нотацию объекта (как в моем примере).
13. LIME - 12 Июля, 2014 - 12:50:07 - перейти к сообщению
DelphinPRO пишет:
это дико неудобно и нечитаемо
вранье
сам пользую объект но не вижу особого неудобства в строке
(Добавление)
единственно что нельзя использовать объект формируемый где-то еще
но не сталкивался на практике с такой необходимостью
14. Viper - 12 Июля, 2014 - 13:35:54 - перейти к сообщению
LIME пишет:
повторение одинаковой ф-ции отличающейся лишь одним параметром
любое ее изменение повлечет за собой потенциальную возможность забыть скопипастить во вторую
я думал ты уж знаешь

Ну может мне ещё и за ТС все сделать?

LIME пишет:
чтоб вынести js в отдельный файл
и чтоб ещё дрыгать ФС.
15. LIME - 12 Июля, 2014 - 13:45:21 - перейти к сообщению
Viper пишет:
и чтоб ещё дрыгать ФС.
чтоб кэшировать в браузере побольше контента
ты сегодня не в духе похоже))
(Добавление)
Viper пишет:
Ну может мне ещё и за ТС все сделать?
вообще-то я на твой вопрос ответил
при чем тут ТС вообще?
(Добавление)
LIME пишет:
не вижу особого неудобства в строке
а если присутствует большое количество постоянных параметров таких как ключ например
то строка даже предпочтительнее
с другой стороны если хочешь менять метод с гет на пост то конечно лучше объект
короче не однозначно
по ситуации
(Добавление)
эммм...я не имел ввиду ключ доступа(не накидывайтесь на меня) )))
ключ который идентифицирует тип запроса
короче не важно(это я по последнему тз ключ вспомнил просто)
просто некоторое количество постоянных параметров

 

Powered by ExBB FM 1.0 RC1