Вопрос собственно очень короткий и простой - почему некорректно работает событие 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.

Какой аналог вы можете посоветовать? Я уже пробовал менять классы в листах стилей, но тогда начинают артачиться все остальные браузеры или это более правильный путь и стоит дальше упирать на него?
И как тогда объяснить, что при использовании свойств innerText и innerHTML на том сайте, который я пишу, всё работает, но не сразу?

Я бы сделал с помощью классов. Вообще, почитайте какой-нибудь учебник, а то написанный код явно выдаёт, что вы не очень понимаете что и для чего пишите.

Я не верю, что в span появляется слово «Текст», если код действительно такой, как приведён выше.

оно (слово) действительно появляется и в таком варианте и если обращаться к элементу напрямую (что я обычно и делал, пока не поставил себе firebug, который порекомендовал использовать функцию get).
Пойду работать с помощью листов. Жаль что данный браузер такой капризный и не использует весьма полезных свойств.
С точки зрения ООП данный код скрипта совершенно корректный. Я получаю объект, а потом использую его свойства и методы через имя, которое присвоил полученному объекту. Сомнения вы можете развеять поместив код в тектовый редактор и сохранив его с соответствующие расширением, а затем открыв во всех имеющихся браузерах.

Beregost
Лучше выложите страничку на какой-нибудь хостинг, что б все желающие могли посмотреть.
Сохранять код мне лень.

Сказали же, 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 - не есть гуд.

У меня таких блоков всего два. В вашем браузере приведённый пример не работает (это конешно же так, ведь иначе я бы и не спрашивал), но работает в других, которые я перечислил выше. Но самое смешное - тот сайт, который я спроектировал работает со свойствами 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>

На счёт идентификатора открытого элемента - то есть нужно, чтобы запоминался текущий открытый элемент?
То есть есть несколько блоков, и одновременно должен быть открыт только один, а все другие - закрыты?

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>

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

Второй вариант не работает, зато прекрасно сработал первый. Значения style.class не определяются, как собственно не определяется значение атрибута class. Вообще class похоже является служебным словом в JavaScript.
Теперь во всех браузерах всё отображается одинаково и работает одинаково эффективно.
Этот случай помог мне добавить в код порядка и красоты, а также исправить несколько мелких ошибок в разметке. Всем спасибо.

Beregost
Вообще-то, что бы поменять класс у элемента, нужно изменять element.className

Прочитайте уже учебник

Обязательно, когда у меня будет время. Уже начал. Обычно время у меня есть по дороге с работы домой и наоборот. Так что пока мне приходится всё получать урывками и результат этого вы уже видели (плачевный).
Собственно и вам спасибо за подсказку на тему как обращаться к классам. Помогло и всё работает ещё лучше, т.к. разметка стала более гибкой.

Ещё один интересующий меня вопрос: как избавиться от белых рамочек, которые возникают вокруг ссылок в вашем браузере?

Добавьте для ссылок стиль

Выделить код

Код:

outline: none;

Точно не помню, но, вроде, так.

Отличный код.
У мну вопрос. как его довести до того, что бы слои скрывались а показывался только один?

aroma
Текст на ссылках также менять надо?

stoneflash пишет:

aroma
Текст на ссылках также менять надо?

Представляется, что решением указанной проблемы является активное использование CSS. Именно в этом направлении развиваются все браузеры. Вместо div и span используются block  и inline. А обработка кликов в этом случае сводится к модификации свойств видимости.

Текст то я поменяю, а вот яву не зашарю.

Вместо div и span используются block  и inline.

Что-то не понял. Первое - теги, второе - свойства. А к чему применять block и inline?

Текст то я поменяю, а вот яву не зашарю.

Вот это я тоже не понял.
:)

stoneflash пишет:

Вместо 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 тут мало на что влиять будут.

stoneflash пишет:

однако при многослойных структурах - возникает проблема.

