【问题标题】:Uncaught RangeError : Maximum call stack size exceededUncaught RangeError : 超出最大调用堆栈大小
【发布时间】:2014-06-11 13:35:19
【问题描述】:

给定以下 jQuery 函数。

$(document).on("click", ".subMenu>a", function(event) {

    $(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click');
});

当点击<li> 中的<span> 时调用此函数,如下所示。

<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 映射(在 &lt;li&gt; 中)。当这个函数被调用时(当一个被&lt;li&gt;标签包围的区域被点击时),锚标签在这个函数中被赋予一个期望的URL,这反过来又触发一个点击事件,导致相同的函数被再次调用 - 最终导致无限递归并出现以下错误。

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

有没有办法避免这种递归,可能是通过某种方式重写函数?

这里给出的 HTML 代码是由 UI 框架生成的,不太可能接触到它。

我可以使用window.location 而不是.trigger('click'),但是当用户按住ctrl 键单击子菜单时,页面应该在新选项卡中打开。使用window.location 不会发生这种情况。

【问题讨论】:

  • 你可以使用$(this).off('click').attr(...).trigger('click'),但我认为触发这样的点击不会导致链接被关注。

标签: javascript jquery html css


【解决方案1】:

试试这个:

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');
});

【讨论】:

  • 有没有不涉及(模块-)全局变量的解决方案?
  • 不用了,点击后href已经改了,不用再改了。此外,它会通过点击重定向到另一个页面
【解决方案2】:

使用 javascript 触发点击,它将绕过处理程序:

$(this).closest("a").attr("href", "www.google.com")[0].click();

【讨论】:

  • 完美解决了我的问题。谢谢!
【解决方案3】:

使用.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();

将激活它。

【讨论】:

  • 谢谢。使用.attr("href", "URL")[0].click().attr("href", "URL")[0].trigger('click') 似乎没有跟随该链接。它不跟随吗?
【解决方案4】:

当点击&lt;li&gt; 中的&lt;span&gt; 时调用此函数,如下所示。

不,不是,这是您代码中的致命缺陷。

$(document).on("click", ".subMenu>a", function(event) {

当点击&lt;a&gt; 时调用您的代码,而不是&lt;span&gt;。由于您触发了对链接的单击,因此再次调用事件处理程序。然后再次。再一次,直到你用完堆栈空间。堆栈溢出!

要修复,只需修复您的选择器:.subMenu&gt;a&gt;span

【讨论】:

  • 谢谢。使用.attr("href", "URL")[0].click().attr("href", "URL")[0].trigger('click') 似乎没有跟随该链接。它不跟随吗?
猜你喜欢
  • 2017-05-23
  • 1970-01-01
  • 2018-03-18
  • 2011-12-01
  • 1970-01-01
  • 2022-09-29
  • 2016-10-19
  • 2017-12-12
相关资源
最近更新 更多