给出以下jQuery函数。
$(document).on("click", ".subMenu>a", function(event) {
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click');
});
如果点击<span>
内的<li>
,则会调用此函数。
<li class="ui-widget ui-menuitem ui-corner-all ui-menu-parent subMenu" role="menuitem" aria-haspopup="true">
<a href="../public_resources/Category.jsf?id=5" class="ui-menuitem-link ui-submenu-link ui-corner-all" tabindex="-1">
<span class="ui-menuitem-icon ui-icon ui-icon-contact"></span><span class="ui-menuitem-text">Occassion</span>
</a>
</li>
可以看出,给定的jQuery函数由CSS类subMenu
(在<li>
中)映射。当调用此函数时(在单击<li>
标记所包含的区域时调用此函数),锚点标记在此函数中被赋予所需的URL,这反过来会触发导致相同功能的单击事件要再次调用 - 最终导致无限递归,并出现以下错误。
未捕获RangeError:超出最大调用堆栈大小
有没有办法避免这种递归,可能是以某种方式重写函数?
此处给出的HTML代码是由UI框架生成的,不太可能触及它。
我可以使用window.location
而不是.trigger('click')
但是当用户通过按住 ctrl 键点击子菜单时,页面应该在新标签。使用window.location
时不会发生这种情况。
答案 0 :(得分:2)
使用javascript触发点击它将绕过处理程序:
$(this).closest("a").attr("href", "www.google.com")[0].click();
答案 1 :(得分:0)
尝试使用:
var a=0;
$(document).on("click", ".subMenu>a", function(event) {
a++;
if(a<=1){
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click');
}else{
a--;
}
});
如果您不想涉及全局变量,可以使用:
$(document).on("click", ".subMenu>a", function(event) {
if($(this).attr('data-clicked')) return true;
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").attr('data-clicked',true).trigger('click');
});
答案 2 :(得分:0)
使用.trigger
,您可以传递参数。尝试这样的事情:
$(document).on("click", ".subMenu>a", function(event, _ISTRIGGER_) {
if(_ISTRIGGER_) return;
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click', true);
});
但请注意,.trigger
不会激活默认行为。做
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5")[0].click();
会激活它。
答案 3 :(得分:0)
如果点击
<span>
内的<li>
,则会调用此函数。
不,它不是,这是你代码中的致命缺陷。
$(document).on("click", ".subMenu>a", function(event) {
单击 <a>
时调用您的代码,而不是<span>
。而且,由于您触发了对链接的点击,因此再次调用事件处理程序。然后再次。再次,直到你用完堆栈空间。堆栈溢出!
要修复,只需修正您的选择器:.subMenu>a>span