Вы про перехват\просачивание события? event.stopPropagation(); event.cancelBubble = true; ...

Да и вообще для решения задачи скрытия\раскрытия блоков, какая была описана выше, не стоит думать сильно о DOM, узлах и прочем.
Это решаемо основами JS, и различия в поддержках DOM Events тут мало на что влиять будут.

Согласен, что управление каскадированием можно решить чисто средствами JS, но использование DOM, DOM Events и CSS (display Property и visibility Property) резко сокращает объем кода.

Можно посмотреть, как вы бы реализовали первый код из сообщения?

Мужики, может кто-нибудь написать код на основе этого скрипта....
Кнопка1 Кнопка2, Слой1 Слой2. Нажимаю Кнопка1 показывается Слой1, нажимаю Кнопка2, Слой1 исчезает, а на его месте появляется Слой2 и так далее... Это трудно? Если очень, то не надо. Если можно, буду благодарен.

Я и так использую в разметке и при решении задачи раскрывающегося меню листы стилей с двумя классами - hide и show.

stoneflash пишет:

Добавьте для ссылок стиль
Код:

outline: none;
Точно не помню, но, вроде, так.

спасибо, помогло. Вообще почитав про FF я очень им заинтересовался, ведь он придерживается нормативов, а это значит что следует стремится к тому, чтобы именно в FF всё работало хорошо (тогда я освою именно нормативы и стандарты, что гораздо важнее пропроитарных игрищ). Инструменты, которыми я могу дополнить данный браузер очень помогают мне в процессе разработки и это тоже несомненный плюс.
Теперь начались сложности с Оперой. Там браузер при повторных щелчках по ссылка так и норовит выделить текст ссылки, а мне этого не нужно.

