jQuery.when().done() 不工作
jQuery .when().done() not working
首先我想说我是 jQuery 的新手,我怀疑我只是在做一些愚蠢的事情,所以希望这对某些人来说非常简单。
我正在尝试向我的网站添加滑动移动子菜单。我想要一种手风琴效果,如果我单击一个父项 link,它的子菜单将打开,所有其他子菜单将关闭。问题是时间 - 子菜单打开,然后通过重置所有子菜单再次关闭。我认为答案是使用 deferreds 但我尝试过的一切都失败了。这是(目前不工作)代码:
function ResetMenu(){
jQuery(".mobile-menu").find(".sub-menu").slideUp(100);
jQuery(".mobile-menu").find(".menu-item-has-child").removeClass("open");
};
function OpenSubmenu(){
jQuery(this).next("ul").slideDown(100);
jQuery(this).parent().addClass("open");
};
jQuery("li.menu-item-has-children > a").click(function(){
if(jQuery(this).parent().hasClass("open")){
jQuery(".mobile-menu").find(".sub-menu").slideUp(100);
jQuery(this).parent().removeClass("open");
} else {
jQuery.when(ResetMenu()).done(OpenSubmenu());
}
return false;
});
如有任何帮助,我们将不胜感激。谢谢!
罗内尔
这是使用 jQuery.when()
的常见错误。
jQuery.when()
需要承诺作为参数。它没有神奇的力量来知道你传递给它的功能何时以某种方式完成。这些函数必须 return 承诺在底层代码完成后得到解决或拒绝,然后您可以将这些承诺传递给 jQuery.when()
。
您的 ResetMenu()
函数没有 return 任何东西,因此,您的 jQuery.when()
不会等待任何东西。它立即执行 .then()
处理程序(这看起来不是你想要的)。
因此,在这一行中:
jQuery.when(ResetMenu()).done(OpenSubmenu());
ResetMenu()
必须 return 承诺 jQuery.when()
知道什么时候完成。
您可以通过以下操作修复 ResetMenu()
以这种方式工作:
function ResetMenu(){
return jQuery(".mobile-menu").find(".sub-menu").slideUp(100).promise().then(function() {
// remove this class when the animation has completed
jQuery(".mobile-menu").find(".menu-item-has-child").removeClass("open");
});
};
然后,您需要更改将函数传递给 .done()
的方式,这既使它只是一个可以稍后执行的函数引用,又绑定了适当的 this
值对它:
jQuery.when(ResetMenu()).done(OpenSubmenu.bind(this));
请注意,.bind(this)
假定 this
是合适的值。您可以在那里传递任何值是正确的值,并且在执行时将成为 OpenSubmenu()
内部的 this
值。
当您将非承诺对象传递给 $.when()
时,传递给 done()
的回调会立即被调用,在您的情况下 ResetMenu
没有返回任何东西 OpenSubmenu
被立即调用,还有另一个问题 - 你不应该直接调用 OpenSubmenu
(通过添加 ()
),你需要将函数引用传递给 done()
function ResetMenu() {
jQuery(".mobile-menu").find(".menu-item-has-child").removeClass("open");
return jQuery(".mobile-menu").find(".sub-menu").slideUp(100).promise();
};
function OpenSubmenu() {
jQuery(this).next("ul").slideDown(100);
jQuery(this).parent().addClass("open");
};
jQuery("li.menu-item-has-children > a").click(function () {
if (jQuery(this).parent().hasClass("open")) {
jQuery(".mobile-menu").find(".sub-menu").slideUp(100);
jQuery(this).parent().removeClass("open");
} else {
jQuery.when(ResetMenu()).done(OpenSubmenu);
}
return false;
});
首先我想说我是 jQuery 的新手,我怀疑我只是在做一些愚蠢的事情,所以希望这对某些人来说非常简单。
我正在尝试向我的网站添加滑动移动子菜单。我想要一种手风琴效果,如果我单击一个父项 link,它的子菜单将打开,所有其他子菜单将关闭。问题是时间 - 子菜单打开,然后通过重置所有子菜单再次关闭。我认为答案是使用 deferreds 但我尝试过的一切都失败了。这是(目前不工作)代码:
function ResetMenu(){
jQuery(".mobile-menu").find(".sub-menu").slideUp(100);
jQuery(".mobile-menu").find(".menu-item-has-child").removeClass("open");
};
function OpenSubmenu(){
jQuery(this).next("ul").slideDown(100);
jQuery(this).parent().addClass("open");
};
jQuery("li.menu-item-has-children > a").click(function(){
if(jQuery(this).parent().hasClass("open")){
jQuery(".mobile-menu").find(".sub-menu").slideUp(100);
jQuery(this).parent().removeClass("open");
} else {
jQuery.when(ResetMenu()).done(OpenSubmenu());
}
return false;
});
如有任何帮助,我们将不胜感激。谢谢!
罗内尔
这是使用 jQuery.when()
的常见错误。
jQuery.when()
需要承诺作为参数。它没有神奇的力量来知道你传递给它的功能何时以某种方式完成。这些函数必须 return 承诺在底层代码完成后得到解决或拒绝,然后您可以将这些承诺传递给 jQuery.when()
。
您的 ResetMenu()
函数没有 return 任何东西,因此,您的 jQuery.when()
不会等待任何东西。它立即执行 .then()
处理程序(这看起来不是你想要的)。
因此,在这一行中:
jQuery.when(ResetMenu()).done(OpenSubmenu());
ResetMenu()
必须 return 承诺 jQuery.when()
知道什么时候完成。
您可以通过以下操作修复 ResetMenu()
以这种方式工作:
function ResetMenu(){
return jQuery(".mobile-menu").find(".sub-menu").slideUp(100).promise().then(function() {
// remove this class when the animation has completed
jQuery(".mobile-menu").find(".menu-item-has-child").removeClass("open");
});
};
然后,您需要更改将函数传递给 .done()
的方式,这既使它只是一个可以稍后执行的函数引用,又绑定了适当的 this
值对它:
jQuery.when(ResetMenu()).done(OpenSubmenu.bind(this));
请注意,.bind(this)
假定 this
是合适的值。您可以在那里传递任何值是正确的值,并且在执行时将成为 OpenSubmenu()
内部的 this
值。
当您将非承诺对象传递给 $.when()
时,传递给 done()
的回调会立即被调用,在您的情况下 ResetMenu
没有返回任何东西 OpenSubmenu
被立即调用,还有另一个问题 - 你不应该直接调用 OpenSubmenu
(通过添加 ()
),你需要将函数引用传递给 done()
function ResetMenu() {
jQuery(".mobile-menu").find(".menu-item-has-child").removeClass("open");
return jQuery(".mobile-menu").find(".sub-menu").slideUp(100).promise();
};
function OpenSubmenu() {
jQuery(this).next("ul").slideDown(100);
jQuery(this).parent().addClass("open");
};
jQuery("li.menu-item-has-children > a").click(function () {
if (jQuery(this).parent().hasClass("open")) {
jQuery(".mobile-menu").find(".sub-menu").slideUp(100);
jQuery(this).parent().removeClass("open");
} else {
jQuery.when(ResetMenu()).done(OpenSubmenu);
}
return false;
});