未捕获RangeError:超出最大调用堆栈大小

时间:2014-04-25 17:54:38

标签: javascript jquery html css

给出以下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时不会发生这种情况。

4 个答案:

答案 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