ошибка "слишком много рекурсии" в JQuery 1.3.2 - PullRequest
16 голосов
/ 12 марта 2009

Я пытаюсь создать форму с некоторым динамическим поведением. В частности, у меня есть свои входы в 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>

Ответы [ 10 ]

7 голосов
/ 12 марта 2009
$(function() {
    $(".question div").click(function() {
        var radio = $(this).children("input")[0];
        radio.checked = !radio.checked;
    });
});
6 голосов
/ 12 марта 2009

да, событие клика вспыхивает… поэтому, когда вы поднимаете $(this).children("input").click(), вы снова повышаете $(".question div").click() и т. Д.

4 голосов
/ 12 марта 2009

Зачем вам это нужно, если вы уже используете <label for="">? Нажатие на ярлык должно активировать радиоуправление в любом случае.

[Редактировать:] Следуя вашему комментарию, вы можете сделать это следующим образом:

Сделать отображение метки как блочного элемента, применить все стили, которые вы использовали для div, оборачивающего поле.

.question label { display:block }

и затем используйте этот макет. Вы можете избавиться, если divs тоже.

<label><input type="radio">Coke</label>
<label><input type="radio">Pepsi</label>
3 голосов
/ 01 декабря 2010

У меня была такая же проблема, когда я собирался сделать так, чтобы мой div отправлял свои дочерние данные: submit. Это решит проблему:

$(function() {
    $(".question div").click(function() {
        $(this).children("input").click(function(event){
            event.stopPropagation();
        });
        $(this).children("input").trigger("click");
    });});
3 голосов
/ 12 марта 2009

Срабатывает click() только когда целью события является div, т.е.

$(function() {
    $(".question div").click(function(event) {
        if($(event.target).is('div'))
            $(this).children("input").click();
    });
});
1 голос
/ 02 ноября 2010
<script type="text/javascript">
$(function() {
    $(".question div").click(function() {
        $(this).find("input").attr("checked", "checked");
    });
});
</script>

PS: Это было слишком много, вероятно, потому что вы останавливали распространение щелчков элементов div, а не щелчков входных данных.

1 голос
/ 12 марта 2009

Проблема (как сказал grilix) в том, что событие «пузырится» в DOM, поэтому есть простое решение, вам просто нужно отменить этот пузырьковый эффект.

Пузырь относится (на английском языке) к событию, запускаемому на ВСЕХ элементах, на которые влияет его положение в документе. Итак, в вашем примере событие "click" получено (в этом порядке) ТЕЛОЙ, затем родительским (.question) DIV, затем другим DIV и, наконец, INPUT.

Чтобы отменить этот пузырь, вы можете пойти по пути jQuery, вызвав метод stopPropagation в функции обратного вызова, например:

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

Простой javascript-способ потребует от вас использования метода cancelBubble, но я полагаю, что он выходит за рамки вашего вопроса.

Привет, Manolo

0 голосов
/ 12 марта 2009

Спасибо всем. Я попробовал идею Гриликса установить проверенный атрибут, хотя мне пришлось немного исправить синтаксис. Вот что я сделал:

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

Это работает, но мне все еще интересно, почему мой предыдущий способ перестал работать с JQuery 1.3.2. Я знаю об изменениях в поведении всплывающих событий, но почему я не могу это исправить, вызвав в моем обратном вызове «event.stopPropagation ()» или «return false»?

0 голосов
/ 12 марта 2009

Я знаю, что это может быть совсем не ответ, но я пишу так, как это случилось со мной раньше: Это дало мне ошибку «слишком много рекурсии», когда я использовал jquery и прототип в одном проекте, и это также может произойти с ajax.net с jquery, поэтому убедитесь, что между библиотеками нет конфликта, если вы используете более одной.

0 голосов
/ 12 марта 2009

Я не помню, как проверить радио с помощью jQuery, но может быть так:

<script type="text/javascript">
$(function() {
    $(".question div").click(function() {
        $(this).children("input").checked(true);
// or
        $(this).children("input").checked= true;
    });
});
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...