jQuery回调 - 在添加新元素

时间:2017-03-02 16:59:10

标签: javascript jquery

前言,我是一名学生,刚开始学习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>

2 个答案:

答案 0 :(得分:3)

嗯,这个很有趣。

首先,$(document).on("click", ".card", function);是执行此操作的正确方法。

如果我是你,我会坚持下去。

但要解释你的代码发生了什么。 (跟随here

在JSFiddle中,我在JS的第7行添加了console.log。每次点击一张卡片都会触发。所以打开你的控制台( F12 ),并制作一张卡片。

单击它时,它将按预期运行。所以另一张牌。

现在,每次点击时,您都会看到第一张卡片的点击事件触发TWICE。基本上翻转,然后再次翻转,让你回到原始状态。第二张卡按预期工作。另一张牌。

第一张牌现在开了三次,第二张牌开了两次。所以现在第一个似乎正在工作,因为它停在不同的面上,第二个是“破碎”,因为它以其原始面结束。

基本上,通过每次制作卡片时运行回调,不仅要向新元素添加事件监听器(按预期),还要向旧卡片添加另一个事件监听器。

除其他原因外,这是为什么我们将$(document).on(event, selector, function);用于动态创建的元素。

有关.on()事件和.click()事件的详细信息,请参阅下文。

.on() | jQuery API Docs

.click() | jQuery API Docs

答案 1 :(得分:0)

在这种情况下使用回调似乎是不好的做法,因为每次添加用户时都会调用cardFlipHandler()函数,因此在.card类上添加新的click事件,因此多次调用它。您可以尝试在类.card的单击事件上添加console.log(),并在一张卡中单击一次,检查它调用的次数。再次添加另一个用户并尝试单击第一张卡然后它将多次控制台。所以这里的问题是由于多次调用click事件而恢复了card的状态,因此你没有得到正确的结果。 因此,最好的方法是使用您的注释代码,而不是在回调中使用函数。