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>
¿Fue útil?

Solución

  

Dado que está agregando dinámicamente nuevos   artículos al DOM, tendrás que   registre el controlador de clic de nuevo en   los nuevos elementos.

Puede usar .live para esto.


Update

Desde jQuery 1.7, el método .on es la forma preferida para hacer esto.

Desde jQuery 1.9, .live método ha sido eliminado.

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top