Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > JavaScript: Общие вопросы > Добавление обработчика события |
Автор: 12345c 21.12.2006, 22:14 | ||||
Известно, что есть функция добавления обработчика к фиксированнному событию, например, к onload. Смысл её такой, что если в обработчике обнаруживается function, то он переопределяется как новая функция, составленная из последовательности двух. С такой функцией добавления нет проблем, она работает. Но понадобился добавитель к переменному обработчику. Проблемы началисть с того, что передать объект-обработчик как параметр не получилось - передаётся почему-то не объект, а его копия (потому что внутри функции присваивание работает, а по окончании значение объекта-обработчика остаётся старым. Вот пример неработающего кода, но не будем на нём долго останавливаться:
Кто предложит решение? (до версии Опера 8.53)) Чтобы присвоить переменному обработчику новую функцию, но не применять function в eval? И вообще, почему не присвоилась функция в первом случае и можно ли сделать красИвее? Дополнение: Получилось решение, оставляю задачку для тренировки умов, она несложная, из серии "не в лоб, так по лбу" ![]() ...А Опера 9.0 с отрисовкой заметно помедленнела. Интересно, исправят ли, или это дань продвинутости? |
Автор: 12345c 22.12.2006, 00:17 |
Получается, что eval+имя - единственно верное направление. |
Автор: Nicholas_S 22.12.2006, 00:18 | ||
12345c, постановка задачи ясна. Единственное, у меня твой второй пример не работает ни в 8, ни в 9ой версиях Оперы. Есть одно решение, насколько оно тебя удовлетворит не знаю, но работает и в 8ой, и в 9ой Опере. За оптимальность не отвечаю, предлагаю только ход мыслей:
Что неудобно, так это указание самого имени функции, к которой добавляем новую. Может быть сделаешь удобнее. |
Автор: Zeroglif 22.12.2006, 00:31 |
Зачем eval, если известно событие и его имя передаётся аргументом? |
Автор: 12345c 22.12.2006, 02:34 |
Да, можно addEventListener. Только покрасивее со сцеплением функций не придумывается. Nicholas_S, я примерно так решил (функция в строке), только без прототипа, потому что получается тавтология с именами. (И важно, чтобы параметр у функции был.) Или придётся брать String.prototype.addFunc , чтобы не повторяться. |
Автор: Sardar 22.12.2006, 04:26 | ||||
Что то жуткое читаю и не врубаюсь в смысл слов... правильно ли я понял, что ты думал аргументы передаются по указателю (изменяемые)? Тогда вообще не понятно, в каждом учебнике же лежит, что всё передаётся (даже примитивы, помним что они immutable) по ссылке, присваивание которой просто изменяет ссылку, а не обьект, на который она ссылалась. Так и в Java и в C#... языки поддерживающие указатели по пальцам можно пересчитать (PHP, C/C++, ...? ) Термин указатель == ссылка, '=' оператор для которой определён как изменяющий значение обьекта, на который ссылка указывает (разыменование). Сишные указатели в сторону ![]() В современных языках только примитивы ещё могут по ссылке изменяться, и то не всегда. Для остальных типов меняется именно значение самой ссылки, а не обьект на который она указывает Кстати вызов toString() на closure выложит его исходник, естественно контекст заменяется на тот, что в eval'е (от window/global). Что ты вообще хотел этим сделать не пойму... Интересно кому в наше время ещё нужны традиционные события... А если не извращаться, то будет так:
P.S. код отвратителен по читабельности, неужели нельзя давать нормальные имена и разбивать по строкам? попытка "закодировать" тривиальный код не одно и тоже с попыткой написать код гениальный, но мало кому понятный ![]() Добавлено @ 04:33 Zeroglif, больше такого никому не говори ![]() Если желаешь поспорить, то в начале в личку, флейм тут не нужен. А зачем тебе нужна возможность изменять "по указателю"? Ведь можно без лишнего сексу передать обьект и мя поля, благо всё в JS (да и в любом другом ECMA) навигируеться так (глобальные помним через window[name], по стандарту global[name]). Nicholas_S, зачем доставать код closure/функции? Вдруг она привязана контекстом к какому нибудь окружению, а обратив всё в текст мы теряем контекст, т.е. теряем вообще смысл и мощь closure. P.S. парни, я понимаю что праздники, но харе столько пить! ![]() |
Автор: Nicholas_S 22.12.2006, 14:48 |
Sardar, была сразу мысль сделать через addHandler(), но глядя на пример ушел в другую сторону. Насчет контекста полностью согласен. |
Автор: 12345c 22.12.2006, 15:02 |
Я не думал, но надо было как-то передать указатель на обработчик события. Ничего, кроме имён, не получилось. Вариант с аттачами событий увеличивает число параметров, как видно. Не большая, конечно, беда... Про closure я думал, но непонятно, как его использовать. В общем, пока пользуюсь своим кодом (буду применять в соседней, ещё не созданной теме ![]() Стиль письма - дело привычки. Мне, например "{", стоящие отдельно на строке, мешают. А по опросу, этот стиль даже более предпочтителен в обиходе, чем они же, прилепленные к оператору. |
Автор: Sardar 22.12.2006, 18:30 |
createDispatcher() в примере как работают closure. Там создаёться в контексте вызова переменная handlers, которая будет своей для каждого диспетчера. closure вообще вещь мощная. Это по сути некий код, привязываемый к разному контексту. Сам же контекст может содержать ссылки на что угодно. Язык разрабатыва(л)(ю) (теорию только), для эффективности разделил концепцию closure на именнованные блоки и собственно closure. Вышло удобно ![]() |
Автор: Zeroglif 22.12.2006, 20:00 |
12345c, Возможно тебе пригодится http://barney.gonzaga.edu/%7Eamoore1/php/addEvent/ регистрации событий через свойства объекта. Просто ещё один самобытный пример. |
Автор: Sardar 22.12.2006, 20:46 | ||
Кстати в этой теме сразу видим, как в JS (любом скриптовом языке) не хватает getters/setters (которые реализованы в JS от мозиллы, а также в Rhino в Java6... да вообще везде, кроме JScript в ИЕ). А перегрузка операторов вообще была бы супер, представь как в C#:
P.S. впрочем JS как язык вообще довольно сильно отстаёт от "современных течений" ![]() |