i have this simple jquery function here.Clicking over a button i want to alert its own class before ajax and again upon succession..but the selector "$(this)" in the last situation is not working and the alert returns "undefined"..
why?
$(".button").live(开发者_运维百科"click",function(){
alert($(this).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert($(this).attr('class')); //returns undefined
}
});
I would do it like this, store $(this)
in a variable so you can use it throughout the function without having to perform a jQuery lookup every time, and you also will not have to depend on the scope to provide the correct element for $(this)
$(".button").live("click",function(){
var button = $(this);
alert(button.attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert(button.attr('class')); //should also return "button"
}
});
});
wrapping this
only once also is a performance enhancement
This will make it work:
$(".button").live("click", function() {
var button = this;
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html) {
alert($(button).attr('class'));
}
});
});
You cannot use the this
reference inside nested functions. The success
function is a nested function and it has its own this
value. If you need the reference to the button inside that nested function, you have to declare a local variable (like button
).
function clickHandler() {
// this == element that was clicked
function ajaxHandler() {
// this != element that was clicked
}
}
Try adding var self = $(this);
when you declare the function, and then use self
instead of $(this)
So your code looks like this:
$(".button").live("click",function(){
var self = $(this);
alert($(this).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert(self.attr('class')); //returns undefined
}
});
Lots of people have posted the solution for this so I won't post the code. Just wanted to mention the reason is because since the success method is a callback your context of $(this) isn't valid anymore. So you need to assign it to a variable and store it for your own use.
$(this)
only exists when referencing an HTML object in the DOM. Since you've tried using in the success function of the AJAX call, $(this)
has no reference. So for example, in the following code $(this)
refers to the item to returned by the jQuery selector:
$('.button').each(function() {
alert($(this));
});
You will need to use a selector to return the item in global scope, and then pass this to the success function in the AJAX call:
var myButton = $('.button');
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html) { alert(myButton.attr('class')); /* returns button */ }
});
Take a look at the context
section here. Basically, what seems to be happening in your code is that the reference to this
no longer applies. Makes sense, given that the context of the code has moved on while the AJAX callback is being handled asynchronously. Explicitly setting the context
to a particular object in the .ajax()
call will carry a reference to the context into the callback function.
You can either add a context: this
property to the hash that is passed to the $.ajax
call, that way the success
handle will it's context set properly, or you can also do something like:
success: $.proxy(function(html) { // using $.proxy will bind the function scope to this
alert($(this).attr('class'));
}, this);
or, another technique I've seen:
$(".button").live("click",function(){
var self = this;
alert($(self).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert($(self).attr('class')); //returns undefined
}
});
精彩评论