4

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!

Community
  • 1
  • 1
Miro
  • 8,402
  • 3
  • 34
  • 72

5 Answers5

7

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);
    }
 });
}
Jon
  • 428,835
  • 81
  • 738
  • 806
  • No, you don't *need* to do that, there are other ways. – Guffa Oct 22 '11 at 12:41
  • I would say it is correct, except you should not write `$el = $(this);` - it should be `var $el = $(this);`. What do you think? – Tadeck Oct 22 '11 at 12:42
  • @Tadeck: True, thanks for the catch. I did write "local variable" but that slipped through. – Jon Oct 22 '11 at 12:43
  • @Jon: No problem, upvoting now ;) – Tadeck Oct 22 '11 at 12:46
  • 1
    @miro: Are you sure your jQuery selector is correct? `[]` is what happens when you have a selector that doesn't match anything... – Jon Oct 22 '11 at 13:15
  • the problem was that i needed $(document).ready(function() { //// }); Thank you guys!!! – Miro Oct 22 '11 at 13:34
3

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);
    }
  });
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Are you saying the `.ajax()` call is not within closure of `loadWithoutCache()`? O.o – Tadeck Oct 22 '11 at 12:49
  • @Guffa: If yes, then please see [this fiddle](http://jsfiddle.net/qcVqj/). Or did I misunderstood you? – Tadeck Oct 22 '11 at 12:55
  • @Tadeck: The context is not part of the closure, it's determined by how the function is called. – Guffa Oct 22 '11 at 17:45
  • @Guffa: You were referring to **scope** within your answer (" _... it doesn't run in the scope of the loadWithoutCache method, as that has already ended_ "), and it remains in the same scope, has the same variables accessible as it would be executed within `loadWithoutCache` function (excluding `this` / context). See [closure definition](http://en.wikipedia.org/wiki/Closure_(computer_science)). – Tadeck Oct 23 '11 at 16:26
  • @Tadeck: The code can access variables from the closure, but it doesn't run in the scope of the function where the closure was created. The reason that closure is called closure and not scope is that it's not the same as scope. – Guffa Oct 23 '11 at 17:46
2

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');

Keith.Abramo
  • 6,952
  • 2
  • 32
  • 46
2

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
    }
 });
}
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • +1 This is almost the same as Jon's answer, except yours is correct (although the difference may not be visible for everyone and someone may not care about global variables). – Tadeck Oct 22 '11 at 12:44
1

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.

Moin Zaman
  • 25,281
  • 6
  • 70
  • 74