web-dev-qa-db-ja.com

JQueryイベントは、ajax呼び出し後に発生しません

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

<div id="container">

ページの読み込み時に。各レコードは、「delete」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();
            }
        });
    });
});
58
Matthew Colley

要素を削除してから(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のバージョンを使用している場合は、廃止された delegate メソッドを使用します。これは本質的に同じことを行います。

また、イベントが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 ....
    });
</script>
_

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

160
Jason Fingar

イベントスクリプトをDIVで囲み、コンテンツを動的にロードした後にReplaceallコマンドを実行できます。

<div class="somescript">
-- Event Script that you want to map with dnamically added content
<div>

-コンテンツを動的にロードし、その後に以下のコマンドを実行します。

$(".somescript").replaceAll($(".somescript"));

動的にロードされたコンテンツがロードされ、replaceコマンドが実行されると、イベントがマップされ、コードが正常に実行されます。

1

コメントが長すぎます、ごめんなさい。

これは古い投稿であることがわかりますが、質問とコメントだけです。 $(document).on( 'click'、 '#xxx "、function(e){});を使用して、AJAXを使用して返されたコンテンツにハンドラーをアタッチするか、関数を使用する(){ $( '#xxx).on(' click '、function(e){});}そして、AJAX呼び出しの後にそれを呼び出すと成功して戻ります。何らかのトリックやガイドラインがありますかそのメソッドを使用するために?私は委任を取得し、それを使用しようとしましたが、それは頻繁に機能しません。囲んでいる要素に委任しようとすることができます。何らかの理由でドキュメントまたは本文にバブルアップしないのでしょうか?

0
SScotti