| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > JavaScript: Общие вопросы > hover элементов формы на javascript |
| Автор: GZep 3.11.2006, 15:08 | ||
| Приветствую Вас! Вот, значит, какая проблема: Есть движок, у которого все элементы формы при наведении должны менять класс(css), а при убирании курсора, соответственно наоборот. Вот, значит, как у меня сейчас сделано:
Только вот проблема, в ИЕ такая фишка не проходит... Придумал решение: Написать яваскрипт ф-цию, которая циклом прохожилась по всем элементам форм и ставит им на onrollover соответствующий класс и обратно, на onrollout. Пробовал сам написать, только не работает. Помогите, пожалуйста! |
| Автор: Nicholas_S 3.11.2006, 15:39 | ||
GZep, если с использованием JS, то так:
|
| Автор: GZep 3.11.2006, 15:47 |
| А можно написать функцию, которая проходилась бы циклом по элементам и задавала им onMouseOver и onMouseOver? |
| Автор: SelenIT 3.11.2006, 16:03 | ||||
GZep, не надо ничего обходить циклом - ловите событие (при его всплытии) на уровне самой формы, и анализируйте объект-источник. В простейшем случае (как в данном примере, когда стили у кнопок и полей при наведении меняются одинаково) - примерно так:
|
| Автор: GZep 3.11.2006, 16:07 |
| Спасибо, но меня все-таки интересует вариант с циклом... |
| Автор: SelenIT 3.11.2006, 16:17 |
| GZep, да что Вы на этом цикле зациклились-то, простите за каламбур? Насколько я могу судить, делать это циклом сейчас "не модно и не современно". |
| Автор: Nicholas_S 3.11.2006, 16:18 | ||
GZep, ноу проблема:
|
| Автор: SelenIT 3.11.2006, 16:23 |
| Или так, только при этом для каждого элемента создается по паре экземпляров функции-обработчика, а можно было бы обойтись одной функцией на все события... |
| Автор: GZep 3.11.2006, 16:35 |
| Nicholas_S, то, что нужно! Спасибо! Прошу извинить меня за настырность с этим циклом. Мне правда неловко! Всем Спасибо. Сейчас напишу универсальную ф-цию и выложу её для народа... |
| Автор: Nicholas_S 3.11.2006, 17:24 |
| SelenIT, ...нужно! Добавлено @ 17:25 ...блин, почему у меня кешируется все и не обновляется, ниче не пойму... |
| Автор: AKS 3.11.2006, 18:02 | ||||||
SelenIT,
Прямо в "яблочко", как говорится! ;) Что ж, поделюсь с Вами своими "впечатлениями" по теме, т.к. автора темы, похоже, Вам "спасти" не удалось... ;) Чуть-чуть переделал Ваш пример, ведь судя по таблице стилей, нужно на самом деле совсем немного (по "вашим следам" - легче топать ;) ):
Вызов:
|
| Автор: SelenIT 3.11.2006, 18:21 |
| AKS, здорово. Только я бы постраховался и проверил n на существование... И еще очень хочется навесить вызовы из скрипта же, не трогая HTML - к сожалению, этому я еще не научился, может быть, поможете? В принципе, в данном конкретном случае кроссбраузерность не нужна (в других браузерах CSS справляется сам), так что можно и не передавать событие при вызове, тогда весь JS легко выносится из HTML (и оформляется в виде .htc, к примеру). Но интересно динамическое навешивание обработчиков в общем случае, когда ссылка на event обязательна... |
| Автор: 12345c 3.11.2006, 19:06 | ||
А что мешает делать так?
Можно сделать и через behavior-стиль для IE: http://js2.ru/example/JsPrimeryCode-84.htm (пример - таблица) Т.е. вопрос к автору темы - зачем стремиться к циклам, если без них работает? |
| Автор: AKS 3.11.2006, 19:07 | ||||||
SelenIT,
Так ведь в функцию передается первым параметром ссылка на объект Event.
Зачем?
|
| Автор: SelenIT 3.11.2006, 19:21 |
| 12345c, насколько я понял, автору нужно подсвечивать только один элемент, а не группу. Поэтому вариант с контейнером, по-моему, мимо. А вот behavior - по-моему, самое то. AKS, с проверкой действительно я перемудрил - мне казалось, что при отсутствии класса у элемента n останется undefined, не подумал, что оно преобразуется в пустую строку... |
| Автор: AKS 3.11.2006, 19:21 | ||
SelenIT, вот, собрал из "домашних заготовок", для данного случая (пусть у формы будет id='forma'):
|
| Автор: SelenIT 3.11.2006, 19:26 |
| AKS, большое спасибо! Опять этот "Коля" (callee)... видно, пришла пора мне познакомиться с ним поближе, в XXI веке без него никак |
| Автор: AKS 3.11.2006, 19:38 |
| SelenIT, "Колей" Zeroglif "ласково" называет caller'а - вызывающий объект, короче сказать, то самое, куда в функции укажет this. А здесь у нас http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Functions:arguments:callee - указатель на текущую функцию (удобная штучка ;) ). |
| Автор: SelenIT 3.11.2006, 19:43 |
| Мда, вот как у меня, оказывается, все запущено - такие базовые вещи путаю... буду срочно исправляться! |
| Автор: AKS 3.11.2006, 19:45 | ||
SelenIT, arguments.callee незаменим в анонимных функциях. Вот пример, только что взял у "себя" с Xpoint (можно было бы так функцию f "присобачить"):
Добавлено @ 19:50 SelenIT, что-то я глянул "со стороны" на фразу "взял у себя" - нехорошо! Основная идея в этом примере (obj.method || obj.another_method)() - от Zeroglif! |
| Автор: SelenIT 3.11.2006, 19:51 |
| AKS, мощно, внушает Выходит, именно этой arguments.callee мне последнее время и не хватало. А я-то все пытался какими-то обходными маневрами this переназначить... |
| Автор: AKS 3.11.2006, 19:57 |
| SelenIT, не-е-е, this не переназначить ни "обходными маневрами", ни какими другими - он "упрямый". Так что берегите время, оставьте его в покое ;) ... |
| Автор: GZep 4.11.2006, 18:30 | ||
| Значит так... Сразу скажу, что от цикла я отказывать не буду.(без цикла у меня уже есть давно пример кода) А вот, что у меня получилось нахимичить с циклом(не смейтесь тока
Меня интересует цикл for ( ; ; ), точнее то, почему он "не пашет" |
| Автор: SelenIT 4.11.2006, 19:09 |
А в Tools -> Advanced -> Error console ничего при этом не пишется? |
| Автор: GZep 4.11.2006, 19:40 |
| Вот что пишет: Event thread: load Error: name: TypeError message: Statement on line 85: Could not convert undefined or null to object Backtrace: Line 85 of inline#1 script in http://localhost/text.php if (content_form_elements[i].type == "checkbox" || content_form_elements[i].type == "radio") Line 28 of inline#2 script in http://localhost/text.php HoverFormElements(); At unknown location [statement source code not available] |
| Автор: SelenIT 4.11.2006, 19:54 |
| GZep, а что такое HoverFormElements() и откуда оно взялось? |
| Автор: AKS 4.11.2006, 20:16 | ||
Я попробовал убрать кое-что из кода и проверил - вроде бы работает. Может так:
|
| Автор: GZep 4.11.2006, 20:56 | ||||
Это у меня так ф-ция называется. Перед тем, как выложить разметку, я естественно покорректировал её(убрал то, что не в тему). HoverFormElements() { = onload.function() { Добавлено @ 20:58
немогли бы Вы код с комментариями дать. |
| Автор: AKS 4.11.2006, 21:04 | ||
GZep,
Я бы с удовольствием, только я не знаю, что комментировать - ведь это же ваш код, просто я убрал несколько строк, показавшихся мне лишними. Напишите, что именно Вас интересует? |
| Автор: SelenIT 4.11.2006, 21:12 |
| GZep, у Вас переменная content_form_elements (и не только она), была глобальной, поэтому влиять на работу кода могло даже то, "что не в тему" (и, судя по сообщению Оперы, как раз влияло)... |
| Автор: GZep 4.11.2006, 21:19 | ||||
| Ура! Сделал! Огромное спасибо AKS'у за идею простого "лечения" цикла for( ; ; ). Финальный вариант предпологает то, что в тегах форм не надо указывать ни стиль, ни действия, только то, что они input'ы.
яваскрипт задает стандартные стили элементов форм, стили при наведении мыши, стили при убирании мыши. Он replace я отказался, потому что, вроде, проще просто поменять имя стиля без замен, ведь мы и так его знаем(поправьте, если не так) Только textarea палки в колеса всемирного прогресса вставляет, ведь он не инпут.... А можно написать <input type="textarea"??? Добавлено @ 21:23
SelenIT, я - просто обожаю префиксы, ну, и немножко пространство имен. Конфликтов имен у меня никогда еще не было, ни в пхп, ни в яваскрипте... |
| Автор: AKS 4.11.2006, 21:41 | ||
Писать-то можно, только толку никакого. ;) А для textarea тогда уж можно отдельно задать обработчик ("раз пошла такая пьянка" ;) - т.е. раз уж Вы выбрали именно такой "тернистый" путь...). |
| Автор: GZep 4.11.2006, 21:49 |
| А по-моему, путь просто отличный... Можно написать эту функцию, стили и все остальное забыть...все само будет делвться и в ИЕ 6-7 будет работать. |
| Автор: GZep 4.11.2006, 22:21 |
| Народ, а как склеить массивы в javascript??? нигде найти не могу... |
| Автор: 12345c 5.11.2006, 00:45 |
http://javascript.aho.ru/files/js/ArrayJS.html#concat |
| Автор: GZep 5.11.2006, 11:12 |
| content_form_elements = document.getElementsByTagName('input').concat(document.getElementsByTagName('textarea')); Не работает! getElementsByTagName() почему-то возвращает массив, где последний элемент имеет значени null(по-моему). Из-за этого не работал цикл for(i=0; i<content_form_elements[i]; i++) {, а пришлось вместо него писать for(i=0; content_form_elements[i]; i++) {. Поправьте, пожалуйста, строчку с concat. |
| Автор: AKS 5.11.2006, 14:43 |
| GZep, нельзя применить concat к коллекциям DOM - нет у коллекций этого метода в "распоряжении". |
| Автор: GZep 5.11.2006, 14:50 |
| А как тогда склеить можно? Могу это сделать при помощи цикла, но хотелось бы покрасивее сделать... |
| Автор: SelenIT 5.11.2006, 15:27 |
| GZep, по-моему, самый красивый вариант показал AKS http://forum.vingrad.ru/index.php?showtopic=119613&view=findpost&p=911009 - вообще никаких циклов, компактно и кроссбраузерно... |
| Автор: GZep 5.11.2006, 17:45 |
| А мне больше нравится, когда в начеле скрипт поставил, и все, больше ничего делать не надо. Вот только скрипт этот еще надо select и taxtarea понимать научить. Что я щас, собственно говоря, и делаю. |
| Автор: SelenIT 5.11.2006, 18:04 |
| GZep, а есть существенная разница, какой скрипт "в начале поставить и больше ничего не делать" - с циклами или без? |
| Автор: GZep 5.11.2006, 19:09 |
| SelenIT, а, ну да, тот же тоже можно в начале поставить и ничего не делать, кроме назначения форме id |
| Автор: GZep 7.11.2006, 12:03 | ||
| Значит так... С циклами ничего конкретного не получилось и я на них "забил". Прошу извинить меня за то, что игнорировал советы умных людей отказать от циклов. Надо было послушаться и не терять даром время. Что я имею на данный момент: 1-ое. В браузерах Opera и FireFOX прекрасно можно обойтись без javascript при помощи CSS, и все будет работать "как нельзя лучше". Остается решить проблему с всеми "любимым" Internet Explorer. 2-ое. Все-таки я признаю, что "отнимать" у тегов атрибуты типа class и id - не совсем верно...хотя скорее - совсем не верно. 3-тье. Код CSS(решает проблему в опере и мозиле):
4-ое. У всех "кпопкоподобных" присвоен класс input_button, для всего остального input_field. 5-ое. Чекбоксы и радио "батоны" в этой теме рассматривать вообще не стоит. 6-ое. Остается решить проблему с ИЕ. Вот тут я хотел спросить: может поставить обработчики на яваскрипте только, если браузер ИЕ(вообще всю ф-цию запихнуть в "тело условия"? |
| Автор: AKS 7.11.2006, 12:41 | ||
GZep,
Так и сделайте! Скачайте http://www.xs4all.nl/~peterned/csshover.html и подключайте через behavior... |
| Автор: GZep 7.11.2006, 13:01 | ||
Одно понятно - идея правильная.
Что это вообще такое? И я вообще заблудился на том сайте |
| Автор: AKS 7.11.2006, 13:18 |
GZep,
|
| Автор: GZep 7.11.2006, 13:57 |
| Ну а как это работает Вы мне объяснить можите? По-моему там много лишнего...регулярное выражение вот краем глаза вижу...Что это за проект? Это проект, который направлен конкретно на hover элементов формы в ИЕ? Или чтоб вообще сделать hover полнофункциональным. Не скудитесь, пожалуйста, на слова. Хочется же не просто сделать, а еще и понять, что сделал. |
| Автор: AKS 7.11.2006, 14:26 | ||
GZep,
Этот сценарий позволяет эмулировать поведение псевдоклассов :hover и :focus в IE для всех элементов, к которым они применены в таблице стилей. Конечно же для вашего случая там много лишнего - сценарий для вашей формы может быть лаконичней (что я мог предложить, я уже предлагал). |
| Автор: GZep 7.11.2006, 16:30 | ||
AKS, вот Ваш пример, только немного переделал(сделал более читабельным), но суть не изменил. Чуть не забыл: я его в тело условия запихнул, которое проверяет тип браузера.
|
| Автор: AKS 7.11.2006, 17:34 | ||||||
GZep,
Можно:
Потом в форме:
И не пытайтесь добавить к имени стилевого класса строку ":hover". У Вас должен быть дополнительный класс .hover, имя которого и будет добавляться (удаляться) к уже имеющимся именам классов элементов формы. |
| Автор: GZep 7.11.2006, 18:12 |
| Ну а как сделать чтоб только в ИЕ эта функция выполнялась? Воткнуть её в тело условия, а для других браузеров сделать эту функцию пустой? или как? И зачем форме id присваивать в этом примере? Он ведь не нужен... |
| Автор: AKS 7.11.2006, 18:30 | ||||
GZep,
А она и будет только в IE выполняться (сделайте первое условие пожестче против Opera if(el && !window.opera), а то я забыл).
Вы написали, а я повторил... |
| Автор: GZep 8.11.2006, 12:12 | ||||||
| Финальный вариант. CSS
JavaScript Для Windows Internet Explorer и Microsoft Internet Explorer
HTML резметка
AKS, поправь, пожалуйста, если что-то не так сделал. Добавлено: Теперь javascript функция будет выполняться только в Internet Explorer. В других браузерах эта функция вообще ни разу вызываться не будет. Это немного ускоряет работу скрипта, ведь раньше все браузеры вызывали функцию и прекращали ее выполнять когда натыкались на условие в ней. Теперь подсветка в браузерах отличных от ИЕ будет выполняться исключительно при помощи css. И теперь не надо писать: <form onmouseover="HoverForm(event)" onmouseout="HoverForm(event)">, теперь надо просто: <form> |
| Автор: GZep 21.11.2006, 15:40 |
| Народ, прокомментируйте, пожалуйста, если есть какие-либо замечания... |
| Автор: 12345c 21.11.2006, 16:49 | ||||
Модифицирую приведённый пример, чтобы показать другой способ достижения того же:
Файл JsPrimeryCode-43.htc :
|
| Автор: GZep 21.11.2006, 18:27 |
| 12345c, так прокомментируйте вариант раз Вы его выложили. Расскажите как он работает, его достоинства и недостатки. Вот я не пойму зачем вообще в подобных вещах пользоваться replace. Это ведь функция, для работы с текстом. Разве не быстрее просто менять имя класса? Кроме того я заметил одну такую особенность в поведении javascript: при изменении класса с помощью javascript изменяются все параметры. Например, вы создали класс, где указан цвет фона и цвет рамки, а потом поменяли ява скриптом этот класс на другой, где указан только цвет фона. Так что же? Вы думаете что цвет фона поменяется, а цвет рамки останется от предыдущего класса? Ничего подобного! Цвет рамки в таком случае поменяется на стандартный, установленный в настройках браузера. Поэтому в своем примере я сделал так, что javascript вообще не меняет имя класса, а просто заменяет цвета, без css, сам. Это я так, к теме сказал... |
| Автор: GZep 22.11.2006, 14:13 | ||||
Я это прекрасно понял. Я это писал не к Вашему примеру, а просто рассказал особенность поведения javascript, по скольку это уместно в данной теме. Ну, не все же такие профи Кстати, по вашему примеру то, что я говорил про особенность javascript все-таки относится, вроде. Вот посмотрите:
Этот отрезал из вашего кода. Сдесь при включении input_button:hover(это произойдет в опере и мозиле) все будет нормально, например параметр font останется от класса input_field,.input_button, где он был задан. А вот в ИЕ, где замену класса будет выполнять javascript не будет наследоваться параметры. То есть font станет стандартным, браузерным. В своем примере я это исправил примитивным, но надежным путем, я просто не менял класс, а задал параметры, которые надо поменять вручную, без css. Вот так ваш вариант будет работать правильно в ИЕ:
Вот так вот. Ваше мнение...??? |
| Автор: Zeroglif 22.11.2006, 15:16 | ||||||
Совершенно не поняли. Яваскрипт не при чём, сложно ожидать от замены имени класса какого-то там наследования.
Откуда такой вывод про IE и Javascript? Есть же живая ссылка на пример, разве вы не видите, что у элементов форм при наведении меняется фон, а шрифт остаётся тот же? Замена класса может быть прописана в стиле, естесственно предыдущий класс будет "забит" последующим, это обычное поведение для стилей, явакскрипт, бедный, ни при чём. Автор скрипта тоже не меняет класс, он добавляет класс, разные вещи же:
против
Выше много классов, они могут перекрывать друг друга (если свойства сопадают, это по сути замена одного класса на другой), а могут дополнять. Если вам нужно при наведении только изменить цвет фона, то вы добавляете (а не удаляете/заменяете предыдущий) новый класс отдельно для фона, а потом убираете его (метод replace, привет). Если же вы заменяете один класс на другой, то само собой вам приходится полностью переносить все свойства (а их может быть ой-ой-ой сколько) в новый класс. Вам оно надо? |
| Автор: GZep 22.11.2006, 15:58 | ||
Это разве не изменение:
Я имею ввиду, что при использовании метода или свойства или как там это в яваскрипте наз-ся, короче при изменении className никакого наследования не происходит, элемент просто забывает про предыдущий класс и к нему присваивается новый. Свойства не заменяются при совпадении, они просто становятся стандартными, кроме тех, что указаны в новом классе. Это я, кстати, на практике видел... |
| Автор: Zeroglif 22.11.2006, 16:34 | ||||
Это изменение, присваивается другое имя, но вот это
уже дополнение, к одному имени справа встанет другое (обратите внимание на пробел в строке), соответственно, сначала элементу наведут красоту из old_name, а потом найдут ниже new_name и наведут красоту, взяв свойства уже из него.
Не в яваскрипте дело, этого не может быть, потому что не может быть... |
| Автор: 12345c 22.11.2006, 16:35 |
Ещё раз (3-й) опишу то, что Вы в упор не видите.
Добавлено @ 16:37 (Пост был к GZep.) Добавлено @ 16:45 (Ещё понятно было бы, если без примера, а тут пример работает. "Давайте спорить о вкусе устриц с теми, кто их ел", а о неправильной работе примера - с теми, кто его видел.) |
| Автор: GZep 22.11.2006, 18:45 | ||||||
Все, я понял. До меня дошло, когда Вы сказали про пробел.
А чтобы понять рекурсию, надо понять рекурсию.(цитата Nastya) Зачем обижать меня? Я просто не знал что в css можно свойства через пробел задавать. Вот от сюда и пошло все...
4 раза прочитал, ничего не понял из смысла фразы, на пятый "ура". Наверное, переутомился сегодня. |
| Автор: GZep 22.11.2006, 19:08 | ||
А вот еще вопросик:
Ну, вопрос, собственно, в коде. |
| Автор: SelenIT 22.11.2006, 19:18 |
| Возвращаясь к предыдущему вопросу, хочу сказать слово в поддержку GZepа - хоть на этот раз его опасения оказались заблуждением и тревога, к счастью, оказалась ложной, но дыма без огня не бывает - я тоже припоминал какие-то проблемы с применением нескольких классов в IE. Так и оказалось: у IE есть аж две проблемы - со стилями вида http://www.quirksmode.org/bugreports/archives/2004/12/IE_CSS_rendering_bug_with_multiple_classnames.html и http://www.quirksmode.org/bugreports/archives/2005/09/IE6_Multi_Class_Bug.html. К счастью, оба варианта (особенно первый) достаточно экзотичны и не имеют ничего общего с данным случаем, но я считаю, что "лучше перебдить чем недобдить" и настороженность не была безосновательной! |
| Автор: GZep 22.11.2006, 19:25 |
Все видели? Вот так вот! Кстати в вашем варианте заметил небольшой глюк, что ли или как его там лучше назвать... Суть "глюка": При наведении мышкой начинает намного страницу "колбасить", например, рамка вокруг флеш ролика(она в 7 версии ИЕ есть) начинает подмигивать глючно. Начало сильно раздражать, вернул код на вариант, который я выложил и назвал финальным - все супер. Ведь хоть и мой вариант сложнее редактировать под себя, но, согласитесь работать он должен чуточку быстрее. |
| Автор: GZep 23.11.2006, 14:05 |
| Из-за глюка, описанного в моем предыдущем посте, я советую использовать все-таки http://forum.vingrad.ru/index.php?showtopic=119613&view=findpost&p=915424. Потому что он вполне корректно работает и теперь он еще меньше будет задействовать системных ресурсов на браузерах отличных от ИЕ. |