0

クラスセレクターの特定の状況で、コンテキスト $(this) が変化するようです。以下の JavaScript をデバッグするのにかなりの時間を費やしましたが、これはあまり得意ではありません。

$.fn.specialbutton = function(callback) {
    $(this).bind('click', function() { // $(this) is the a.button, as expected
        $.ajax({
            url: 'ajax.php',
            data: callback(); // context pitfall 
        }).done(function(response) {
            $(this).html(response); // context changed to something unknown
        })
    });
}

$('a.button').specialbutton(function() {
    // context pitfall 
    return {
        id: $(this).data('id'); // $(this) is not what you expect
    };
});

最終的に、解決策はコンテキストを保存し、コールバックの明示的な呼び出しを使用することだと思います。

$.fn.specialbutton = function(callback) {
    $(this).bind('click', function() { // $(this) is the a.button, as expected

        var $this = $(this); // save the context;

        $.ajax({
            url: 'ajax.php',
            data: callback.call($this); // explicitly specify context
        }).done(function(response) {
            $this.html(response); // reuse the saved context
        })
    });
}

$('a.button').specialbutton(function() {
    // context pitfall 
    return {
        id: $(this).data('id'); // $(this) is what was specified in prototype
    };
});

コンテキストの変更のルールと理由は何ですか? これは設計上の特徴ですか、それとも制限ですか? これは、セレクターが HTML id セレクター、つまり$('a#button'). 上記をコーディングするためのより良い、または一般的な方法は何でしょうか?

4

3 に答える 3

2

簡単な答えは、コンテキストを変更しないということです。というか、文脈の変化に一貫性があります。メソッド内にいるdone場合、そのメソッドは、行っているajax呼び出しに固有です。したがって、その場合の は、ハンドラー内とはまったくthis異なることを意味します。thissubmit

サブミット ハンドラーの外でその ajax 呼び出しを行った場合、どうなると思いますthisか?

要約するthisと、定義上、文脈依存です。コンテキストを変更すると (呼び出しを行う場合ajaxや、そのオブジェクトのメソッド/コールバック内で行う場合など)、 の意味thisは確実に変わります。以前のコンテキスト値が必要な場合は、上位のクロージャからthisの以前の値を追跡する必要があります。これは、設定時に行っていることとまったく同じです。this$this

于 2013-05-14T17:15:33.393 に答える
1

context( this) は、関数がどのように定義および/または実行されるかに応じて変化します。

それを書くためのより良い方法は次のようになります:

$.fn.specialbutton = function(callback) {
    this.bind('submit', function() { // $(this) is the a.button, as expected
        $.ajax({
            url: 'ajax.php',
            data: callback.call(this), // explicitly specify context
            context: this, // explicitly specify context
        }).done(function(response) {
            this.html(response); // the context is now correct
        })
    });
}

$('a.button').specialbutton(function() {
    // context pitfall 
    return {
        id: this.data('id'); // this is the element that was submitted
    };
});

アンカータグには送信イベントがないため、コードはあまり意味がありません...

于 2013-05-14T17:17:46.280 に答える