Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Автоматический выбор уровней в мультиселект-списке. / Подсветка и выделение строк таблиц.


 javascript.aho.ru Javascript в браузерах: разработка, документация, примеры. Выпуск # 8, 2006-06-06
краткое содержание

Автоматический выбор уровней в мультиселект-списке. / Подсветка и выделение строк таблиц.

(1) Автоматизация выбора группы опций в структурированном мультиселект-списке из двух и более уровней. Как разработать пользовательский интерфейс. (2) Подсветка строк таблицы при наведении и выделение строки таблицы при клике вместе с чекбоксом на ней. Строка таблицы "выделить всё".
Существует дней: 47
Автор: 12345c
Другие выпуски:
Рассылка 'Упражнения по яванскому письму. Javascript.'
 
Статья
4.06.06

Много-  уровневый мульти-  селект.
 Часть 2.

Получить автоматическое выделение группы элементов в теге "select". Задача возникла из-за того, что он есть поле ввода, наиболее подходящее для изображения структуры. Другие конструкции - не поля ввода (списки, тексты документа или таблицы), и для отправки выбранной подструктуры через форму потребовались бы дополнительные действия. При решении увидим, что отображение структуры в списке <select> - тоже непростая задача в силу ограничений функциональности тега.

Примеры и статья наиболее полезны для программистов, так как показывает ход решения и разработку интерфейса нетривиальной задачи, хотя пользователи могут скопировать и применять полученный код. Некоторые трудности переписывания скрипта возникнут, если пользователь захочет изменить способ выделения уровней, к виду которого привязана программа.

Вернёмся к постановке задачи, потому что упоминание её в прежнем выпуске было конспективным, и, возможно, не всеми осознана её цель и полезность.

Что такое мультиселект? Это HTML-конструкция тегов вида:

<select multiple size=3>
  <option>1</option>
  <option>2</option>
  <option>3</option>
  <option>4</option>
</select>

Ключевое слово здесь - multiple, оно позволяет изменять число выделений строк от 0 до максимума, а помогает в выделении служебная клавиша Ctrl. При её удержании кликом по строке option выделяем или снимаем выделение для любой строки. Клавиша shift тоже участвует в операциях выделения, ускоряя процесс - при удержании её клик выделяет или снимает выделение сразу у группы строк option.

Всё это работает в HTML без скриптов и устраивает, пока имеем дело со списком, а не структурой. Более того, визуальное отображение двухуровневой структуры имеется в HTML (тег optgroup). Не более, чем визуальное. Клик по строке названия группы ни к чему не приводит - ни в выделениях, ни программно. Представим, что захотели мы улучшить управление структурой, отображённой в списке select специальными выделениями - символами, создающими отступы. И поставили задачу, чтобы, кликнув по названию подсписка, выделили подсписок.

Повторю примеры того, где автовыделение подуровней структуры было бы полезно. Это разветвлённые системы подфорумов, группы подписок на рассылки (список реализован у конкретного подписчика в виде структуры с чекбоксами) или многочисленные строки выбора в анкетах.

Двухуровневый список с выделением подуровней по клику на узле
<select multiple size=6  onchange="fh(this)">
  <option>1. Раздел 1</option>
  <option>--1.1 Пункт 1</option>
  <option>--1.2 Пункт 2</option>
  <option>2 Раздел 2</option>
  <option>3 Раздел 3</option>
  <option>--3.1 Пункт 1 Раздела 3</option>
  <option>--3.2 Пункт 2 Раздела 3</option>
</select>
<script>
ff=function(t){ //групповое выделение опций в списке выбора
    var i=t.selectedIndex;
    if(t.options[i].text.indexOf('--')>=0)return;
    while(i<t.options.length-1
        &&t.options[++i].text.indexOf('--')>=0)
        t.options[i].selected=!0;}
</script>

Для 3 и более уровней:

<select size="8" multiple onchange="ff(this)">
<option>1.Раздел 1</option>
<option>∙ 1.1.Пункт1</option>
<option>2.Раздел 2 </option>
<option>∙ 2.1.Пункт1 (р.2)</option>
<option>∙ ∙ 2.1.1.Подпункт1 (п. 1 р.2)</option>
<option>∙ ∙ 2.1.2.Подпункт2 (п. 1 р.2)</option>
<option>∙ 2.2.Пункт2 (р.2)</option>
<option>∙ ∙ 2.2.1.Подпункт2 (п. 2 р.2)</option>
</select>
<script>
c="∙ ";  //признак уровня структуры
ff=function(t){ //групповое выделение опций в списке выбора
  var i;
  alert(t.selectedIndex)
  sel=t.options[i=t.selectedIndex].selected;
  j=t.options[i].text.lastIndexOf(c);i++;
  while(i<t.options.length  //если не конец
    &&t.options[i].text.lastIndexOf(c)>j //и не тот же уров.
    ){t.options[i++].selected=sel;}}
