72

これはjqueryのかなり奇妙な問題です。divを読み込んでいます

<div id="container">

ページの読み込み時。各レコードは、「削除」ajax関数が関連付けられた表形式のデータです。ページが読み込まれ、「削除」リンクをクリックすると、ajax呼び出しが正常に開始されます。ただし、イベントが発生すると、ajax呼び出しからデータが返され、divにデータが入力されます(ただし、ページは更新または再読み込みされません)。リンクをもう一度クリックしても、ajaxスクリプトは発生しません。これが私のコードです:

$(document).ready(function() {
    $("button.done").button({
    }).click(function() {
        var BatchID = $("input#BatchID").val();
        var Amount = $("input#Amount").val();
        var Name = $("input#CheckName").val();
        var Check_Number = $("input#Check_Number").val();
        var Company = $("select#Company").val();
        var Department = $("select#Department").val();
        $.ajax({
            type: 'GET',
            url: '/app/usagCheckEntryWS.html',
            data: {
                "BatchID" : BatchID,
                "Amount" : Amount,
                "Name" : Name,
                "Check_Number" : Check_Number,
                "Company" : Company,
                "Department" : Department
            },
            success: function (data) {
                    var ang = '';
                    var obj = $.parseJSON(data);
                    $.each(obj, function() {
                       ang += '<table><tr><td width="45">' + this["RefID"] + '</td><td width="140">' + this["Name"] + '</td><td width="95">' + this["CheckNumber"] + '</td><td align="right" width="70">$' + this["Amount"] + '</td><td width="220" style="padding-left: 15px;">' + this["Description"] + '</td><td><div class="delete" rel="' + this["RefID"] + '"><span>Delete</span></div></td></tr></table>';
                    });
                    $('#container').html(ang);
                    $("input#Amount").val('');
                    $("input#CheckName").val('');
                    $("input#Check_Number").val('');
                    $("select#Company").val('MMS');
                    $("th#dept").hide();
                    $('input#CheckName').focus();
            }
        });
    });
});

4

2 に答える 2

196

要素を削除してから (javascript 経由で) 置き換えると、ページの読み込み時に追加されたイベント バインディングがすべて失われます。

(これは、ページの読み込み後にページに追加されたコンテンツ、つまり ajax で読み込まれたコンテンツにも適用されます)

これにはいくつかの解決策があります。

1)「バインディング」コードをカプセル化し、ページの読み込み時と、問題の要素がページに追加された直後の両方で呼び出します。例えば:

$(document).ready(function(){
    // bind event handlers when the page loads.
    bindButtonClick();
});

function bindButtonClick(){
    $('.myClickableElement').click(function(){
        ... event handler code ...
    });
}

function updateContent(){
    $.ajax({
        url : '/ajax-endpoint.php',
        data : {'onMyWay' : 'toServer'},
        dataType : 'html',
        type : 'post',
        success : function(responseHtml){
            // .myClickableElement is replaced with new (unbound) html element(s)
            $('#container').html(responseHtml);

            // re-bind event handlers to '.myClickableElement'
            bindButtonClick();  
        }
    });
}

2)これを処理するより洗練された方法: jQuery の .on() メソッドを使用します。これにより、イベント ハンドラーをイベント ターゲット以外の要素 (つまり、ページから削除されない要素) にバインドできます。

$(document).ready(function(){
    $('body').on('click','.myClickableElement',function(){
        ... event handler code ....
    });
});

さらなる説明:

この.on()メソッドは、イベント デリゲーションを使用して、親要素にイベント ハンドラー コード (3 番目の引数) を保持し、イベント ターゲット (2 番目の引数) で特定の種類のイベント (1 番目の引数) が実行されたときに発生するように指示します。

1.7 より前のバージョンの jQuery を使用している場合は、基本的に同じことを行う非推奨のデリゲートメソッドを使用してください。

また、イベントが dom ツリーを介して「バブルアップ」する方法のため、イベント ターゲット (.on() メソッドの 2 番目の引数) は委任要素 (jQuery オブジェクトのセレクター) の子孫でなければならないことに注意してください。たとえば、次は機能しません

<div id="container-1">
    <div>
        <div id="another-div">
            Some Stuff
        </div>
    </div>
</div>

<div id="container-2">
    <a id="click-me">Event Target!!!</a>
</div>

<script type="text/javascript">
    $('#container-1').on('click','#click-me',function(){
        ... event handler code ....
        // This will never execute, should've used '#container-2', or 'body', or 'document' instead of '#container-1'
    });
</script>

通常、ページ上のすべての要素は子孫であるため、要素bodyまたはdocument要素は通常安全な選択です。

于 2012-12-07T17:23:21.520 に答える