обработчик событий для всех объектов input (text)

 
0
 
JavaScript
ava
Forza | 01.12.2004, 16:12
Привет!

Ранее я умел вызывать обработчики событий прямо из тэга, а сейчас понадобилось вызывать одинаковые обработчики onfocus и onblur для всех элементов input type=text текущего документа. Каждому в тэг пихать названия функций не хочется, пытаюсь "зарегистрировать" обработчики для этих событий как-то по-хитрому. Пока не получается.
Рассмотрим упрощённый вариант:
<HTML><HEAD></HEAD>
<BODY>
<FORM><INPUT TYPE=text NAME=input1>
<INPUT TYPE=text NAME=input2></FORM>
</BODY></HTML>

Предположим, что по onfocus в текстовое поле должно записываться имя этого текстового поля, а по onblur оно должно стираться.
Kommentare (13)
ava
Се ля ви | 01.12.2004, 17:30 #
начиная с JavaScript 1.1 можно присваивать обработчики как свойства. В твоём случае удобно будет написать так:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
   <form id="forma">
       <input type="text" name="input1">
       <input type="text" name="input2">
   </form>
</body>
</html>



var x = document.body.getElementById('forma').getElementsByTatName('input');
for (var i = 0; i < x.length;){
   x[i].onfocus = function(){ alert('Фокус'); }
   x[i++].onblur = function(){ alert('Фокус'); }

   // Думаю, сработает даже более хитрый вариант, но не уверен:
   // x[i++].onblur = x[i].onfocus = function(){ alert('Фокус'); }
}


P.S. Пиши под стандарт XHTML хотя бы 1.0, а то такой старинный код глаза режет... Приобщишся к XML`у заодно)
ava
Forza | 01.12.2004, 17:45 #
Се ля ви, а ты в браузере свой код проверял? У меня, например, он совсем не сработал.
Кроме этого никак не могу понять смысл в x[i++].
Да и вообще текстовых полей на самом деле очень много, поэтому присваивать по 2 обработчика каждому из них в цикле ИМХО не есть рационально. Может, лучше повесить один обоработчик на форму, а в нём смотреть источник события?
ava
Sardar | 01.12.2004, 21:52 #
Цитата (Forza @ 1.12.2004, 16:45)
Да и вообще текстовых полей на самом деле очень много, поэтому присваивать по 2 обработчика каждому из них в цикле ИМХО не есть рационально. Может, лучше повесить один обоработчик на форму, а в нём смотреть источник события?

Не верный ход мыслей ;-) Можно написать одну функцию, которую регистрируешь для всех элементов.

HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<form name="forma">
<input type="text" name="input1">
<input type="text" name="input2">
</form>
</body>
</html>

function onfocus_els() {this.value=this.name;}
function onblur_els() {this.value="";}
var els=document.forms.forma.elements;
for(var i=0; i<=els.length; i++) {
els[i].onfocus=onfocus_els;
els[i].onblur=onblur_els;
}


Писал отдельные функции для принципа, что бы подтвердить слова выше. Если создаватьфункцию на месте, то у каждого элемента будет свой обьект функция, что не страшно и потребление памяти не увеличивает ;-)
var els=document.forms.forma.elements;
for(var i=0; i<=els.length; i++) {
els[i].onfocus=function() {this.value=this.name;};
els[i].onblur=function() {this.value="";};
}

ava
Се ля ви | 02.12.2004, 00:47 #
Цитата (Forza @ 1.12.2004, 17:45)
смысл в x[i++].

смысл в том, что ты обращаешься к i-тому элементу массива x, а после этого увеличиваешь i на единицу. Это называется "постфиксая инкрементация". Ещё бывает префиксная - ++i - изменение перед возвратом. То же самое с декрементацией: --i - уменьшает на единицу перед возвратом, а i-- - после возврата.

Не проверял - хотя был уверен, что сработает. Странно...
Но Sardar лучше предложил - перебирать коллекцию elements удобнее, я о ней как-то забыл совсем. Хотя я бы тогда, если тебе нужно присваивать события исключительно текстовым input`ам, делал проверку на принадлежность к оным:

