Función jQuery click vs online onclick
Pregunta
Estoy intentando reorganizar mi código y hacerlo más discreto.
Principalmente, hay un enlace para realizar una acción. Si hace clic en el enlace, la acción se realiza a través de ajax (el código ajax no está en el código aquí) y el texto se reemplaza por otro texto, ofreciendo al usuario la capacidad de deshacer la acción. Si el usuario hace clic en el enlace Deshacer, ajax restablece la situación anterior y el texto que ofrece al usuario realiza la acción que se muestra nuevamente.
He creado una versión más sencilla de mi problema en un solo archivo html (código a continuación). Hay dos párrafos Si hace clic en el enlace del primer párrafo, que utiliza la llamada onclick en línea, el código funciona como se espera. Pero si hace clic en el enlace del segundo párrafo, que usa la función jQuery onclick, el enlace Deshacer no funciona, y no puedo entender por qué.
¿Alguna ayuda? Muchas gracias!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function() {
$(".add2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .add2").remove();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
return false;
})
$(".undoadd2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .actions").find("span.added, a.add2").remove();
$("#" + placeId + " .actions").append("<a class='add2' onclick='copyPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>");
return false;
})
});
function addPlace(placeId){
$("#" + placeId + " .add").remove();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>");
return false;
}
function undoAddPlace(placeId){
$("#" + placeId + " .actions").find("span.added, a.undoadd").remove();
$("#" + placeId + " .actions").append("<a class='add' onclick='addPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>");
return false;
}
</script>
</head>
<body id="home">
<div class="place" id="3435910">
<p class="actions"><a href="#" onclick="addPlace('3435910'); return false;" class="add">Add place</a></p>
</div>
<div class="place" id="3435912">
<p class="actions"><a href="#" class="add2">Add place</a></p>
</div>
</body>
</html>
Solución
Otros consejos
Simplemente demostrando el uso de .end () para una solución más fluida:
$(function() {
$(".add2").click(function(){
return $(this).parents(".place")
.find(".add2")
.hide()
.end()
.find(".actions")
.append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
});
$('.undoadd2').live('click', function(){
return $(this).parents(".place")
.find(".actions")
.find("span.added, a.undoadd2")
.remove()
.end()
.end()
.find(".add2")
.show();
});
});
Dado que está agregando dinámicamente nuevos elementos al DOM, tendrá que volver a registrar el controlador clic
en los nuevos elementos. jQuery establece el controlador cuando llama a $ ('...'). haga clic en (...)
.
¡Guau! ¡Gracias a todos!
He leído sobre el evento en vivo y el código de trabajo final es:
$(function() {
$(".add2").click(function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .add2").hide();
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>");
return false;
})
$('.undoadd2').live('click', function(){
var placeId = $(this).parents(".place").attr("id");
$("#" + placeId + " .actions").find("span.added, a.undoadd2").remove();
$("#" + placeId + " .add2").show();
return false;
});
Anteriormente utilicé remove () para eliminar el texto que ofrece realizar la acción. Lo he cambiado para ocultar / mostrar, por lo que no tengo que usar live también en la primera función.
Gracias de nuevo!
El controlador de clic no se está seleccionando cuando agrega el elemento al DOM. Intente usar jQuery para registrar el controlador de clics cambiando las líneas que se ven así:
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>")
A
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" >Undo</a>");
$('#' + placeId + " .actions").find("span:last").find("a").click( function() {
undoAddPlace( placeId );
return false;
});
Es posible que pueda hacerlo de manera más simple, pero parece que podría estar agregando más de un espacio al párrafo, así que fui conservador. Probablemente también podría encadenar un apéndice, pero pensé que la reselección aclaraba el punto.