Подтвердить что ты не робот

Ошибка "слишком много рекурсии" в JQuery 1.3.2

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

Ответ 1

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

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

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

Ответ 2

$(function() {
    $(".question div").click(function() {
        var radio = $(this).children("input")[0];
        radio.checked = !radio.checked;
    });
});

Ответ 3

ya, нажмите пузырьки событий вверх... поэтому, когда вы поднимаете $(this).children("input").click(), вы снова поднимаете $(".question div").click() и т.д.

Ответ 4

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

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

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

.question label { display:block }

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

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

Проблема (как сказал Грилликс) - это событие, "разворачивающее" DOM, так что там простое решение, вам просто нужно отменить этот эффект пузыря.

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

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

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

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

Привет, Маноло

Ответ 8

<script type="text/javascript">
$(function() {
    $(".question div").click(function() {
        $(this).find("input").attr("checked", "checked");
    });
});
</script>

PS: он слишком сильно пересматривался, потому что вы останавливали распространение кликов divs, а не кликов входов.

Ответ 9

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

<script type="text/javascript">
$(function() {
    $(".question div").click(function() {
        $(this).children("input").checked(true);
// or
        $(this).children("input").checked= true;
    });
});
</script>

Ответ 10

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