</script>

Работающие скрипты примеров смотрите на странице приложения к статье.

С программирования таких эффектов начинается самое интересное. Выполнить выделение группы можем довольно легко, как в примерах. Но чтобы научить снимать выделение, нужен другой подход. Если с указанным скриптом попробуем работать, удерживая клавишу Ctrl, она начнёт срабатывать не всегда, интуитивная понятность её использования нарушится. Клавишу shift тоже следует обрабатывать по-особому - если с ней выполним выделение нескольких заголовков уровней, то все уровни под заголовками должны быть выделены, или наоборот, выделение снято.

Общая цель этих сложных преобразований простая - сделать интуитивно понятным пользование кнопками выделения в многоуровневых списках. Если выделили строку описания группы строк - выделилась вся группа. Если сняли выделение - снялось выделение всей группы.

Следует учесть, что есть группы, выделение которых без выделения подгруппы не имеет смысла (пустые узлы структуры, типа тега optgroup), а есть те, которые могут существовать отдельно. И тогда, если кликом на них выделяем всю подгруппу, то должен существовать способ выделения только одного заголовка. Очевидно, единственный способ остаётся - нажатие с Ctrl.

В результате, чтобы решить задачу, сначала необходимо разработать пользовательский интерфейс - написать правила, выполнение которых мы хотим видеть в скрипте. Получаем правила управления:

  1. клик по узлу - выделение всех младших узлов и элементов;
  2. Ctrl-клик по узлу - снятие/установка выделения только узла, если узел - непустой (представляет собой элемент структуры) и снятие/установка всех младших узлов и элементов, если узел пустой;
  3. клик по полностью выделенному узлу - снятие всех младших узлов и элементов;
  4. Ctrl-клик по элементу - обычное действие снятия или выделения
  5. клик по элементу - обычное действие выделения только этого элемента. Вариант - выделение только Одного элемента в списке его уровня и младших, не затрагивая соседних и старших.
  6. shift+клик по элементу или узлу - выполнение тех же действий, что и для Ctrl, для всех изменившихся элементов и узлов с приоритетом для старших.

Так как статья - учебная, а не информационная, давайте посмотрим, какими способами такие задачи решаются. Имеем: неподходящее поведение скрипта. Задача: разобраться, что в нём происходит.

Кроме того, что можно пользоваться отладчиками Javascript, отладочный скрипт мы сами можем легко написать. Требуется узнать, что происходит при разных событиях мыши на элементе select. Пишем функции, выводящие нужную информацию под исследуемым списком.

Отладочный пример с мониторингом нажатий.
<select size=8 multiple onchange=fch(this)
  onmousedown=fd(this); onclick=fc(this)>
<option>1.Раздел 1</option>
<option onmousedown=alert(0)>∙ 1.1.Пункт1</option>
<option>2.Раздел 2 </option>
<option>∙ 2.1.Пункт1 (р.2)</option>
<option>∙ ∙ 2.1.1.Подпункт1 (п. 1 р.2)</option>
<option>∙ ∙ 2.1.2.Подпункт2 (п. 1 р.2)</option>
<option>∙ 2.2.Пункт2 (р.2)</option>
<option>∙ ∙ 2.2.1.Подпункт2 (п. 2 р.2)</option>
</select>
<script>
onload=function(){ida0=document.getElementById('a0');}
  c="∙ ";  //признак уровня структуры
fd=function(t){  i0=t.selectedIndex;
  ida0.innerHTML+='down:'+i0+'; '
    +(i0>=0?t.options[i0].selected:'not_mdown')+';<br>';
}
fch=function(t){ //групповое выделение опций в списке выбора
  i0=t.selectedIndex;
  ida0.innerHTML+='change:'+i0+'; '
    +(i0>=0?t.options[i0].selected:'not_change')+';<br>';
/*  j=t.options[i].text.lastIndexOf(c);i++;
  while(i<t.options.length  //если не конец
    &&t.options[i].text.lastIndexOf(c)>j //и не тот же уров.
    ){t.options[i++].selected=sel;}*/
}
fc=function(t){  i0=t.selectedIndex;
  ida0.innerHTML+='click:'+i0+'; '
    +(i0>=0?t.options[i0].selected:'not_click')+';<br>';
}
</script>
<div id=a0></div>

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

