Pergunta

Estou tentando reorganizar meu código e torná-lo mais unobstrusive.

Principalmente, há um link para executar uma ação. Se você clicar no link, a ação é realizada via ajax (o código ajax não é sobre o código aqui) e o texto é substituído por outro texto, oferecendo ao usuário a capacidade de desfazer a ação. Se o usuário clicar no link Desfazer, ajax restabelecer a situação anterior eo texto oferecendo ao usuário executar a ação é mostrado novamente.

Eu fiz uma versão mais simples do meu problema em um único arquivo html (código abaixo). Há dois parágrafos. Se você clicar no link do primeiro parágrafo, que usa em linha chamada onclick, o código funciona como esperado. Mas se você clicar no link do segundo parágrafo, que usa a função jQuery onclick, no link Anular não funciona, e eu não consigo descobrir o porquê.

Qualquer ajuda? Muito obrigado!

<!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>
Foi útil?

Solução

Uma vez que você está dinamicamente adicionando novos itens para o DOM, você terá que registrar o manipulador de clique novamente em os novos itens.

Você pode usar .live para isso.


Atualizar

Desde jQuery 1.7, o método .on é o preferido forma de fazer isso.

Desde jQuery 1.9 a .live método foi removida.

Outras dicas

Apenas demonstrando o uso de .end () para uma solução mais fluido:

$(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();
    });
});

Uma vez que você está adicionando dinamicamente novos itens para o DOM, você terá que registrar o manipulador click novamente sobre os novos itens. jQuery define o manipulador quando você chamar $('...').click(...).

Wow !! Graças a todos vocês!

Eu li sobre o evento ao vivo e código de trabalho final é:

$(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 eu usei remove () para excluir o texto que se oferece para executar a ação. Eu mudei-o para esconder / show, então eu não tenho que usar ao vivo também na primeira função.

Mais uma vez obrigado!

O manipulador de clique é não ser pego quando você acrescentar o elemento ao DOM. Tente usar jQuery para registrar o manipulador de clique, alterando a linha (s) que se parecem com:

$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>")

Para

$("#" + 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;
});

Você pode ser capaz de fazê-lo de forma mais simples, mas parece que você poderia estar adicionando mais de um palmo ao parágrafo então eu fui conservador. Você poderia também provavelmente cadeia off de acréscimo, mas eu pensei que o reselect fez o ponto mais claro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top