前言,我是一名学生,刚开始学习Javascript和jQuery。因此,我的目标是从表单字段中获取信息并将其添加到“联系卡”中的页面,然后可以单击该联系卡以在两组信息之间进行更改,在本例中为名称和说明。
因此,一旦添加了新卡,我就会进行回调以使卡可以点击。它崩溃的地方是第一张卡按预期工作,第二张卡加第二张卡然后工作,但第一张卡没有,第三张卡加第三张,第一张工作,第二张不再有效,依此类推。使用$(document).on代替回调可以使一切正常,但我真的想弄清楚为什么回调不起作用。
非常感谢任何建议,谢谢!
var users = [];
var identifier = 0;
function cardFlipHandler(){
$(".card").click(function(){
var tempID = $(this).attr("identifier");
if($(this).attr("state") === "front"){
$(this).html("<p>" + users[tempID].description + "</p>");
$(this).attr("state", "back");
}
else {
$(this).html("<h1>" + users[tempID].first_name + " " + users[tempID].last_name + "</h1><p>Click for description</p>");
$(this).attr("state", "front");
}
});
}
$(document).ready(function(){
cardFlipHandler();
$("#addUser").click(function(){
var fname = $("form").find("input[name='first_name']").val();
var lname = $("form").find("input[name='last_name']").val();
var desc = $("form").find("input[name='description']").val();
users.push({first_name: fname, last_name: lname, description: desc});
$("#rightSide").append("<div class='card' identifier='" + identifier + "' state='front'><h1>" +fname + " " + lname + "</h1><p>Click for description</p></div>");
identifier++;
cardFlipHandler();
});
/*$(document).on("click", ".card", function(){
var tempID = $(this).attr("identifier");
if($(this).attr("state") === "front"){
$(this).html("<p>" + users[tempID].description + "</p>");
$(this).attr("state", "back");
}
else {
$(this).html("<h1>" + users[tempID].first_name + " " + users[tempID].last_name + "</h1><p>Click for description</p>");
$(this).attr("state", "front");
}
});*/
});
*{
margin: 5px;
padding: 0px;
}
#wrapper {
width: 970px;
margin: 0 auto;
}
#userTable tr td, tr th{
border: 1px solid black;
}
#leftSide {
display: inline-block;
width: 400px;
vertical-align: top;
}
#rightSide {
display: inline-block;
width: 400px;
vertical-align: top;
}
.card {
width: 300px;
height: 150px;
background-color: #F1F1F1;
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Contact Cards</title>
<meta name="description" content="Coding Dojo assignment to create a page where contact cards can be added.">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript" src="card.js"></script>
</head>
<body>
<div id="wrapper">
<div id="leftSide">
<form>
<label>First Name:</label>
<input type="text" name="first_name">
<label>Last Name:</label>
<input type="text" name="last_name">
<label>Description:</label>
<input type="text" name="description">
</form>
<button id="addUser">Add User</button>
</div>
<div id="rightSide">
</div>
</div>
</body>
</html>
答案 0 :(得分:3)
嗯,这个很有趣。
$(document).on("click", ".card", function);
是执行此操作的正确方法。但要解释你的代码发生了什么。 (跟随here)
在JSFiddle中,我在JS的第7行添加了console.log
。每次点击一张卡片都会触发。所以打开你的控制台( F12 ),并制作一张卡片。
单击它时,它将按预期运行。所以另一张牌。
现在,每次点击时,您都会看到第一张卡片的点击事件触发TWICE。基本上翻转,然后再次翻转,让你回到原始状态。第二张卡按预期工作。另一张牌。
第一张牌现在开了三次,第二张牌开了两次。所以现在第一个似乎正在工作,因为它停在不同的面上,第二个是“破碎”,因为它以其原始面结束。
基本上,通过每次制作卡片时运行回调,不仅要向新元素添加事件监听器(按预期),还要向旧卡片添加另一个事件监听器。
除其他原因外,这是为什么我们将$(document).on(event, selector, function);
用于动态创建的元素。
有关.on()
事件和.click()
事件的详细信息,请参阅下文。
答案 1 :(得分:0)
在这种情况下使用回调似乎是不好的做法,因为每次添加用户时都会调用cardFlipHandler()
函数,因此在.card
类上添加新的click事件,因此多次调用它。您可以尝试在类.card
的单击事件上添加console.log(),并在一张卡中单击一次,检查它调用的次数。再次添加另一个用户并尝试单击第一张卡然后它将多次控制台。所以这里的问题是由于多次调用click事件而恢复了card的状态,因此你没有得到正确的结果。
因此,最好的方法是使用您的注释代码,而不是在回调中使用函数。