Глядя на упоминавшееся в прежнем выпуске обсуждение решения задачи, видим, в чём проблема, вызываюшая усложнение решения. Если кликать по строке option, удерживая Ctrl, selectedIndex, указывает на первую строку, имеющую выделение, а не на строку, по которой кликнули. Поэтому-то наличие выделения выше по строкам не даёт достаточной информации для правильной работы скрипта. Поэтому простым способом не можем отследить нажатие строки при Ctrl+click, и приходится анализировать "последствия" - изменение выделения одной строки, чтобы затем скорректировать выделенность строк, если клик был произведён по строке не младшего уровня. Решение усложняется тем, что клик на <option> воспринимается только в FF/Opera, а Ctrl+клик на option - только в FF (но Ctrl+mousedown - там и там).

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

Что ж, делать нечего, придётся с каждым кликом запоминать состояние выбранности каждой строки option, чтобы потом искать различия. Благо, что список для программы остаётся линейным списком опций, и его выделенность считываем в массив. Добавление строк

a=[];   //массив для отображения выделенностей
  l=t.options.length;
  for(k=0;k<l;k++)aSel[k]=t.options[k].selected;
  ida0.innerHTML+='sels:'+aSel+';<br>';

в функцию fch() показывает состояние выделенностей и подводит к решению.

Формулируется оно так. Полностью убираем иные вызовы, кроме onchange, так как видно, что для всех браузеров массив выделенностей содержит всё необходимое. При следующем вызове onchange сравниваем массив с новым состоянием выделений в select. Если изменилось состояние строки, то ставятся в соответствие с ней все строки более низких уровней под ней.

Эта часть алгоритма будет прекрасно работать для Ctrl и shift, которые умеют снимать выделения. Но для обычного клика нужно программно ставить снятие выделения по пункту 3 правил управления, в то время как он, как показала отладка, всегда устанавливает выделение на месте клика и снимает его со всех остальных строк. К алгоритму требуется индикатор простого клика. Он реализуется тоже на анализе изменений выделенностей (проверять, была ли нажата Ctrl, не обязательно).

Существует ещё разница в узлах: пустые-непустые (пункт 2 правил). Давайте отметим их для начала теми же визуальными признаками уровня структуры. Если непустой, то перед названием (но после признаков уровня "· ") будет стоять "_". Позже его можно сделать невидимым, разместив в id или class опции.

Здесь, для того, чтобы написать нужный алгоритм, снова возвращаемся к проектированию пользовательского интерфейса. Построим таблицу реакций скрипта на нажатия клавиш и опций, чтобы по ней построить алгоритм. Различаются (первый параметр) способы нажатия - с клавишей Ctrl (или shift), или простое. Различаются (второй параметр таблицы) нажатия на опции: узловая или самого нижнего уровня. (Если узловая, то пустой или непустой узел.) Различаются, наконец, (третий параметр) состояния опции - была она выбрана до нажатия или нет.

Состояние при действии Реакция
Клик Строка Выделен-
ность
ПростойУзелБыла 000 Выделение узла и его подструктуры если не вся выделена; снятие выделения, если вся структура выделена. Незатрагивание элементов не в родительской подструктуре, если установлено правило 5, вариант.
Нет 001 Выделение узла и нижней структуры. Незатрагивание не в родительской подструктуре, если установлено правило 5, вариант.
Эле-
мент
Была 010 Снятие выделения, если 1 выделенный элемент в списке/подструктуре (особое правило для удобства, можно не делать, потребует анализ onmousedown), снятие выделения с верхних пустых узлов, если есть. Со снятием выделения других элементов (всех или в своей подструктуре (правило 5, вариант)).
Нет 011 Обычное выделение одного элемента со снятием выделения других (всех или в своей подструктуре (правило 5, вариант)).
С Ctrl или shiftУзелБыла 100 Снятие выделения непустого узла без подструктуры. Снятие пустого узла со всей подструктурой (не как при простом клике, а независимо от выделенности подструктуры).
Нет 101 Выделение одного непустого узла без подструктуры. Выделение пустого узла с его подструктурой.
Эле-
мент
Была 110 Обычное снятие выделения; снятие выделения верхних пустых (правило 2) узлов, если их подструктура стала невыделенной.
Нет 111 Обычное выделение; выделение верхних пустых (правило 2) узлов если их подструктура стала полностью выделенной.

