Вызов click() на radio не изменяет его checked
Добрый день!
Столкнулся с непонятной логикой поведения в FF. На странице средствами javascript создается и настраивается форма. Сначала производится ее создание и настройка, а потом она append'ится в состав страницы. В состав этой формы входит radio-группа. На каждый элемент группы через JQuery подвешен обработчик click(). В конце настройки формы, но до ее append'a на страницу, на первом radio принудительно вызывается его click(). В IE, Chrome, Safari все нормально. В FF проблема... обработчик по click вызывается нормально, а вот checked самого radio-элемента остается неизменным... С checkbox'ами такая же картина... Замена click на change тоже эффекта не дало... Что за ерунда? Мне что, писать собственную реализацию метода click? |
Можно погадать почему, но может все-таки код свой покажите?
|
Цитата:
![]() |
(function(){ var elemContainer = $('<div></div>'); elemContainer.addClass('elem-container'); formContainer.append(elemContainer); var image = $('<img class="grid-icon" src="styles/images/pivot/pivot-columns.png" />'); elemContainer.append(image); var inputRadio = $('<input type="radio" class="elem-container-switcher" elemtype="cap" name="table-radio-group" id="table-radio-group-capElements" />'); elemContainer.append(inputRadio); image.click(function(){inputRadio.click();}); inputRadio.click(function(){ if (this.checked) { elemContainer.parents('.table-headers-type-form:first').find('.active').removeClass('active'); elemContainer.addClass('active'); } console.log(this.checked) }); elemContainer.append('<label for="table-radio-group-capElements" class="block-header">Заголовки</label>'); var options = [ //...... ]; var optionsList = $('<ul class="no-marked-list no-margin-list no-padding-list" id="options-list"></ul>'); for (var i = 0; i < options.length; ++i) { //...... } elemContainer.append(optionsList); elemContainer.append('<div class="selection-information"></div>'); inputRadio.click(); console.log(inputRadio.get(0).checked) })(); click в предпоследней строчке кода Первым делом я предположил, что что-то в составе страницы создает такую непонятку, но это оказалось не так. Я написал вот так в чистой странице: function(){ var df = document.createDocumentFragment(); var input = $('<input type="checkbox" id="checkbox1"></input>'); input.click(function(){ console.log('click => ' + (this.checked ? 'true' : 'false')) }); input.change(function(){ console.log('change => ' + (this.checked ? 'true' : 'false')) }); input.click() $('#result').append(input); } Во всех браузерах кроме FF input меняет свое состояние и в консоль пишется true. В FF при вызове input.click()в консоль пишется false и сам checkbox не меняет своего состояния. Я сделал еще одну кнопку и повесил на нее функцию: $('#do1').click(function(){ var checkbox = $('#checkbox1'); var df = document.createDocumentFragment(); df.appendChild(checkbox.get(0)); checkbox.click(); $('#result').append(checkbox); }); Результат оказался таким, как я и предполагал: как только checkbox выпал из основного DOM-дерева, он перестал меняться. Использование вместо documentFragment обычного тега (document.createElement('div')) с таким же результатом подтвердило мои догадки. И еще любопытный момент: физический click порождает также событие change, а программный click этого не делает. Это во всех браузерах. |
Цитата:
Кстати, ни разу так не пробовал... Любопытный эффект что ли? Или просто click зацикливается? |
demoniqus, ты нормальный хтмл пример в состоянии сделать? Или так на твой говнокод смотреть и дальше медитировать? :)
|
Цитата:
|
Вот модель происходящего
<html> <head> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" > $(function(){ $('#do').click(function(){ var df = document.createDocumentFragment(); var input1 = $('<input type="checkbox" id="checkbox1"></input>'); input1.click(function(){ console.log('click => ' + (this.checked ? 'true' : 'false')) }); input1.change(function(){ console.log('change => ' + (this.checked ? 'true' : 'false')) }); input1.click() $('#result').append(input1); }); }); </script> </head> <body> <button id="do">CYCLE</button> <div id="result"></div> </body> </html> |
Цитата:
Ты понимаешь термин "тестовый пример"? |
Устанавливайте обработчик элементам при их добавлении на страницу, или делегируйте их обработку ближайшему родителю гарантировано присутствующему на странице.
|
Цитата:
Как вариант просто поменяй местами два последних действия. ;) <!DOCTYPE html> <html> <head> <script src='http://code.jquery.com/jquery-latest.js'></script> <!-- <script src="https://code.angularjs.org/1.3.9/angular.min.js"></script> <script src="https://code.angularjs.org/1.3.9/angular-route.js"></script> <link rel='stylesheet type=text/css href=tmp.css' /> --> <style type='text/css'> </style> <script type='text/javascript'> $(function(){ $('#do').click(function(){ var df = document.createDocumentFragment(); var input1 = $('<input type="checkbox" id="checkbox1" />'); input1.click(function(){ alert('click '+this.checked); }); input1.change(function(){ alert('change '+this.checked); }); $('#result').append(input1); input1.click(); }); }); </script> </head> <body> <button id="do">CYCLE</button> <div id="result"></div> </body> </html> |
Цитата:
|
Цитата:
|
Цитата:
|
demoniqus, ты мой пример смотрел?
http://javascript.ru/forum/misc/5491...tml#post365164 |
demoniqus, пофигу какая у вас там форма ибо вы явно прописываете добавление элементов, и при их добавлении нужно и устанавливать обработчик, а лучше делегировать родителю. А об иных проблемах, которые могут быть, написал ksa.
|
Цитата:
Объясняю: я создаю некую форму (но еще не помещаю ее в дерево документа), навешиваю обработчики событий (которые влияют на состояние данной формы и содержат в себе определенную логику связей состояний элементов). Из-за логической связи состояний различных элементов формы их проще настроить, вызвав нужный обработчик, нежели писать еще кучу кода. Вот через тот самый click() я и вызываю эту настройку. И сделать это я хочу до того, как показать форму пользователю (самого как пользователя бесит жутко, когда у тебя на глазах начинают прыгать сами по себе разные прибамбасы по всей странице). И только потом уже готовую форму я append'ю в страницу. Ты же поменял настроечный click и append местами. |
Цитата:
|
Цитата:
Цитата:
|
Цитата:
Мне нужно, чтобы click происходил ДО ТОГО, как форма попадет в страницу. Особенно в свете особенностей работы того же IE, который примерно до 10х раз тормознутее того же Хрома и Лисы... Сейчас на w3c читаю инфу по click и change и пока не вижу ничего такого, что могло бы объяснить подобное поведение в FF. Я просто хотел предположить, что в данном случае FF наиболее строго следует какой-нибудь спецификации (как это часто бывает в случае IE), но только не вижу такой спецификации. Цитата:
И, как я сказал, это сложное приложение, а потому различные связи будут и никуда от этого не деться. Вопрос в том, на что я наткнулся: это глюк Лисы или же это на самом деле нормальное поведение, а остальные браузеры просто прощают эту ошибку (сомневаюсь, что IE может быть лояльнее, чем хоть кто-нибудь другой)? Цитата:
|
>Мне нужно, чтобы click происходил ДО ТОГО, как форма попадет в страницу.
И каким это образом? Если нужно чтобы при добавлении группы, какой-то из ее элементов был установлен, например выбранный ранее пользователем, то этот выбор должен определять сервер. Делает это он не "щелчком", а посредством анализа запросов. Если заведомо известно какой должен быть установлен, по умолчанию например, то устанавливайте ему это свойство. |
Цитата:
Чтобы максимально облегчить жизнь пользователю, сократить число телодвижений с его стороны, я по умолчанию выбираю первый элемент из radio-группы. Если бы от его состояния не зависели параметры иных компонентов, иные данные, то можно было просто тупо и надежно поставить input.checked = true. Но зависимость есть и потому я вызываю обработчик click(). И я никак не ожидал, что click() не изменит checked, да тем более только в одном браузере. |
Часовой пояс GMT +3, время: 14:08. |