var els=document.forms['forma'].elements;
for(var i=0; i<=els.length; i++) {
if (els[i].tagName != 'input' && els[i].getAttribute('type') != 'input') continue;
els[i].onfocus=function() {this.value=this.name;};
els[i].onblur=function() {this.value="";};
}

В этом варианте, как видишь, приходится обойтись без красивого приёма
els[i++].onblur=function() {this.value="";};
- а записать инкремент в заголовок цикла, что бы оператор continue тоже увеличивал счётчик.
ava
Forza | 02.12.2004, 10:28 #
Цитата (Sardar @ 1.12.2004, 21:52)
Не верный ход мыслей  Можно написать одну функцию, которую регистрируешь для всех элементов.

Дело в том, что здесь на форуме я видел пример, когда обработчик события был один раз прописан для таблицы, а потом в нём разбиралось, какая TD-ячейка его вызвала, и далее была работа именно с этой ячейкой. Вот я на основе этого и пытался прописать обработчик форме или всему документу, а в нём уже определять источник события.

Цитата
смысл в том, что ты обращаешься к i-тому элементу массива x, а после этого увеличиваешь i на единицу. Это называется "постфиксая инкрементация". Ещё бывает префиксная - ++i - изменение перед возвратом. То же самое с декрементацией: --i - уменьшает на единицу перед возвратом, а i-- - после возврата.

Да-да! Я конкретно ступил тогда! Просто привык сам ставить i++ в заголовок цикла, а когда ты написал инкремент в теле, я спутал его с i+1. smile=54 А почему ты считаешь инкремент счётчика в теле цикла "красивым приёмом"? smile

Спасибо всем ответившим! Всё работает!
ava
Forza | 02.12.2004, 12:17 #
Итак, всё заработало как надо. Только одно "но". Броузер в строке состояния пишет "Выполнено, но с ошибками на странице" - ругается по поводу строки "els[i].onfocus=onfocus_els;" следующим образом: "els[...]" - есть null или не является объектом.
Хотя повторю, что все события обрабатываются правильно.
Код с назначением обработчиков для каждого объекта располагаю внутри <BODY> после описания <FORM>.
ava
Forza | 02.12.2004, 14:14 #
Из-за чего может быть это "липовое" сообщение об ошибке от ИЕ? Т.е. он ругается, но всё делает правильно.
А то восклицательный знак на жёлтом треугольнике в строке состояния выглядит как-то несолидно. :hmmm
ava
Се ля ви | 02.12.2004, 14:36 #
Цитата (Forza @ 2.12.2004, 10:28)
А почему ты считаешь инкремент счётчика в теле цикла "красивым приёмом"?

Ну просто по соображениям удобства smile Может быть, это уже мои профессиональные "выкрутасы", проявления того, что называется искусством кодирования. Просто в теле у меня полюбому всстречается i, так почему бы не заинкрементировать его уже прямо там, вместо того, что бы писать отдельный i++ в заголовке цикла? Так просто более крато и ёмко получается.


Цитата (Forza @ 2.12.2004, 12:17)
Броузер в строке состояния пишет "Выполнено, но с ошибками на странице" - ругается по поводу строки "els[i].onfocus=onfocus_els;" следующим образом: "els[...]" - есть null или не является объектом.

