Вопрос собственно очень короткий и простой - почему некорректно работает событие onclick? В написанном мной сайте создаётся ощущение будто вашему браузеру требуется предварительная активация, потому что при первом щелчке по импровизированной кнопке в виде текста в дескрипторах span событию уделяется ровно ноль внимания. Далее события отрабатывается корректно. Если на страничке присутствует несколько кнопок, то каждую приходится активировать таким вот убогим способом.
Во многих браузерах сайт работает корректно (safari, opera, IE, мой любимый Chrome). В такой ситуации я могу просто забить на ваш, т.к. мне вообще не нужно чтобы сайт корректно работал в вашем браузере. Я не специалист по разработке WEB, просто это моё хобби, но в душе я перфекционист и это мешает мне пройти мимо данной проблемы стороной.
В конце концов я накактал тупейшую тестовую страничку и вот что получилось:
<html> <head> <title>Тестируем событие onclick</title> <script language="JavaScript"> function click_test() { element=document.getElementById("test"); alert("Здравствуй Мир!!!"); } </script> </head> <body> <p id="test" name="test" onclick="click_test()">+</p><span id="test2" name="test2"></span> </body> </html>
В этом варианте всё работает на 5+.
А потом я решил протестировать то, что собственно меня интересовало больше всего: раскрывающиеся меню.
<html> <head> <title>Тестируем событие onclick</title> <script language="JavaScript"> function click_test() { element=document.getElementById("test"); element2=document.getElementById("test2"); if(element.innerText=="+") { element.innerText="-"; element2.innerText="Текст"; } else { element.innerText="+"; element2.innerText=""; } } </script> </head> <body> <p id="test" name="test" onclick="click_test()">+</p><span id="test2" name="test2"></span> </body> </html>
в таком виде в вашем браузере страничка вообще мертва. В других, названных мной выше браузерах, всё работает как надо.
Вопрос простой: чего я делаю неправильно?
Отсутствует
Ну, вообще-то onclick работает правильно.
Просто innerText это нестандартное свойство, которого нет в FF.
Isn't it ironic... don't you think? — Alanis Morissette
Отсутствует
Какой аналог вы можете посоветовать? Я уже пробовал менять классы в листах стилей, но тогда начинают артачиться все остальные браузеры или это более правильный путь и стоит дальше упирать на него?
И как тогда объяснить, что при использовании свойств innerText и innerHTML на том сайте, который я пишу, всё работает, но не сразу?
Отредактировано Beregost (02-02-2009 20:53:53)
Отсутствует
Я бы сделал с помощью классов. Вообще, почитайте какой-нибудь учебник, а то написанный код явно выдаёт, что вы не очень понимаете что и для чего пишите.
Я не верю, что в span появляется слово «Текст», если код действительно такой, как приведён выше.
Isn't it ironic... don't you think? — Alanis Morissette
Отсутствует
оно (слово) действительно появляется и в таком варианте и если обращаться к элементу напрямую (что я обычно и делал, пока не поставил себе firebug, который порекомендовал использовать функцию get).
Пойду работать с помощью листов. Жаль что данный браузер такой капризный и не использует весьма полезных свойств.
С точки зрения ООП данный код скрипта совершенно корректный. Я получаю объект, а потом использую его свойства и методы через имя, которое присвоил полученному объекту. Сомнения вы можете развеять поместив код в тектовый редактор и сохранив его с соответствующие расширением, а затем открыв во всех имеющихся браузерах.
Отредактировано Beregost (02-02-2009 21:07:56)
Отсутствует
Beregost
Лучше выложите страничку на какой-нибудь хостинг, что б все желающие могли посмотреть.
Сохранять код мне лень.
Isn't it ironic... don't you think? — Alanis Morissette
Отсутствует
Сказали же, innerText - не поддерживается.
<html> <head> <title>Тестируем событие onclick</title> <script language="JavaScript"> function click_test() { element=document.getElementById("test"); element2=document.getElementById("test2"); if(element.innerHTML=="+") { element.innerHTML="-"; element2.innerHTML="Текст"; } else { element.innerHTML="+"; element2.innerHTML=""; } } </script> </head> <body> <p id="test" name="test" onclick="click_test()">+</p><span id="test2" name="test2"></span> </body> </html>
А вообще - да, лучше сделать через классы. Или просто element.style.display='none' На таком примере ещё и можно так сделать, но если у Вас несколько таких блоков, то всё их содержимое хранить в Javascript - не есть гуд.
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
У меня таких блоков всего два. В вашем браузере приведённый пример не работает (это конешно же так, ведь иначе я бы и не спрашивал), но работает в других, которые я перечислил выше. Но самое смешное - тот сайт, который я спроектировал работает со свойствами innerText и innerHTML в FF, но только после "активации", процесс которой я описал выше - чем это может быть вызвано?
Сейчас с моими не очень богатыми знаниями в области WEB интерфейсов в голове есть только один вариант:
определять открыт элемент или нет по значению атрибута class (ранее я специально добавлял скрытый текст "+" в страничку, чтобы определять открыт элемент или закрыт - возможно это дико, но иного пути я пока не нашел). При применении классов весь текст элемента будет находиться в разметке, а не в скрипте, но при увеличении количества таких элементов будет расти код скрипта, что не очень хорошо. Мне было бы интересно найти решение самому, тем более, что на полке давно пылится хорошая книга по JavaScript, но вот насчёт идентификатора открытого элемента я бы с удовольствием выслушал вас.
Отсутствует
Вариант с display:none
<html> <head> <title>Тестируем событие onclick</title> <script language="JavaScript"> function click_test() { element=document.getElementById("test"); element2=document.getElementById("test2"); if(element2.style.display=='none') { element.innerHTML="-"; element2.style.display=""; } else { element.innerHTML="+"; element2.style.display="none"; } } </script> </head> <body> <p id="test" name="test" onclick="click_test()">+</p> <span id="test2" name="test2" style="display:none">Тут какой-то текст</span> </body> </html>
Вариант с классами:
<html> <head> <title>Тестируем событие onclick</title> <style type="text/css"> .visibleClass {display:;} .hiddenClass {display:none} </style> <script language="JavaScript"> function click_test() { element=document.getElementById("test"); element2=document.getElementById("test2"); if(element2.className=='hiddenClass') { element.innerHTML="-"; element2.className="visibleClass"; } else { element.innerHTML="+"; element2.className="hiddenClass"; } } </script> </head> <body> <p id="test" name="test" onclick="click_test()">+</p> <span id="test2" name="test2" class='hiddenClass'>Тут какой-то текст</span> </body> </html>
На счёт идентификатора открытого элемента - то есть нужно, чтобы запоминался текущий открытый элемент?
То есть есть несколько блоков, и одновременно должен быть открыт только один, а все другие - закрыты?
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
stoneflash
спасибо
На счёт идентификатора открытого элемента - то есть нужно, чтобы запоминался текущий открытый элемент?
То есть есть несколько блоков, и одновременно должен быть открыт только один, а все другие - закрыты?
мне нужно создать неограниченное число открывающихся и закрывающихся блоков и при этом не допустить увеличения текста скрипта. Кстати в одной из книжек я прочитал, что Мазила, на основе которой сделан FF поддерживает свойство innerHTML.
Отсутствует
<html> <head> <title>Тестируем событие onclick</title> <script language="JavaScript"> function showHide(id,textWhenHidden,textWhenVisible) { element=document.getElementById("link"+id); element2=document.getElementById("text"+id); if(element2.style.display=='none') { element.innerHTML=textWhenVisible; element2.style.display=""; } else { element.innerHTML=textWhenHidden; element2.style.display="none"; } } </script> </head> <body> <p id="link1" onclick="showHide(1,'Показать блок 1','Скрыть блок 1')">Показать блок 1</p> <span id="text1" style="display:none">Тут какой-то текст 1</span> <p id="link2" onclick="showHide(2,'Показать блок 2','Скрыть блок 2')">Показать блок 2</p> <span id="text2" style="display:none">Тут какой-то текст 2</span> <p id="link3" onclick="showHide(3,'Показать блок 3','Скрыть блок 3')">Показать блок 3</p> <span id="text3" style="display:none">Тут какой-то текст 3</span> <p id="link4" onclick="showHide(4,'Показать блок 4','Скрыть блок 3')">Показать блок 4</p> <span id="text4" style="display:none">Тут какой-то текст 4</span> </body> </html>
Ну как-нибудь так тогда сделать. В функцию передаём номер управляемого блока, текст ссылки, когда блок скрыт и текст, когда блок отображается.
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
Второй вариант не работает, зато прекрасно сработал первый. Значения style.class не определяются, как собственно не определяется значение атрибута class. Вообще class похоже является служебным словом в JavaScript.
Теперь во всех браузерах всё отображается одинаково и работает одинаково эффективно.
Этот случай помог мне добавить в код порядка и красоты, а также исправить несколько мелких ошибок в разметке. Всем спасибо.
Отсутствует
Beregost
Вообще-то, что бы поменять класс у элемента, нужно изменять element.className
Прочитайте уже учебник
Isn't it ironic... don't you think? — Alanis Morissette
Отсутствует
Обязательно, когда у меня будет время. Уже начал. Обычно время у меня есть по дороге с работы домой и наоборот. Так что пока мне приходится всё получать урывками и результат этого вы уже видели (плачевный).
Собственно и вам спасибо за подсказку на тему как обращаться к классам. Помогло и всё работает ещё лучше, т.к. разметка стала более гибкой.
Отредактировано Beregost (03-02-2009 15:43:38)
Отсутствует
Добавьте для ссылок стиль
Точно не помню, но, вроде, так.
Отредактировано stoneflash (03-02-2009 17:42:14)
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
aroma
Текст на ссылках также менять надо?
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
aroma
Текст на ссылках также менять надо?
Представляется, что решением указанной проблемы является активное использование CSS. Именно в этом направлении развиваются все браузеры. Вместо div и span используются block и inline. А обработка кликов в этом случае сводится к модификации свойств видимости.
Отсутствует
Вместо div и span используются block и inline.
Что-то не понял. Первое - теги, второе - свойства. А к чему применять block и inline?
Текст то я поменяю, а вот яву не зашарю.
Вот это я тоже не понял.
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
Вместо div и span используются block и inline.
Что-то не понял. Первое - теги, второе - свойства. А к чему применять block и inline?
Текст то я поменяю, а вот яву не зашарю.
Вот это я тоже не понял.
В решении этих вопросов надо исходить из позиции стандартов W3. XML Events показывает, что все реакции на события при их обработке должны проходить от корня дерева - документа к целевому узлу, для которого, собственно, и предназначен клик. Т.е. на один клик мыши откликнутся все узлы, которые "видны из под данного" в указанном порядке. Майкрософт пошел своим путем (по непроверенным данным в восьмой версии ИЕ будет поддерживаться стандартная модель). В IE событие просачивается от целевого узла (который лежит на поверхности) к корню документа. Когда отображается только один уровень объектов, реагирующих на клик - эта разница незаметна, однако при многослойных структурах - возникает проблема. Какие есть решения для многослойных структур?
1. Делать перехват распространения клика с учетом существования двух моделей обработки событий (по моим данным - только IE поддерживает вторую модель)-именно так мне приходилось делать
2. Опираться на спецификацию XML Events комитета W3. Но это возможно только при появлении соответствующих реализаций. В FF обозначены эти механизмы (явные следы обнаружены в проекте XFORMS, но мне еще не удалось это использовать (см. мой вопрос об XML и клике на этом форуме в декабре 2008). Удачи.
PS. По поводу block и inline: В своей работе я уже давно разделил содержание и представление. Стараюсь не использовать div и span. Использую XML. Отсюда и ссылка на block и inline. Такой подход соответствует направленности стандартов комитета W3.
Отсутствует
однако при многослойных структурах - возникает проблема.
Вы про перехват\просачивание события? event.stopPropagation(); event.cancelBubble = true; ...
Да и вообще для решения задачи скрытия\раскрытия блоков, какая была описана выше, не стоит думать сильно о DOM, узлах и прочем.
Это решаемо основами JS, и различия в поддержках DOM Events тут мало на что влиять будут.
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует
однако при многослойных структурах - возникает проблема.
Вы про перехват\просачивание события? event.stopPropagation(); event.cancelBubble = true; ...
Да и вообще для решения задачи скрытия\раскрытия блоков, какая была описана выше, не стоит думать сильно о DOM, узлах и прочем.
Это решаемо основами JS, и различия в поддержках DOM Events тут мало на что влиять будут.
Согласен, что управление каскадированием можно решить чисто средствами JS, но использование DOM, DOM Events и CSS (display Property и visibility Property) резко сокращает объем кода.
Отсутствует
Можно посмотреть, как вы бы реализовали первый код из сообщения?
«I actually hate programming, but I love solving problems» © Rasmus Lerdorf, PHP's Creator
Отсутствует