AJAX成功内的$(this)无法正常工作


103

我试图更改一些使用onclick的旧代码,以便我使用$(this)。问题是,在成功内部时,$(this)不起作用。无论如何,没有将其设置为var就能做到这一点。

$('.addToCart').click(function() {

    $.ajax({
        url: 'cart/update',
        type: 'post',
        data: 'product_id=' + $(this).attr("data-id"),
        dataType: 'json',
        success: function(json) {

            if (json['success']) {

            $(this).addClass("test");

            }   
        }
    });

});

Answers:


231

问题

在回调内部,this引用jqXHR的是Ajax调用的对象,而不是事件处理程序绑定到的元素。了解有关如何this在JavaScript中工作的更多信息


解决方案

如果您可以使用ES2015 +,那么使用箭头功能可能是最简单的选择:

$.ajax({
    //...
    success: (json) => {
         // `this` refers to whatever `this` refers to outside the function
    }
});

您可以设置context选项

该对象将成为所有与Ajax相关的回调的上下文。默认情况下,上下文是一个对象,代表调用中使用的ajax设置($.ajaxSettings与传递给的设置合并$.ajax)。(...)

$.ajax({
    //...
    context: this,
    success: function(json) {
         // `this` refers to the value of `context`
    }
});

或使用$.proxy

$.ajax({
    //...
    success: $.proxy(function(json) {
         // `this` refers to the second argument of `$.proxy`
    }, this)
});

或保留this对回调外部值的引用:

var element = this;

$.ajax({
    //...
    success: function(json) {
         // `this` refers to the jQXHR object
         // use `element` to refer to the DOM element
         // or `$(element)` to refer to the jQuery object
    }
});

有关


1
随着我变得越来越精通JavaScript并建立越来越大的复杂项目,我终于有所了解,但是看到这个答案可以使我非常了解我的假设是正确的,而不仅仅是理论,所以我个人甚至感谢您如果违反SO评论政策!=)
JasonDavis 2015年

我同意(并感谢),所有这三个选项均有效。我不了解ajax上下文选项。一个较小的缺点是我的IDE(Phpstorm)无法识别该选项,可以解决它在诸如此类的JS闭包中有用地检测到的范围问题。添加代理包装程序确实可以消除警告,因此上下文:这在它庞大的启发式列表中必须是未知的技巧。
scipilot '16

同上上下文选项。工作完美。
Anna_MediaGirl,

优秀的例子!
Jawwad Rizwan

-2
jQuery(".custom-filter-options .sbHolder ul li a").each(function () {
    var myStr = jQuery(this).text();
    var myArr = myStr.split(" (");
     url = 'your url'; // New Code
            data = myArr[0];
                try {
                    jQuery.ajax({
                        url : url,
                        context: this,
                        type : 'post',
                        data : data,
                        success : function(data) {
            if(data){
                  jQuery(this).html(data);
            }else{
                  jQuery(this).html(myArr[0]);
            }
                        }
                    });
                } catch (e) {
                } 


});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.