Sardar был немножечко не прав, а я у него скопировал, не проверив - там в строчке
Цитата
for(var i=0; i<=els.length; i++) {

не должно быть знака "<=", замени его на просто "<", как у меня было изначально - просто последний элемент массива - это именно элемент с номером length - 1, а не length - потому что нумерация начинается с 0, а length - это количесто элементов, которое, соответственно, на 1 больше smile
Поэтому элемент els[els.length] - не существует, вот он и не может к нему обратиться и выдаёт ошибку.
ava
Forza | 02.12.2004, 14:42 #
Цитата
Ну просто по соображениям удобства smile Может быть, это уже мои профессиональные "выкрутасы", проявления того, что называется искусством кодирования. Просто в теле у меня полюбому всстречается i, так почему бы не заинкрементировать его уже прямо там, вместо того, что бы писать отдельный i++ в заголовке цикла? Так просто более крато и ёмко получается.


На мой взгляд, это всё-таки менее удобно. Цикл for на то и был сделан имхо, чтобы вся служебная инфа о его функционировании была вынесена в заголовок - смотришь, и сразу видишь логику работы цикла. К тому же если тело цикла большое, и счётчик там встречается много раз, то каждый раз надо проверять: а поставил ли я ему где-то инкремент? а не поставил ли их несколько? smile
А в JavaScript нет аналога перловского foreach $i (0..els.length-1)? Он вообще снимает вопросы о месте инкремента в цикле. smile
ava
Се ля ви | 02.12.2004, 18:29 #
Цитата (Forza @ 2.12.2004, 14:42)
На мой взгляд, это всё-таки менее удобно. Цикл for на то и был сделан имхо, чтобы вся служебная инфа о его функционировании была вынесена в заголовок - смотришь, и сразу видишь логику работы цикла.

Дело вкуса, сам понимаешь :-)

Цитата (Forza @ 2.12.2004, 14:42)
К тому же если тело цикла большое, и счётчик там встречается много раз, то каждый раз надо проверять: а поставил ли я ему где-то инкремент? а не поставил ли их несколько?

Для больших циклов будет не удобно, согласен. Но я и не стремлюсь к универсализму - маленьким ёмкимм циклам - одни подходы, большим громоздким - другие. Всё определяется подзадачами...


Цитата (Forza @ 2.12.2004, 14:42)
А в JavaScript нет аналога перловского foreach $i (0..els.length-1)? Он вообще снимает вопросы о месте инкремента в цикле.

Нету... Их только совсем недавно в Java сделали (в JDK 1.5) а JS по-большому счёту за Java плетётся, так что года через 2-3, думаю, будет в ходу этот приём, но не сейчас...
ava
Sardar | 03.12.2004, 01:03 #
Цитата
Sardar был немножечко не прав, а я у него скопировал, не проверив - там в строчке

Звиняюсь, "промазал" поклавише... ;-)
Цитата
Их только совсем недавно в Java сделали (в JDK 1.5) а JS по-большому счёту за Java плетётся, так что года через 2-3, думаю, будет в ходу этот приём, но не сейчас...

Когда же народ перестанет путать JS и Java, это совсем разные языки, не по применению, они вообще по смыслу другие! Никогда JS за Java не шёл, просто когда то был связан с Java, ну а имя по историческим причинам. Хотя если кому нравится думать что JS это Ява, то это его право... может у него даже получится программить... ;-)
ava
Се ля ви | 03.12.2004, 05:58 #
Цитата (Sardar @ 3.12.2004, 01:03)
Когда же народ перестанет путать JS и Java

Ты не так понял. Я не путаю их, ни в коем случае. Просто куча приёмов было позаимствовано у неё и заимствовалось по мере появляния... А при том, что JavaScript несмотря на обилие документации, по большому счёту плохо документирована, изучая Java я то и дело сталкиваался с различными приёмами и думал - а сработает ли это в JavaScript? И обычно срабатывало...

А по сути у них действительно много общего - оба используют виртуальную машну со сборщиком мусора, у них примерно похожий синтаксис - правда сильно отличаются реализация ООП (здесь она основана на прототипах, а не на классах - это не упрощённая, а просто другая модель) и событий (хотя в нетскейпе вроде бы какое-то время назад для некоторых событий нужно было специально включать слушателей - наследие Java, от которого ушёл JScript), немного - обработка ошибок (по сути, она просто тоже не ОО, а реализована на основе события onError, хотя блоки try..catch сохранились), но это уже специфика языков-сценариев для веб-интерфейсов.

Т.е. я предлагаю считать, что JavaScript - это упрощённая, сильно переработанная и приспособленная для сценариев Java, т.е. именно Сценарная Java, что отражено в её названии - JavaScript. По крайней мере с этим подходом мне было легче в своё время изучать оба этих языка, сравнивая и находя между ними общие черты и отличия, когда изучение одного могло подтолкнуть изучение другого, а другого - изучение первого...

