@greenfavo
2015-10-03T22:34:10.000000Z
字数 2512
阅读 713
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">
<?php
require '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
<?php
session_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基础没打牢导致出了这么多问题,看来又得回去看犀牛书了。