Кстати, решил вопрос с количеством функций - решение оказалось тривиальным, даже удивляюсь как не дошёл до этого сразу. Просто использую теперь одну функцию с переменными, где переменной является id элемента. В итоге у меня одна короткая функция, которая работает правильно где угодно.
Также начались проблемы с Safari от Apple. Они заключаются в кодировке содержимого страницы. Даже не смотря на мета тег:
<meta http-equiv="content-type" content="text/html; charset=windows-1251">
этот браузер упорно отказывается понимать в какой кодировке его следует сразу выводить содержимое :(.

Вопрос оказался актуальным и пришлось сесть за написание кода, хотя этим мне
приходиться заниматься крайне редко. Я не ставил перед собой цель получить
универсальный код обработки кликов для любого браузера. Приведенные коды
следует считать концептуальным подходом, как направление для дальнейших исследований.
Решая эту задачу с использованием DOM, пришлось столкнуться с тем, что IE и эти
стандарты игнорирует (как и многие другие).
Вот эти коды: 
<html>
    <head>
        <title>Пример кода, который прекрасно работает в FF</title>
        <link rel="stylesheet" type="text/css" href="ex.css"/>
    </head>
    <body>
           <script  language="JavaScript" type="text/javascript">
                function oneclick(elem)
                {   
                    var x1=elem.parentNode.childNodes;
                    alert('идет обработка узла '+x1.item(3).textContent);
                    if (elem.textContent=='+')
                        {elem.textContent='-'
                        x1.item(4).className='cl';
                        x1.item(5).className='op';
                        }
                    else
                        {elem.textContent='+'
                        x1.item(5).className='cl';
                        x1.item(4).className='op';
                        }
                    } 
        </script>        
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел1</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел2</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел3</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел4</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
    </body>
</html>

*******************************
<html>
    <head>
        <title>Пример кода, который прекрасно работает в IE</title>
        <link rel="stylesheet" type="text/css" href="ex.css"/>
    </head>
    <body>
           <script  language="JavaScript" type="text/javascript">
                function oneclick(elem)
                {
                    var x1=elem.parentNode.childNodes;
           
                    alert('идет обработка узла '+x1[2].innerHTML);
       
                    if (elem.innerHTML=='+')
                        {elem.innerHTML='-'
                        x1.item(3).className='cl';
                        x1.item(4).className='op';
                        }
                    else
                        {elem.innerHTML='+'
                        x1.item(4).className='cl';
                        x1.item(3).className='op';
                        }
                    } 
        </script>        
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел1</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел2</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел3</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
        <div> <span class="ind" onclick="oneclick(this)">+</span> <span >узел4</span><span class='op'>закрыт</span><span class='cl'>открыт</span></div>
    </body>
</html>
**код для файла ex.cpp
        span {margin-left:3pt;
        }

        .ind {    cursor:pointer;
        }

        .op {display:inline;
        }

        .cl {display:none;
        }
    ******
однако, эти решения связаны с однослойными задачами, что значительно проще
многослойных. Попробуйте организовать обработку кликов в такой
структуре (именно к ним относились мои ранние сентенции)
<div onclick="oneclick(this)"> узел1
  <div onclick="oneclick(this)"> узел1.1
    <div onclick="oneclick(this)"> узел1.1.1 </div>
    <div onclick="oneclick(this)"> узел1.1.2 </div>
   </div>
  <div onclick="oneclick(this)"> узел1.2
    <div onclick="oneclick(this)"> узел1.2.1 </div>
    <div onclick="oneclick(this)"> узел1.2.2 </div>
   </div>
</div>   
Для проведения экспериментов достаточно при щелчке изменить цвет контента
соответствующего div-а и только одного.
Удачи всем на WEB-дорогах!

piontr
А если добавить ещё один элемент?
И вообще не понятно, что этот код делает. Сначала видим три элемента, потом - два, третий пропадает куда-то.
Какую задачу пытались решить?

stoneflash пишет:

piontr
А если добавить ещё один элемент?
И вообще не понятно, что этот код делает. Сначала видим три элемента, потом - два, третий пропадает куда-то.
Какую задачу пытались решить?

Это практически Ваша задача с использованием функции
function showHide(id,textWhenHidden,textWhenVisible)
1.Вместо того, чтобы создавать неоднородность за счет использования id (представьте, что эти структуры генерируются на фазе исполнения, где контролировать id практически невозможно.
2.В исходной задаче сочетание <p> и следующего за ним <span>, мягко выражаясь, не вполне корректно, так как  <span> всегда окажется на новой строке после </p>.Поэтому в задаче эти структуры заменены на div, с вложением нескольких spam-ов. 
3. Задача которая рассмотрена в примерах может быть сформулирована следующим образом:
Написать код, который работает со структурами, подобными пунктам меню. При этом фиксировать, какой пункт выбран (сообщение alert с контентом этого элемента (не id)) и что с этим пунктом происходит (открыт - закрыт с одновременным изменением + на -).

1.Вместо того, чтобы создавать неоднородность за счет использования id (представьте, что эти структуры генерируются на фазе исполнения, где контролировать id практически невозможно.

Хм. Что за ситуация такая?

2.В исходной задаче сочетание <p> и следующего за ним <span>, мягко выражаясь, не вполне корректно, так как  <span> всегда окажется на новой строке после </p>.Поэтому в задаче эти структуры заменены на div, с вложением нескольких spam-ов.

Можно просто заменить название тега на любой другой inline.

Написать код, который работает со структурами, подобными пунктам меню. При этом фиксировать, какой пункт выбран (сообщение alert с контентом этого элемента (не id)) и что с этим пунктом происходит (открыт - закрыт с одновременным изменением + на -).

А кто сказал ссылка открытия\скрытия блоков должна быть в одном контейнере с самим блоком? В вашем примере получается жёсткая привязка. Как только выносим блок из основного меню - код перестаёт работать, так как уже у блоков не один родитель.

зы.
Какой-то странный спорчик вышел :) Непонятно, что решаем и к чему прийти должны :)