[关闭]
@greenfavo 2015-10-03T22:34:10.000000Z 字数 2512 阅读 713

php学习笔记(五)ajax无刷新点赞

php


一,前言

今天写了个无刷新微博点赞的demo,主要功能就是点赞时不刷新页面,而且每条微博只能点一次赞。php处理那部分到不难,但由于js基础不牢固,导致写ajax时出了一些意想不到的错误,多方百度才解决。期间遇到了2个问题:一是ajax添加的内容无法绑定事件,二是ajax中无法获取jquery中的$(this)对象。看看我是怎么解决的。

二,前端代码

没用php框架,所以没有采用MVC的方法,代码不多就将一点php代码嵌套进html里了。一开始我想通过ajax加载微博内容,但无法为后来添加的内容绑定事件,而且像这种数据比较多的通过ajax载入不利于seo,所以就直接从服务器上获取。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>无刷新微博点赞</title>
  6. <style type="text/css">
  7. ul.weibo{
  8. list-style: none;
  9. width: 1000px;
  10. margin: 10px auto;
  11. }
  12. li{
  13. margin: 20px 0;
  14. padding: 20px 20px;
  15. border: 1px solid #ccc;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <ul class="weibo">
  21. <?php
  22. require 'conn.php';
  23. $sql="select * from praise order by id desc";
  24. $result=mysql_query($sql);
  25. if (mysql_num_rows($result)>0) {
  26. while ($row=mysql_fetch_assoc($result)) {
  27. ?>
  28. <li>
  29. <?php echo $row['content'];?>
  30. <a href=""
  31. class="praise" id="<?php echo $row['id']?>">赞
  32. </a>
  33. <span><?php echo $row['praise'];?></span>
  34. </li>
  35. <?php }
  36. }
  37. ?>
  38. </ul>
  39. <p class="msg"></p>
  40. <script src="jquery.min.js"></script>
  41. <script type="text/javascript">
  42. $(".praise").click(function(event){
  43. event.preventDefault();//阻止默认事件,防止点击a标签刷新页面
  44. var id=$(this).attr("id");
  45. //jquery里的$(this)在ajax里获取不到,作用域改变了,要提前保存
  46. var self=$(this);
  47. $.get('handle-praise.php',{id:id}, function(data) {
  48. if (data=="nofirst") {
  49. alert("这条微博你已经点过赞了");
  50. }else{
  51. self.next("span").text(data);
  52. }
  53. });
  54. });
  55. </script>
  56. </body>
  57. </html>

三,php处理

数据库表叫praise,有3个字段:id,content,praise(微博id,微博内容,点赞数)。

这部分简单,看代码及注释就能懂。不解释了。

handle-praise.php

  1. <?php
  2. session_start();
  3. require 'conn.php';
  4. $id=$_GET['id'];//微博ID
  5. $sql="select * from praise where id=$id";
  6. if (empty($_SESSION['id'.$id])) {//如果该微博session为空,即第一次点赞
  7. //不要用$_SESSION['id'.$id]==""作为判断条件,会抛出未定义的提示
  8. $result=mysql_query($sql);
  9. $row=mysql_fetch_assoc($result);
  10. $praise=$row['praise']+1;//点赞数量加1
  11. $sql="update praise set praise=$praise where id=$id";
  12. mysql_query($sql);
  13. echo $praise;
  14. $_SESSION['id'.$id]=$id;//点赞过后设置该微博的session
  15. }else{//不是第一次点赞
  16. echo "nofirst";
  17. }
  18. ?>

四,遇到的问题及解决方法

第一个是通过ajax加载的DOM元素无法直接绑定事件,原因是事件处理程序只会添加到调用该事件方法比如说click时已经存在的元素,像通过ajax调用这样后来添加的元素是不会绑定那些事件的。常用的解决方法是一开始就把事件绑定到包含它的元素上,不依赖于事件冒泡,叫做事件委托。

比如我们这个例子,假如通过ajax加载微博信息,用ajax载入li,包括li里面的a链接和span点赞数,要实现点击每个li里的链接就更新span里的点赞数,可以绑定到已经存在的ul.weibo上,但这会使所有的li里面的span变化。不是我想要的效果。所以为了简单我没有通过ajax载入微博信息,只对更新点赞数用了ajax。

第二个问题是我要实现每点一个'赞'的链接,它相邻的span里的点赞数就会更新,这是通过ajax实现的。这要用到this,来帮我确定当前点的是谁,谁相邻的元素变化。

奇怪的是我发现我不能在.get使jquery(this)获取当前对象,我把它alert出来发现是空白。因为一开始不知道问题出在哪里,不知道怎么描述问题导致百度了好久,终于让我找到答案了。原来是ajax里的上下文和jquery里的上下文不是一个东西,ajax里的上下文是options对象,而jquery里的上下文就是它封装的(this)ajax使(this)。解决的方法是在ajax外面用个变量把$(this)存起来,然后在ajax里使用这个变量就可以了。

五,总结

js基础没打牢导致出了这么多问题,看来又得回去看犀牛书了。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注