$(this) doesn't work in a function

2019-01-08 01:01发布

问题:

The following code loads html content from a file (i used this thread)

<script>
$.fn.loadWithoutCache = function (){
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
    success: function(data) {
        $(this).html(data);        // This is not working
      //$('#result').html(data);   //THIS WORKS!!!
        alert(data);           // This alerts the contents of page.html
    }
 });
}


$('#result').loadWithoutCache('page.html');

</script>

Please let me know what the problem is? I hope it's something stupid :)

Edit: CORRECT CODE

<script>
$(document).ready(function() {

$.fn.loadWithoutCache = function (){
 var $el = $(this);
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
     context: this,
     success: function(data) {
     $el.html(data);
    }
 });
}

$('#result').loadWithoutCache('page.html');

});
</scipt>

Thanks Jon and everyone!

回答1:

The callback (success) function runs when the response arrives, and it doesn't run in the scope of the loadWithoutCache method, as that has already ended.

You can use the context property in the ajax call to set the context of the callback functions:

$.fn.loadWithoutCache = function (){
  $.ajax({
    url: arguments[0],
    cache: false,
    dataType: "html",
    context: this,
    success: function(data) {
      $(this).html(data);
    }
  });
}


回答2:

The problem is that inside the success callback, this does not have the value you expect it to.

However, you do have access to this (with the expected value) inside loadWithoutCache itself. So you can achieve your goal by saving $(this) into a local variable and accessing it from inside the success handler (creating a closure).

This is what you need to do:

$.fn.loadWithoutCache = function (){
 var $el = $(this);
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
     success: function(data) {
        $el.html(data);
        alert(data);
    }
 });
}


回答3:

You scoping of this is incorrect. You need to save your this to a variable outside of the ajax success function and reference it from that variable

<script>
$.fn.loadWithoutCache = function (){
 var self = this;
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
    success: function(data) {
        self.html(data);        // This is not working
      //$('#result').html(data);   //THIS WORKS!!!
        alert(data);           // This alerts the contents of page.html
    }
 });
}


$('#result').loadWithoutCache('page.html');



回答4:

Within the AJAX callback, this is bound to a different object. If you want to reuse the target of your plugin, store (capture) it in a local variable and use that.

$.fn.loadWithoutCache = function (){
 var $target = $(this);
 $.ajax({
     url: arguments[0],
     cache: false,
     dataType: "html",
     success: function(data) {
        $target.html(data); // note change
    }
 });
}


回答5:

JQuery's this is contextual. http://remysharp.com/2007/04/12/jquerys-this-demystified/

console.log($(this)) at different points to see what it refers to.