【问题标题】:"too much recursion" error in JQuery 1.3.2JQuery 1.3.2 中的“递归过多”错误
【发布时间】:2009-03-12 18:19:46
【问题描述】:

我正在尝试制作具有一些动态行为的表单。具体来说,我在 div 中有我的输入,我想让它这样当用户单击 div 中的任何位置时,输入被选中。我使用的是 JQuery 1.2.6,一切正常。

但是,我升级到 JQuery 1.3.2 并且出现了一些奇怪的行为。当我单击任何输入时,在选择它之前会出现延迟。我的 Firefox 错误控制台在 JQuery 库中给了我几个“递归过多”的错误。我在 Internet Explorer 7 中尝试了该页面,并收到错误消息“对象不支持此属性或方法”。

是我做错了什么,还是 JQuery 中的错误?有谁知道在不回到旧版本的情况下解决此问题的方法?我正在使用 Firefox 3.0.7 以防万一。这是我为说明问题而制作的一个简单示例:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>quiz test</title>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
</head>
<body>
<div class='question'>Favorite soda?
    <div><input type='radio' name='q' value='A' id='a'><label for='a'>Coke</label></div>
    <div><input type='radio' name='q' value='B' id='b'><label for='b'>Pepsi</label></div>
    </div>
<script type="text/javascript">
$(function() {
    $(".question div").click(function() {
        $(this).children("input").click();
    });
});
</script>
</body></html>

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:
    $(function() {
        $(".question div").click(function() {
            var radio = $(this).children("input")[0];
            radio.checked = !radio.checked;
        });
    });
    

    【讨论】:

    • 感谢您的快速响应。我尝试使用 focus() 并没有收到错误,但是单击 div 不再像使用 click() 那样选择输入。
    • 什么意思?有什么区别?
    • 抱歉,我没注意到单选按钮在哪里。
    【解决方案2】:

    是的,点击事件会冒泡……所以当你提高 $(this).children("input").click() 时,你会再次提高 $(".question div").click(),依此类推。

    【讨论】:

    • 我认为问题与新的冒泡行为有关。但是,我尝试在处理程序中调用 event.stopPropagation() 并且遇到了同样的问题。我也尝试了 return false ,但我仍然遇到了问题。
    • 将来用反引号或&lt;code&gt;&lt;/code&gt; 包裹内联代码。我已经修好了。
    【解决方案3】:

    如果您已经在使用&lt;label for=""&gt;,为什么还需要这样做?无论如何,点击标签应该会激活无线电控制。

    [编辑:]跟进您的评论,您可以这样做:

    使标签显示为块元素,应用您用于 div 包装字段的所有样式。

    .question label { display:block }
    

    然后使用此布局。如果 div 也可以去掉。

    <label><input type="radio">Coke</label>
    <label><input type="radio">Pepsi</label>
    

    【讨论】:

    • 我实际上将它用作更复杂布局的一部分。标签并没有完全占据整个 div,我不能单独使用标签,如果用户单击 div 中的任何位置,我希望输入被选中。
    • 我尝试制作标签块,但效果并不理想。如果我在 CSS 上胡闹,我可能会修复它,但我想知道是否有一种快速的方法可以让它像以前一样工作,但是使用新版本的 JQuery。
    • +1 :这是解决它的正确方法。不要重新发明轮子......主要优点是即使没有javascript也能工作!处理 CSS 比处理“不必要的”javascript 问题更有价值。如果它与原来不完全一样,那么您可能需要修改您的 CSS 规则并可能重新排列它们。您应该将 Chetan 答案标记为解决方案。顺便提一句。这也适用于较新版本的 JQuery。
    【解决方案4】:

    仅当事件的目标是 div 时触发click(),即

    $(function() {
        $(".question div").click(function(event) {
            if($(event.target).is('div'))
                $(this).children("input").click();
        });
    });
    

    【讨论】:

      【解决方案5】:

      当我要让我的 div 提交它的子输入时,我遇到了同样的问题:提交。这将解决问题:

      $(function() {
          $(".question div").click(function() {
              $(this).children("input").click(function(event){
                  event.stopPropagation();
              });
              $(this).children("input").trigger("click");
          });});
      

      【讨论】:

        【解决方案6】:

        问题(正如 grilix 所说)是事件“冒泡”DOM,因此,有一个简单的解决方案,您只需要取消该冒泡效果。

        Bubble 是指(简单的英语)一个事件,由于它在文档中的位置而受到影响的所有元素都被触发。因此,在您的示例中,“点击”事件由(按此顺序)BODY 接收,然后是父 (.question) DIV,然后是另一个 DIV,最后由 INPUT 接收。

        要取消气泡,您可以使用 jQuery 方法,在回调函数中调用 stopPropagation 方法,如下所示:

        $(function() {
            $(".question div").click(function(event) {
                $(this).children("input").click();
                event.stopPropagation();
            });
        });
        

        普通的 javascript 方式需要您使用 cancelBubble 方法,但我想这超出了您的问题范围。

        您好, 马诺洛

        【讨论】:

          【解决方案7】:
          <script type="text/javascript">
          $(function() {
              $(".question div").click(function() {
                  $(this).find("input").attr("checked", "checked");
              });
          });
          </script>
          

          PS:递归太多可能是因为您停止传播 div 的点击,而不是输入的点击。

          【讨论】:

            【解决方案8】:

            我不记得如何使用 jQuery 检查收音机,但可能是这样的:

            【讨论】:

            • 你的想法不错,虽然你的语法有点不对劲。我试过了,它奏效了。 $(function() { $(".question div").click(function() { $(this).children("input").attr("checked", true); }); });谢谢。
            • 我说,我不记得那个 XD.. :)
            【解决方案9】:

            我知道这可能根本不是答案,但我正在写它,就像以前发生在我身上一样: 当我在同一个项目中使用 jquery 和原型时,它给了我“太多递归”错误,而且这也可能发生在带有 jquery 的 ajax.net 上,所以如果你使用多个库,请确保库之间没有冲突。

            【讨论】:

              【解决方案10】:

              谢谢大家。我尝试了grillix 设置checked 属性的想法,尽管我不得不稍微修正一下语法。这是我所做的:

              $(this).children("input").attr("checked", true);
              

              它有效,但我仍然很好奇为什么我以前的方法停止使用 JQuery 1.3.2。我知道事件冒泡行为的变化,但为什么我不能通过在回调中调用“event.stopPropagation()”或“return false”来解决这个问题?

              【讨论】:

              • @mikez302:当你调用 stopPropagation() 时,事件已经冒泡到了 div;您必须向按钮和标签添加一个 onclick-handler 并在那里停止传播;此外,retrning false 等效于 preventDefault(),而不是 stopPropagation()
              • ps:您的解决方案适用于单选按钮,但复选框会失败
              • 谢谢。这种新行为有点奇怪,但我现在已经习惯了。
              • 这是标准事件流:w3.org/TR/DOM-Level-3-Events/events.html#Events-flow;不过,IE 不支持事件捕获
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-09-13
              相关资源
              最近更新 更多