调用的jQuery.post回调函数是什么上下文?
让我们举个例子说:
$(".button").click(function() { $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function(data, textStatus) { $(this).parent().after('button clicked
'); }, "json" ); });
我跑了这个并没有用。 在我理论化之前我尝试了一些事情,在这个特定的“.button”的上下文中没有调用回调,所以$(this)没用。 这相反:
$(".button").click(function() { var thisButton = $(this); $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function(data, textStatus) { thisButton.parent().after('button clicked
') }, "json" ); });
这感觉有点像黑客。 这是获取对点击按钮的引用的正确方法吗? 什么上下文(或任何其他回调)被调用?
谢谢!
阿里
你在这里注意到的是JavaScript闭包的工作方式。 与其他OO语言一样,当调用方法时,它有一个“this”,类似于Java或Ruby的self
。 但是,JavaScript非常具有可塑性,并且jQuery利用该属性在调用回调时将其设置为有用的值。
在事件的情况下,jQuery将this
指针设置为指向绑定事件处理程序的元素。 看一下这个:
var hello = function() { console.log("Hello " + this); });
如果你来自OO背景,你可能会在困惑中看到上面的代码片段: this
指向了什么。 默认情况下,它将指向全局对象(浏览器中的窗口)。 但你可以轻松地覆盖:
hello.call("world") // will print "Hello world"
调用在this
之后接受多个参数,这些参数作为参数传递。 一个名为apply
类似方法也会将this
作为第一个参数,但将一个参数Array作为第二个参数。
现在,如果我们再看一下你的例子:
$(".button").click(function() { $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function(data, textStatus) { $(this).parent().after('button clicked
') }, "json" ); });
这里的问题是,当jQuery再次调用该函数时,它并没有使用相同的函数调用它。 当您创建一个匿名函数时,它将保留同一范围内的所有局部变量,但不包含this
,这些变量由JavaScript本身(对全局对象)设置或在调用时被覆盖。
因此,解决方案是在局部变量中存储指向this
变量的指针,然后this
变量可用于闭包。
如上所述,解决方案是:
$(".button").click(function() { var parent = $(this).parent(); $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function() { parent.after('button clicked
') }, "json" ); });
一般来说,当我存储本地时,我存储了我能够使用的最具体的元素集,以使回调代码更简单。 常见的jQuery习惯是做var self = this
,这也很好。
另请注意,JavaScript函数不会检查参数的数量,因此如果不使用参数,将参数保留为空是完全合法的。 它们仍将被传入,但空参数列表将被忽略。
根据jquery api (在“Callback Function Queues”下),任何JQuery AJAX回调函数中的this
对象将自动指向ajax对象的设置或 – 如果指定 – context
对象。
遗憾的是,您无法在$ .post()中指定context
。
这是解决问题的正确方法。
找出上下文的最简单方法是使用Firebug和console.log(this)
– 我怀疑它将是XHR对象。
关键字“this”绑定到函数的范围。 要引用其他父作用域,您需要将引用存储在适当的作用域变量中,例如var parentScope = this;