问题描述:前端发送POST请求,得到二维数组,一维为行,二维为4条用户信息和1条用户留言信息,需要根据目前登陆者的用户名比对每条用户信息,如果是当前用户的留言信息,则将delete按键显示,并绑定相应的按键响应函数。
为了简化代码示例,只mark上最核心的部分。
首先以下这些代码是肯定是这样,然后后面再一步步把我犯的错误代码写上,最后总结这个问题:
$(document).ready(function(){
//假设当前登陆的用户名为mika
var username = "mika";
var data = new Object();
data.action = "refresh";
//发送POST请求,从服务器端返回的是JSON字符串,这里接收到的data是jQuery自动为我们转换为了JS对象,JSON字符串的样子大概是这样
/*[{"id":"1","username":"mika","comment":"this is mika s comment","commenttime":"11:49:06","imgnum":"1","webpage":null},{"id":"2","username":"mika1","comment":"this is mika1 s comment"
,"commenttime":"11:50:12","imgnum":"1","webpage":"zhangtao@sina.cn"}]*/
$.post('/comment/2/php/mainpage.php',data, function(data) {
//循环遍历这个对象
for(var row in data){
//定义一个评论单元的html
var htmlCont = '\
<div id="indexWrapper" class="cX">\
<span class="indexid" hidden="hidden">indexidcontent</span>\
<img class="img" src="img/imgnum.jpg" />\
<a class="userName" href="webpage">username</a> \
<span class="date">datee</span>\
<p clasa="text">commcon</p>\
<a class="delete">删除</a>\
</div>\
';
//用每一行的实际数据替换上面的标签内容和属性
htmlCont = htmlCont.replace(/indexidcontent/,data[row]["id"]);
htmlCont = htmlCont.replace(/username/,data[row]["username"]);
htmlCont = htmlCont.replace(/datee/,data[row]["commenttime"]);
htmlCont = htmlCont.replace(/imgnum/,data[row]["imgnum"]);
htmlCont = htmlCont.replace(/webpage/,data[row]["webpage"]);
htmlCont = htmlCont.replace(/commcon/,data[row]["comment"]);
//检测当这一行的数据的用户是否是当前登陆用户,如果是则把这一个html div设定一个特定id
if (data[row]["username"] == username){
indexWrapper = "indexWrapper" + data[row]["id"];
htmlCont = htmlCont.replace(/indexWrapper/,indexWrapper);
}else{
htmlCont = htmlCont.replace(/indexWrapper/,"");
}
//把data的这一行数据的html单元插入到html文档中id为content的div中
$("#content").prepend(htmlCont);
/***********
*下面补上事件绑定的代码
*这里的代码就是错了好几次的地方
***********/
indexWrapper = null;
htmlCont = null;
}
});
})
好了,现在所有的数据都能够在html文档中显示,下面就进行事件绑定部分的代码实现
一 . 第一次犯错
第一次错误原因是没有搞清楚jQuery bind()函数参数用法,不列出错误代码了,把bind函数的用法mark如下:
$(selector).bind(type,[data],fn);
type:可含有一个或多个事件类型的字符串,一般都是一个
data:作为event.data属性值传递给事件对象的额外数据对象,注意这个参数是一个JS对象形式,这个参数坑了我。
fn:就是回调函数的名字,或者直接写成function(){}
坑在这:如果给这个type参数传入一个整形变量,那么当触发这个事件的时候,才把这个变量值传入,而不是绑定时传入的值,这点很坑。
这里测试这个错误:
//在POST循环外定义一个变量var test = 1;
//在上面事件绑定代码处添加如下代码
if (data[row]["username"] == username) {
$("#"+indexWrapper).bind('click',test,function(event) {
alert(test);
});
test++;
}
//点击每一个用户名为mika的div(这里假设有3个用户名为mika的数据,即上面的if进入了3次),都alert了数字4,就是这么吊!
二 . 第二次犯错
下面列出我的第二次错误代码,大家来找茬。
if (data[row]["username"] == username) {
$("#"+indexWrapper).bind('mouseenter',{indexWrapper:indexWrapper},function(event) {
$("#" + event.data.indexWrapper + " .delete").css('display', 'block');
$("#" + indexWrapper + " .delete").bind('click',{id:data[row]["id"]},function(event) {
alert(event.data.id);
});
});
$("#" + indexWrapper).bind('mouseleave',{indexWrapper:indexWrapper}, function(event) {
$("#" + event.data.indexWrapper + " .delete").css('display', 'none');
});
}
注意1:传入bind的参数是作为event.data属性值传递给事件对象的;
注意2:jQuery选择器原理与CSS选择器相同,如果选择器里面要使用变量,就可以这样$(“#” + varName);
注意3:CSS选择器的派生选择器用法;
注意4:我把对delete按键的click事件绑定放在了 id为indexWrapper的div容器的mouseenter事件响应里面,这就导致,每mouseenter一次,就把click绑定一次,这样的问题是大大的,绑定几次,按下一次delete按键,就触发几次响应函数,结果很糟糕;
最终正确的代码是:
if (data[row]["username"] == username) {
$("#"+indexWrapper).bind('mouseenter',{indexWrapper:indexWrapper},function(event) {
$("#" + event.data.indexWrapper + " .delete").css('display', 'block');
});
$("#" + indexWrapper).bind('mouseleave',{indexWrapper:indexWrapper}, function(event) {
$("#" + event.data.indexWrapper + " .delete").css('display', 'none');
});
$("#" + indexWrapper + " .delete").bind('click',{id:data[row]["id"]},function(event) {
alert(event.data.id);
});
}
【完】