web-dev-qa-db-ja.com

jQueryクリック関数とインラインonclick

コードを再編成して、目立たないようにしようとしています。

主に、アクションを実行するためのリンクがあります。リンクをクリックすると、アクションはajaxを介して実行され(ajaxコードはここのコードにはありません)、テキストは他のテキストに置き換えられ、ユーザーはアクションを元に戻すことができます。ユーザーが[元に戻す]リンクをクリックすると、ajaxは以前の状況を復元し、ユーザーに提供するテキストが再び表示されるアクションを実行します。

問題のより単純なバージョンを単一のhtmlファイル(以下のコード)で作成しました。 2つの段落があります。インラインonclick呼び出しを使用する最初の段落のリンクをクリックすると、コードは期待どおりに機能します。しかし、jQuery onclick関数を使用する2番目の段落のリンクをクリックすると、[元に戻す]リンクが機能せず、その理由がわかりません。

何か助けはありますか?どうもありがとう!

<!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>
10
ana

新しいアイテムをDOMに動的に追加しているため、新しいアイテムにクリックハンドラーを再度登録する必要があります。

.live このため。


更新

JQuery 1.7以降、 .on これを行うにはメソッドが推奨されます。

JQuery 1.9以降 .live メソッドは削除されました。

16
Wolfr

より流動的なソリューションのための.end()の使用を示すだけです。

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

ワオ!!あなた方全員に感謝します!

ライブイベントについて読みましたが、最終的な作業コードは次のとおりです。

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

以前は、アクションの実行を提供するテキストを削除するためにremove()を使用していました。非表示/表示用に変更したので、最初の関数でもライブを使用する必要はありません。

再度、感謝します!

2
ana

新しいアイテムをDOMに動的に追加しているため、新しいアイテムにclickハンドラーを再度登録する必要があります。 jQueryは、$('...').click(...)を呼び出すときにハンドラーを設定します。

2
Daniel A. White

要素をDOMに追加するときに、クリックハンドラーが取得されません。 jQueryを使用して、次のような行を変更してクリックハンドラーを登録してみてください。

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

もっと簡単にできるかもしれませんが、段落に複数のスパンを追加しているように見えるので、控えめに説明しました。おそらく追加をチェーンオフすることもできますが、再選択することでポイントが明確になると思いました。

1
tvanfosson