Сложность реализации в том, что хотим получить не только реакцию на один Ctrl-клик, а все реакции на изменения выделений при shift-клике, которые можно рассматривать как ряд Ctrl-кликов. Не вдаваясь далее в подробности реализации (о реализациях алгоритмов нужно писать книги типа Д.Кнута "Искусство программирования"), приведём результат.

<select multiple onchange=ff(this) onkeyup=fk(event)
  onmousedown=fc(this,event) onkeydown=fk(event) size=8>
<option>1.Раздел 1 (пустой пункт)</option>
<option>∙ 1.1.Пункт1</option>
<option>_2.Раздел 2 (непустой п.)</option>
<option>∙ 2.1.Пункт1 (р.2) (пустой п.)</option>
<option>∙ ∙ 2.1.1.Подпункт1 (п. 1 р.2)</option>
<option>∙ ∙ 2.1.2.Подпункт2 (п. 1 р.2)</option>
<option>∙ _2.2.Пункт2 (р.2) (непустой)</option>
<option>∙ ∙ 2.2.1.Подпункт2 (п. 2 р.2)</option>
</select>
<script>  //© I.Svetlov, 2006
 //групповое выделение опций в списке выбора
aSel=[];//для отображ.преж.сост.списка select
aSelS=[];//для сост.выдел-сти подструктуры
clickArea=[];  //область работы простого клика
onload=function(){ida0=document.getElementById('a0');}
c="∙ ";  //признак уровня структуры
nepust="_";  //признак"непустоты"узла(после признака уров.)
Variant5=!0; //правило работы простого клика в подструкт.
aLev=[];  //начала уровней подструктур

fc=function(t,ev){ //по onmousedown, чтобы задать нач.уст.
  /*ctrlsh=ev.ctrlKey||ev.shiftKey;*/  fASelS(t);
  if(!ctrlsh&&m1==1)t.options[t.selectedIndex].selected=!1;
}
fk=function(ev){ctrlsh=ev.ctrlKey||ev.shiftKey;}//из-за Оперы
fASelS=function(t,x){  l=t.options.length;  //длина списка
  m1=0;
  for(k=0;k<l;k++){  aSel[k]=t.options[k].selected;
    m1+=aSel[k];
    aLev[n1=((j1=t.options[k].text.lastIndexOf(c))
      -(j1<0)*(c.length-1)+c.length)/c.length]=k;
    aSelS[aLev[n1]]=x?null:(aSel[k]?0:2);//выбрано/не выбр.
    for(n2=0;n2<n1;n2++){if(aSel[k]
        &&aSelS[aLev[n2]]==2||!aSel[k]
        &&aSelS[aLev[n2]]==0)aSelS[aLev[n2]]=1;
      if(aSelS[aLev[n2]]==null)aSelS[aLev[n2]]=aSel[k]?0:2;}
}}    //заполненность подуровней:0-весь,1-часть,2-нет
ff=function(t){ //по onchange, установка выделений
  m=-1;n=0; //m-индекс прост.клика,n==1 -признак прост.кл.
  for(k=0;k<l;k++){  clickArea[k]=!1;
    if(t.options[k].selected){
      if(t.options[k].selected)n++;
      jm=t.options[m=k].text.lastIndexOf(c); //уровень.кл.
  }}
  if(n==1&&(m==l-1||jm>=t.options[m+1].text.lastIndexOf(c)))
    for(k=m;k>=0&&jm<=t.options[k].text.lastIndexOf(c);k--)
      clickArea[k]=!0;  //верхн.обл.прост.клика над элем
    if(n==1)
      for(k=m;k==m||k<l&&jm<t.options[k].text.lastIndexOf(c)
        +(m==l-1||jm>=t.options[m+1].text.lastIndexOf(c));
      k++)clickArea[k]=!0;//обл.прост.клика под элем.|узлом
  
  for(k=0;k<l;k++){  //смена выделений
    aLev[n1=((j1=t.options[k].text.lastIndexOf(c))
      -(j1<0)*(c.length-1)+c.length)/c.length]=k;
    if(ctrlsh){for(n2=0;n2<=n1;n2++)if(aSel[aLev[n2]]
      !=t.options[aLev[n2]].selected
      &&pustUz(aLev[n2],t))break;  //по Ctrl-Click & пуст.уз.
     if(n2<=n1)t.options[k].selected=!aSel[aLev[n2]];
    }else{for(n2=0;n2<=n1;n2++)if(aLev[n2]==m)break;//-Click
      if(n2<=n1&&aSel[aLev[n2]])
        t.options[k].selected=aSelS[aLev[n2]]!=0;
      if(n2<=n1&&!aSel[aLev[n2]])t.options[k].selected=!0;
    if(!clickArea[k]&&Variant5)t.options[k].selected=aSel[k];
      else if(n2>n1)t.options[k].selected=!1;
  }}
  fASelS(t,1);//для коррекции пустых узлов
  for(k=0;k<l;k++)//коррекция пустых узлов
    if(pustUz(k,t)){
      if(aSelS[k]==0)t.options[k].selected=!0;
    if(aSelS[k]==2)t.options[k].selected=!1;}
}
pustUz=function(k,t){return t.options[k].text.indexOf(nepust)
  !=(j1=t.options[k].text.lastIndexOf(c))
  +c.length-(j1<0)&&k<l-1&&t.options[k].text.lastIndexOf(c)
  <t.options[k+1].text.lastIndexOf(c)
}</script>
<div id=a0></div>

