![]() |
|
Модераторы: Sardar, Aliance |
![]()
|
|
| SelenIT |
|
||||||||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
Вчера наш любимый самый-недопонимаемый-язык-программирования-в-мире нанес моему самоуважению очередную смертельную рану ниже пояса. Я-то уже, можно сказать, привык к таким сюрпризам и перестал из-за каждого из них уходить в депрессию и запой на полгода, но... хочется ведь разобраться!
Итак, моя наивная детская вера в незыблемость основ - напр., того, что обработчики событий вида нечто.onclick и т.п. вызываются исключительно внешними причинами (как-то действия юзера, в частности, клики), но не программными вызовами типа нечто.click(), была беспощадно поругана суровой правдой жизни и разбилась вдребезги о таковую. Хотя подобное утверждалось не только на многих уважаемых форумах, но и, например, здесь:
И действительно, пример связанных чекбоксов по ссылке (надо полагать, из старинной, но серьезной книги) и в IE6, и в FF2 работает в точности по описанному - ничего не зацикливается, меняются они синхронно, как положено... Поэтому, когда на другом уважаемом форуме я наткнулся на рекомендацию вызывать onclick кнопки путем вызова ее click(), я испытал нешуточное нервное потрясение. К моему удивлению, такой вариант:
радостно выкинул алерт по клику на Button2... Какого же, простите, censored-переcensored, оно вызывается, если в тех же самых "умных книжках" четко сказано следующее?
Небольшое расследование привело меня лишь в еще большее недоумение. Слегка изменив код из первой ссылки:
я с удивлением увидел, что в IE для каждой пары (и чекбоксов, и кнопок) выскакивает аккурат по 2 алерта - для каждого элемента из пары: получается, лишь первый программный клик вызывает обработчик, а дальше какой-то другой механизм борется с зацикливанием - так, что ли? И совсем странно ведет себя это безобразие в Опере 9.20 и последней альфе FF3 (Gecko/20070604 Minefield/3.0a6pre). В первой никаких алертов вообще нет, но чекбоксы после первого клика... начинают часто мерцать и перестают реагировать на новые клики - неужели то самое зацикливание? Хорошо еще, браузер от этого не зависает намертво... Во второй же алерт выскакивает... трижды - получается, что "привязываемый" чекбокс оказывается "кликнут" дважды и его состояние в итоге не меняется! Ни в MSDN, ни в MDC, ни в стандарте DOM я так и не нашел хотя бы примерной рекомендации, как должен вести себя браузер в таком случае... может, плохо искал? Вообще, откуда повелась такая свистопляска именно с onclick-ом? Onsubmit у формы ведь, насколько я помню, никогда не вызывается при ее программном submit()-е (хотя теперь уже я ни в чем не уверен...)? Уважаемые гуру и корифеи! Пожалуйста, натолкните меня на хоть какую-нибудь твердую почву, не дайте свихнуться окончательно! А то у меня только-только стала своя жизнь налаживаться, обидно все потерять и кончить дни в дурке из-за такого, по сути, пустяка... ;) -------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
||||||||
|
|||||||||
| AKS |
|
|||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
??? Вообще-то, как-раз он ( click() )для того и существует. Но ближе к делу. На мой взгляд данный тест всего лишь подтверждает то, что все браузеры работают по-разному и не более того. Взять, к примеру, IE. Все, как будто, логично - событие, происходящее в данный момент вновь не инициируется. Если взять Opera, то впечатление такое, как-будто у нее нет программного click() в том виде, в каком он имеется в IE. У нее происходит прямой вызов того, что в атрибуте onclick (т.е. происходит не click(), а вызов onclick()). Если таким же образом подойти к проблеме в IE, то возникнет точно такая же бесконечная рекурсия... С Gecko интересней, но не думаю, что это необъяснимо - это всего лишь свои особенности... |
|||
|
||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
Хм... я был уверен, что click() существует главным образом для программного переключения чекбоксов/радиокнопок, а onclick() всегда нужно вызывать явно, поэтому-то до сих пор не сталкивался с этой странностью;)... да и вышеприведенные цитаты (где дважды повторено, что click() onclick-а не вызывает) на чем-то ведь основываются? Если это просто устаревшая информация - то где можно прочитать о том, когда и почему это поведение было изменено? Если же заведомо ложная - то где найти истину? И опять же, почему тогда программный submit() формы не вызывает ее обработчика onsubmit - даже в Опере (только что проверил)? Почему разные события в этом плане ведут себя по-разному и отчего это зависит? Да уж - на работе у меня в FF 2.0.0.4 пример связанных взаимным click()-ом чекбоксов работает, а дома ведет себя аналогично FF3 (тройное срабатывание)... может, дело в extension-ах каких-нибудь? Жалко, пока нет времени на масштабное исследование... И все же я был бы очень благодарен, если бы меня ткнули носом в TFM, объясняющий различие поведения click() - onclick vs. submit() - onsubmit и тому подобные (для меня абсолютно неочевидные, более того - субъективно нелогичные) элементарные вещи... -------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| Zeroglif |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
На старых доках и собственно ситуации на момент написания этой древнейшей книжки.
Много чего постоянно менялось в угоду пользователям или же а-ля "сделаем как у IE", чтиво по таким изменениям с ходу фиг найдёшь... Потому что это просто разные методы, метод click ака эмулирует реальный клик рукой/пальцем ;-) , он более универсален (им же и сабмитить можно), его можно прицепить к множеству элементов (у того же IE, например), в общем, click всегда был сам по себе, а submit и проч. сами по себе. Я бы резюмировал так: Метод, типа "эмулирующий" левый клик. Не равнозначен этому клику. Стандартен (w3c), но только для инпутов с определёнными атрибутами, в разных браузерах исторически был реализован по-разному, как с точки зрения элементов, к которым применим, так и с точки зрения всего остального: взаимодействия с обработчиками и проч. событиями, и т.д. и т.п. Осюда - жди сюрпризов...
p.s. почему браузеры самостоятельно выходят из потенциального infinite loop объяснить не могу, сюрррпрыз. Это сообщение отредактировал(а) Zeroglif - 5.6.2007, 12:22 |
||||||
|
|||||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 49 Всего: 401 |
Zeroglif, огромное спасибо!
Т.е. строгой системы нет, все определяется исторически сложившимися обстоятельствами? Если уж submit() и reset() по этой части оказались полными антиподами, хотя, казалось бы, сами события - явные "близнецы" (по "всплываемости", "отменяемости" и т.п.)... Выходит, это скорее submit() по части (не-)запуска обработчика стоит особняком... кстати, везде ли это так или тут тоже "возможны варианты"? P.S. Отдельное спасибо за последнюю ссылку - не понимаю, как я сам вчера не приметил в ней слона в самом первом абзаце... -------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| Zeroglif |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Откуда взяться строгой системе для методов/свойств на хосте, если разные движки умудряются местами даже единый стандарт (ECMAScript) по-своему интерпретировать? Уверенности про все браузеры нет, я бы сказал, что нельзя полагаться на то, что submit() плюс onsubmit обязательно не наложатся друг на друга (если есть необходимость иметь их обоих, то при submit() лучше бы временно заглушить обработчик). |
|||
|
||||
| AKS |
|
||||
|
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
SelenIT, вот решил продолжить вашу "славную традицию по мозгодробильным опытам":
Итак, какие тут есть "варианты". 1. Событие, как видно из примера, можно прервать. Но если для FF и Opera раскоментить preventDefault, то никакого эффекта не будет. Вывод - "древний" метод click() требует к себе соответствующего отношения (использовать местами запрещенный cancelBubble). 2. Если событие не прерывать (в условии заменить 1 на 0), и кликнуть по боксу в FF, то имя тэга будет написано аж ШЕСТЬ раз. В IE/Opera лишь дважды. 3. В FF метод click() симулируя событие на боксе не делает его мишенью события - чтобы в этом убедиться, нужно кликнуть по документу и будет распечатано трижды (если событие не прервано) или дважды HTML. В IE/Opera клик по документу возвращает HTML Input (Input). Наверняка есть и еще какие-нибудь причуды, но я пока больше не нашел. ;) |
||||
|
|||||
![]()
|
| Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | JavaScript: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |