@greenfavo
2015-10-03T14:34:10.000000Z
字数 2512
阅读 802
php
今天写了个无刷新微博点赞的demo,主要功能就是点赞时不刷新页面,而且每条微博只能点一次赞。php处理那部分到不难,但由于js基础不牢固,导致写ajax时出了一些意想不到的错误,多方百度才解决。期间遇到了2个问题:一是ajax添加的内容无法绑定事件,二是ajax中无法获取jquery中的$(this)对象。看看我是怎么解决的。
没用php框架,所以没有采用MVC的方法,代码不多就将一点php代码嵌套进html里了。一开始我想通过ajax加载微博内容,但无法为后来添加的内容绑定事件,而且像这种数据比较多的通过ajax载入不利于seo,所以就直接从服务器上获取。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>无刷新微博点赞</title><style type="text/css">ul.weibo{list-style: none;width: 1000px;margin: 10px auto;}li{margin: 20px 0;padding: 20px 20px;border: 1px solid #ccc;}</style></head><body><ul class="weibo"><?phprequire 'conn.php';$sql="select * from praise order by id desc";$result=mysql_query($sql);if (mysql_num_rows($result)>0) {while ($row=mysql_fetch_assoc($result)) {?><li><?php echo $row['content'];?><a href=""class="praise" id="<?php echo $row['id']?>">赞</a><span><?php echo $row['praise'];?></span></li><?php }}?></ul><p class="msg"></p><script src="jquery.min.js"></script><script type="text/javascript">$(".praise").click(function(event){event.preventDefault();//阻止默认事件,防止点击a标签刷新页面var id=$(this).attr("id");//jquery里的$(this)在ajax里获取不到,作用域改变了,要提前保存var self=$(this);$.get('handle-praise.php',{id:id}, function(data) {if (data=="nofirst") {alert("这条微博你已经点过赞了");}else{self.next("span").text(data);}});});</script></body></html>
数据库表叫praise,有3个字段:id,content,praise(微博id,微博内容,点赞数)。
这部分简单,看代码及注释就能懂。不解释了。
handle-praise.php
<?phpsession_start();require 'conn.php';$id=$_GET['id'];//微博ID$sql="select * from praise where id=$id";if (empty($_SESSION['id'.$id])) {//如果该微博session为空,即第一次点赞//不要用$_SESSION['id'.$id]==""作为判断条件,会抛出未定义的提示$result=mysql_query($sql);$row=mysql_fetch_assoc($result);$praise=$row['praise']+1;//点赞数量加1$sql="update praise set praise=$praise where id=$id";mysql_query($sql);echo $praise;$_SESSION['id'.$id]=$id;//点赞过后设置该微博的session}else{//不是第一次点赞echo "nofirst";}?>
第一个是通过ajax加载的DOM元素无法直接绑定事件,原因是事件处理程序只会添加到调用该事件方法比如说click时已经存在的元素,像通过ajax调用这样后来添加的元素是不会绑定那些事件的。常用的解决方法是一开始就把事件绑定到包含它的元素上,不依赖于事件冒泡,叫做事件委托。
比如我们这个例子,假如通过ajax加载微博信息,用ajax载入li,包括li里面的a链接和span点赞数,要实现点击每个li里的链接就更新span里的点赞数,可以绑定到已经存在的ul.weibo上,但这会使所有的li里面的span变化。不是我想要的效果。所以为了简单我没有通过ajax载入微博信息,只对更新点赞数用了ajax。
第二个问题是我要实现每点一个'赞'的链接,它相邻的span里的点赞数就会更新,这是通过ajax实现的。这要用到this,来帮我确定当前点的是谁,谁相邻的元素变化。
奇怪的是我发现我不能在
js基础没打牢导致出了这么多问题,看来又得回去看犀牛书了。