Общее правило реализации алгоритмов такое: из имеющихся правил делать другие, эквивалентные данным, которые легче реализовать. Так сформировались новые правила, которые последовательно были реализованы. Предпочтительно избегать цепочечных функций в циклах (когда следующее значение зависит от предыдущего) - они эффективны, но запутывают, лучше обходиться индексными и решать задачи по частям.

Примечания. Поддержка Оперы (7.54). К сожалению, из-за неподдержки Оперой некоторых операций пришлось для неё ввести функцию fk(), заменить onmousedown на onmouseover и добавить вызовы onkeydown, onkeyup. Усложнилась задача поддержки нескольких селектов на странице для всех браузеров, потому что определять версию и увеличивать код не стал. Не доработано в Опере правило корректировки "пустых" узлов и удаления одиночной выделенности. Потеря функциональности, распространившаяся на все браузеры, небольшая, поэтому терпимо. Возможно, через некоторое время на странице примера будет лежать доработанный код. Посмотреть на хорошо работающий компактный код, но без поддержки Оперы можно здесь.

Так называемых "пустых" узлов в структуре пользователя может не существовать, или наоборот, все узлы будут пустыми (без самостоятельного выделения, без информации). У них есть свойство, что если все элементы их списка не выделены, снимается выделение и на узле. Так же, при выделенности всего списка узел выделяется автоматически. В примере это наблюдается при клике во второй строчке: выделение приводит к выделению заголовка - "пустого" узла, так как список элементов состоит из одного.

В рабочем примере изображена структура со свойством раздельной работы с подструктурами. Это может быть необычно и непривычно: клики затрагивают только один уровень структуры, другие остаются совершенно неизменны, хотя процесс переписывания выделений виден при клике. Чтобы работать со всей структурой как с одним списком, надо присвоить переменной Variant5 значение false.

Так же необычно, но полезно снятие выделения при одиночном клике на выделенной строке.

По-особенному сделана работа с Ctrl-кликом на "пустом" узле - изменяется выделение всей подструктуры, потому что выделение одного пустого узла не имеет особого смысла.

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

Теперь, как практически пользоваться кодом, чтобы меньше настраивать скрипт? Если устраивают признаки вложенности уровней в данном виде - хорошо. Но если они будут выражены цветом или неявно, то признаки понадобится перенести в имена классов для опций и несколько переделать скрипт.

Уровень: для программистов
-v---

Статья.
6.06.06

Таблицы с подсветкой строк

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

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

Какими способами реализуется алгоритм подсветок и выделений? Во-первых, можем сделать автоматику подсветок, ставя в каждом теге строки (TR) атрибуты onmouseover, onmouseout, onclick. Когда надоест повторять их в каждой строке много раз, вспомнятся обработчики событий. Наконец, есть подход, основанный на базе псевдоклассов CSS, которые работают в FF/Opera для любого тега. В IE есть альтернатива псевдоклассам - скрипты поведения (behavior), которые тоже задаются через CSS.

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

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