Вообще можно тему открыть, где подробно сравнить эти 2 языка. Моя позиция такая - авторы JavaScript преследовали 2 цели: создание языка, похожего на Java, и при этом приспособленного для сценариев на HTML-страницах. Понятно, что Server-Side JavaScript не выдержит никакой конкуренции с J2EE - её создание было просто вызвано тем, чтобы уже существующим JS-кодерам дать возможность с минимальным переучиванием писать серверные несложные скрипты.

По большому счёту JavaScript слишком специфичен, что бы можно было его называть ещё одной платформой Java - отличий от J2SE у него гораздо больше, чем разница между J2EE и J2ME. Хотя бы синтаксических. Тем не менее, насколько это позволяла специфическая среда, в которой выполняется JavaScript-код, авторы постарались сохранить всё что было в Java и им это в значительной мере удалось... Та же как VisualBasic.NET похож на VBScript и Visual Basic for Applications, хотя между ними имеются значительные различия...

Цитата (Sardar @ 3.12.2004, 01:03)
Хотя если кому нравится думать что JS это Ява, то это его право... может у него даже получится программить...

Надо просто чётко представлять различия, которых имхо всё-таки меньше, чем сходства. smile
später ergänzt:
а про плетётся я имел ввиду блок try..catch - он был ведён значительно позже, чем в Java, и я в одной радостной статье про эту вещь как раз читал - мол такая удобная штука в Java была, наконец-то и в JavaScript её реализовали) Вобщем вывод напрашивается - сложность программ растёт значительно быстрее, чем сложность скриптов, поэтому для скриптовых язков вполне естественно при усложнении заимствовать что-то у старших коллег, помня при этом, что они не совсем коллеги - т.е. надо не забывать о специфике применения...
ava
Sardar | 03.12.2004, 10:44 #
Цитата
Тем не менее, насколько это позволяла специфическая среда, в которой выполняется JavaScript-код, авторы постарались сохранить всё что было в Java и им это в значительной мере удалось...

А конкретно что они сохранили? ;-)

У JS схожий синтаксис с Java, впрочем это же можно сказать и о C++. Но не только синтаксис определяет язык, а больше сходства нет. Ни в чём ;-)
Начнём с того что нет библиотек классов. Я пишу как на JS так и на Java. Когда пишу на Java я перестраиваюсь не этот язык, я проектирую будущую прогу в типах/классах, как будто прога это большая общага каждый тянет за верёвочку и всё начинает двигатся smile
В JS нет понятие типа как Ява, есть только два типа: примитив и обьект. Всё это обьекты, функции это тоже обьекты, как и любой друго обьект может быть созданна во время исполнения скрипта. Интерфейс любого обьекта можно изменить как угодно, потому понятие интерфейса(безопасного типа) нет. Это кстати негативная, но гибкая сторона JS.
Модель событий другая, реализованна не на листенерах. У каждого обьекта есть некоторые события, которые он может бросить. В старой(традиционной) модели у каждого обьекта было свойство в котором лежит обьект-функция, JS окружение вызывает эту функцию как метод обьекта(this указывает на обьект) если наступило событие. В новой модели от W3C используются списки обработчиков событий, всё остальное то же самое.
Цитата
а про плетётся я имел ввиду блок try..catch - он был ведён значительно позже, чем в Java, и я в одной радостной статье про эту вещь как раз читал - мол такая удобная штука в Java была, наконец-то и в JavaScript её реализовали)

Нетскейповцы много чего упустили, вообще изначально чисто их JS был просто ужасен. Взгляни еще на обьекты String и Array, что лишнее у первого и чего не хватает у второго ;-)
Try/catch появились впервые в JScript, потом были реализованны и в JS1.5, но не нетскейповцами, к счастью криворукие перестали существовать. Не путать Мозиллоподобных(Gecko движок) и NN4!

В целом JS был придуман изменять свойства сущестувующих обьектов, это потом уже был додуман DOM, новая модель событий и т.д. JS был призван работать в среде с паралелльным исполнением. потому в нём нет глупых sleep и подобных. У JS большое сходство с Python, но не с Java ;-)
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden