2009-03-12 5 views
16

Я пытаюсь сделать форму с некоторым динамическим поведением. В частности, у меня есть мои входы в div, и я хотел бы сделать это, когда пользователь щелкает в любом месте div, вход выбран. Я использовал JQuery 1.2.6, и все работало нормально.Ошибка «слишком много рекурсии» в JQuery 1.3.2

Однако я обновился до 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> 

ответ

0

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

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

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

+0

@ mikez302: когда вы вызываете stopPropagation(), событие уже активизировалось до div; вам нужно будет добавить обработчик onclick к кнопке и метке и прекратить распространение там; Кроме того, получение false эквивалентно функции preventDefault(), а не stopPropagation() – Christoph

+0

ps: ваше решение работает с радиокнопками, но сбрасывается для флажков – Christoph

+0

Спасибо. Это новое поведение немного странно, но я привык к этому сейчас. –

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

Благодарим за быстрый отклик. Я попытался использовать focus(), и я не получил ошибку, но нажатие в div больше не выбирает вход, как это делает с помощью click(). –

+0

Что вы имеете в виду? Какая разница? –

+0

Извините, я не заметил, где они переключатели. –

6

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

+0

Я думал, что проблема связана с новым барботажным поведением. Однако я попытался вызвать event.stopPropagation() в моем обработчике, и у меня была та же проблема. Я также попытался вернуть false, и у меня все еще была проблема. –

+1

Оберните встроенный код вокруг обратных ссылок или '' в будущем. Я исправил это. – nyuszika7h

+0

ой, хорошо .. спасибо :) – grilix

4

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

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

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

.question label { display:block } 

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

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

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

+0

это лучшее решение. – grilix

+0

Я попытался сделать блок ярлыка, но он не подошел так, как я хотел. Я мог бы исправить это, если бы я обманул CSS, но мне интересно, есть ли у него быстрый способ заставить его работать так, как раньше, но с новой версией JQuery. –

0

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

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

У вас была хорошая идея, хотя ваш синтаксис был немного отключен. Я попробовал это, и это сработало. $ (функция() { \t $ ("вопрос дел. ") Нажмите (функция() { \t \t $ (это) .children (" вход ") атр (" проверено", правда),.. \t}); }); Спасибо. –

+0

Я сказал, я не помню, что XD .. :) – grilix

0

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

3

Только огонь click() когда цель мероприятия является ДИВ, т.е.

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

Только то, что я искал, спасибо! –

1

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

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

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

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

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

Привет, Manolo

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

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

3

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

$(function() { 
    $(".question div").click(function() { 
     $(this).children("input").click(function(event){ 
      event.stopPropagation(); 
     }); 
     $(this).children("input").trigger("click"); 
    });}); 
Смежные вопросы