Подуровни могут не только выделяться, но и сворачиваться при клике на них или на части строки. Возможные задачи разрастаются в масштабах, пора остановиться, чтобы за лучшим не потерять хорошее. Хорошее - это скромная подсветка строк с возможностью выделения чекбокса или радиокнопки по клику на любом месте строки. Чтобы, падая обессилевшей рукой на левую клавишу мыши, гарантированно попасть на какую-либо строку...

В недавнем обсуждении вопроса на одном из форумов были представлены три варианта реализации таблицы с подсветкой строк от 3 авторов, и как дополнительная опция, добавлена строка с действием "Выделить всё". Вот вариант, стоящий среди реализаций особняком, так как выполнен на псевдоклассах и behavior-скрипте. Все цвета также вынесены в классы CSS.

<b>Таблица с выделением строк и чекбоксов на ней,
  реализованная с помощью behavior для IE
  и :hover для FF/Opera.<br> 
<br>
<style>
    td:active{background-color:red;}
    tr:hover{background-color:darkred;}/*для FF/Opera*/
    tr{behavior:url(JsPrimeryCode-84.htc)}
    .hovered{background-color:darkred;}
    .pressed1{background-color:red;}  /*для IE*/
    .selected1{background-color:blue;}
</style> 
<script>chk=function(e,t){
  tg=document.all?e.srcElement:e.target;
  if(tg.tagName!='INPUT')t.firstChild.firstChild.checked
    =!t.firstChild.firstChild.checked;
  t.className=t.firstChild.firstChild.checked?'selected1'
    :'';}
chkAll=function(e,t){chk(e,t);
    Al=document.getElementsByName('chk[]');
    tg=t.firstChild.firstChild;
    //alert(Al[0].parentNode.parentNode.tagName)
    for(i=0;i<Al.length;i++){Al[i].checked=tg.checked;
    Al[i].parentNode.parentNode.className
      =t.firstChild.firstChild.checked?'selected1':'';}
}
</script>
<table border=1 width=100% cellspacing=0>
<tr onclick=chkAll(event,this)><td><input type=checkbox>
  выделить/снять все</td><td>*</td></tr>
<tr onclick=chk(event,this)><td><input type=checkbox
  name=chk[]>+++</td><td>*</td></tr>
<tr onclick=chk(event,this)><td><input type=checkbox
  name=chk[]>+++</td><td>*</td></tr>
<tr onclick=chk(event,this)><td><input type=checkbox
  name=chk[]>+++</td><td>*</td></tr>
<tr onclick=chk(event,this)><td><input type=checkbox
  name=chk[]>+++</td><td>*</td></tr>
<tr onclick=chk(event,this)><td><input type=checkbox
  name=chk[]>+++</td><td>*</td></tr>
</table>

Файл JsPrimeryCode-84.htc:

<attach for=element event=onmouseover handler=hig_light>
<attach for=element event=onmouseout handler=low_light>
<attach for=element event=onmousedown handler=H_press>
<attach for=element event=onmouseup handler=low_light>
<script>
function hig_light(){element.className='hovered';}
function Ht_press(){element.className='pressed1';}
function low_light(){element.className
  =element.firstChild.firstChild.checked?'selected1':'';} 
</script>

Демонстрация работы находится на странице примеров. Более подробное обсуждение этого и других вариантов подсветки строк таблицы читайте в следующем выпуске.

Уровень: для программистов
-v---

 javascript.aho.ru , © I.Svetlov, 2005-2006 
Текущая очерёдность плана статей (подписчики могут корректировать через голосование).
9. Таблицы с подсветкой строк и выделением по клику. Подсветка и выделение части строки.
8. Ключевые слова новых технологий, которые нужно знать разработчику веб-страниц.
3. Как писать тексты с доступом через JS без экранирования специальных символов (&lt; и другие).
4. select и list - в них есть много общего. Как и с меню навигации. Эмулятор селекта.
5. Древовидное меню, подход к данным, отделение данных от представления.
6. Многонедельный календарь со ссылками. (По списку строится календарь.)

Если обнаружилось, что приходили не все письма, пожалуйста, сообщите об этом автору рассылки, чтобы помочь разобраться, какие коды некоторые почтовые серверы не пропускают. Предложения о новых темах, вопросы по Javascript, замечания по выпуску рассылки отправляйте на почту автора.

 


В избранное