【问题标题】:Uncaught RangeError: Maximum call stack size exceeded - jQuery Error未捕获的 RangeError:超出最大调用堆栈大小 - jQuery 错误
【发布时间】:2015-10-19 15:24:41
【问题描述】:

我正在使用 jQuery,我正在尝试在 click 函数中为不同的链接添加一个点击触发器。这是我所拥有的:

$('.details .banner .banner_link').on("click", function(e){
            e.stopPropagation();
            e.preventDefault();

             $('a.banner_link').trigger("click");
        });

如您所见,我正在使用 stopProp 和 PreventDef,但我仍然得到:

Uncaught RangeError: Maximum call stack size exceeded

这快把我逼疯了,我已经被困了一段时间了,请大家帮忙,或者至少为什么会这样?!

背景:

上面代码中的.banner_link 和a.banner_link 是同一页面上的两个独立链接。我获取了 a.banner_link 的 html 并将其(通过 js)添加到页面上,以在单独的位置显示相同的链接。

我想在新创建的链接中模拟原始链接的行为(它会导致弹出模式),因此我使用 trigger("click") 函数来执行此操作。

注意:

如果我只是在外部点击函数范围之外运行触发器('click'),它运行良好!

【问题讨论】:

  • 您需要在触发点击之前禁用您的处理程序。就目前而言,您的处理程序称自己为无限。
  • 您明确调用“点击”,因此点击被重新称为无限;它与默认行为无关...
  • 您的代码显示,“每当单击 .banner_link 元素时,请单击所有 a.banner_link 元素。”这似乎是非常简单的无限递归。也许您的误解源于“.banner_linka.banner_link ... 是同一页面上的两个独立链接”这句话——选择器.banner_link 适用于类banner_link 的所有元素。为什么你认为这些不会包含在选择器a.banner_link 描述的元素中?
  • 您已经为.banner_link 定义了一个点击函数,它会在.banner_link 上触发一个点击事件,因此它会无限循环,直到它被您的浏览器停止。

标签: javascript jquery google-chrome stack-overflow


【解决方案1】:

由于链接绑定了点击事件,所以当你移动链接触发点击时,点击事件会再次触发,进而调用点击触发器永恒。

为什么需要手动触发点击事件?如果您的模态对话框显示逻辑在一个函数中,只需让点击事件调用该函数。如果它不在一个单独的函数中,它应该是。

stopPropagation 和 preventDefault 将停止事件向上传播,并分别阻止 click 事件的默认操作,但调用 trigger 再次“点击”按钮超出了这些功能的范围

【讨论】:

    【解决方案2】:

    这是一个无限递归,因为

    $('a.banner_link').trigger("click");
    

    将再次调用点击处理程序,依此类推。 由于这些“点击”不是真实事件,e.stopPropagation(); 将不起作用(因为实际点击已经停止传播)。

    你可以使用状态变量来阻止它

        $('.details .banner .banner_link').on("click", function(e){
            if ( $(this).clickstate )
                return:
    
            e.stopPropagation();
            e.preventDefault();
    
             $(this).clickstate = true;
             $('a.banner_link').trigger("click");
        });
    

    因此,更智能的方法是更改​​选择器:

        $('.details .banner a.banner_link').on("click", function(e){
    
              // do what needs to be done ...
    
    
        });
    

    另一种方法是将a.banner_link 的点击处理程序的内部封装到一个函数中并调用它:

      function aClick() {
         ...
      }
    
      $('.details .banner .banner_link').on("click", function(e){
            e.stopPropagation();
            e.preventDefault();
    
             aClick();
        });
    
    
       $('a.banner_link').on("click", function(e){
            aClick();
        });
    

    【讨论】:

    • 触发器选择器是 a.banner_link,因此您的选择器将无法在具有类 .banner_link 的元素内查找锚标记,除非这是一个错字? :-)
    • @StevenBrookes 如果选择器在触发器中工作,它无论如何都会作为选择器工作 - 没明白你的意思...
    • @StevenBrookes 耍了个花招,明白了。将进行编辑。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2018-01-01
    • 2013-05-17
    • 1970-01-01
    • 2013-07-08
    • 2012-08-15
    • 2012-03-30
    • 1970-01-01
    • 2018-01-24
    相关资源
    最近更新 更多