Для элемента COL в CSS не бывает псевдокласса :hover. Ну, может, и бывает, но у него всё равно нет своих потомков, на которых отразилось бы это действие. Как тогда подсветить столбец таблицы при наведении мыши? Да и строку подсветить не так просто: в IE7 :hover действует только для элемента A (ссылки). На javascript это можно сделать, как минимум, двумя способами.

Подсветка строк и столбцов HTML-таблицы

На одном форуме возник вопрос о подсветке (выделении цветом) в HTML-таблице ячейки, строки и столбца – при наведении мыши. Ну, как подсвечивать строку с ячейкой вроде бы понятно:

Но как выделить цветом текущую (наведённую) колонку? У элемента col CSS-фокус с col:hover для ячеек выбранного столбца не срабатывает (так как, строго говоря, ячейки не являются потомками col). Поэтому без какого-то минимума javascript тут не обойтись.

Первое решение – быстрое и неправильное

Быстренько кропаем следующее «красивое» решение: krest.html. Алгоритм такой:

  1. Всем элементам col таблицы назначаем атрибуты id, значение которых заканчивается на число – индекс, начиная с нуля.
  2. Таблице присваиваем атрибут onmouseover = [some function]
  3. В функции-обработчике (мы назвали её cBg – от "change background") мы получаем индекс текущей ячейки (над которой мышь) – cellIndex, добавляем к этому индексу спереди условные буквы (у нас – "col_") и получаем идентификатор соответствующей (текущей, если мы всё правильно сделали) колонки.
  4. Назаначаем найденной текущей колонке className = "green", предварительно описанный в правилах CSS.
  5. Ну, а при противоположном событии (onmouseout) удаляем className green у текущей колонки.
  6. Цвета фона текущей строки и ячейки попросту описываем в CSS псевдоклассами tr:hover, td:hover.

Красота! Возвращаемся на форум, который нас растревожил по этому поводу, и обнаруживаем в одном из сообщений ссылку на практически точно такой же говнокод: http://css-tricks.com/examples/RowColumnHighlighting/js/example-one.js. То есть сначала-то мы не знали, что это у нас получился говнокод, но глядя, как в зеркало, на позорную Жикверь-based-поделку, злобно выискали все соринки в глазу негодяя.

  • Первое: не работает в Опере! Почему-то при динамическом назначении селектора класса элементу col в Опере цвет столбца не меняется (хотя в принципе в статическом CSS раскрашивать таблицу через col можно).
  • Второе: подсветка строки и ячейки на CSS не работает в IE6 (и, видимо, в IE7) – так как там псевдокласс :hover действует только для ссылок (элементов a).
  • И третье: конкуренты напомнили о неявных зависимостях: префикс "col_" у нас для ID колонок генерируется на сервере (получаем готовый HTML), и javascript на клиенте должен как-то догадываться об этом префиксе, чтобы с его помощью находить элементы col. У конкурентов здесь лучше: ID колонок генерируется прямо в javascript.

Простое решение: быстрое, работающее, но с зависимостями

Сначала делаем, чтобы всё просто работало (Just do it! (c)): krest2.html. Кода javascript в нём, пожалуй, даже и не больше, чем в первом решении – из-за Оперы нет смысла искать колонки по идентификаторам, и мы присваиваем раскрашивающий селектор класса всей таблице. За это приходится платить увеличением HTML-кода.

Как через класс таблицы можно по-разному раскрасить разные группы ячеек? Ясно, что только назначив каждой ячейке группы свой className. То есть логика такая: таблица с классом "c1" (color1) будет раскрашивать все вложенные элементы с классом "td1" в условленный цвет – это должно быть заранее описано в правилах CSS, для каждого класса (соответственно, например, класс таблицы "c2" будет менять фон всех элементов с классом "td2").

Ясно, что куча всех этих классов в ячейках совершенно не нужна серверу. Ну, и становится тяжеловато "правильно" оперировать селекторами классов без специальной функции (из-за этого текущей ячейке цвет меняем напрямую – через свойство style).

Поиск идеального решения

Во-первых, проверим вариант управления цветом через колонки: krest3.html. В IE6 работает, в Опере, с..., не работает! Ну, тут уже меня заело, полез копаться в Операх. В Опере версии 11.64 всё-таки работает. В версии 11.10 – нет. Забить или не забить?.. По-моему, быть хуже IE – это уже сверхнаглость. Забьём ради красоты решения.

Во-вторых, вернём «функциональность»: вместо двух безымянных функций для mouseover и mouseout сделаем, как в первом варианте одну функцию на всё – cBg.

В-третьих... ну, тут много всего. Надо просто сделать «нормально», «нормализовать» все взаимоотношения между javascript, CSS и сервером (HTML). Для начала просто поместим javascript, куда положено, – в HEAD, и вынесем в отдельный файл.

Вот что в результате получилось: krest.js. Кроме основного функционала подсветки, мы включили в этот файл вспомогательные «библиотечные» функции: cc (управление классами элементов), addLoadEvent (назначение очевидно). Основная сложность при подготовке таблицы оказалась в упорядочивании элементов col: мы предусматриваем ситуацию, когда эти элементы явно не переданы в HTML, и даже ситуацию, когда эти элементы переданы частично (например, в HTML описаны 2 элемента col, а реально в таблице 5 столбцов). Скрипт всё это обрабатывает и унифицирует, и в итоге в подготовленной таблице есть все элементы col с нужными классами (которые известны только javascript).

Интерфейсы

В нашей системе подсветки javascript в ответ на какие-то действия пользователя назначает некоторым элементам HTML некоторе классы CSS. Чтобы всё это правильно отображалось, классы должны быть описаны в правилах CSS (может быть, вообще в отдельном файле). У наименований селекторов CSS своя логика, их имена не должны зависеть от движка javascript. Поэтому во «входящей» функции системы – prepTableHL должны быть «ключики», позволяющие указывать javascript, с какими сущностями CSS следует работать.

У нас получилось внедрить только один такой ключик – наименование класса для подсветки строки (rowC): krest4.html. Ну, ещё можно сообщать js ширину таблицы, чтобы корректно работать с элементами col. А то у нас жёстко было зашито "15", и если ширина всего 5 ячеек, скрипт отчасти перемалывал пустоту (что, в общем, мелочь), а если 16?.. Что же, последняя колонка окрашиваться не будет? Мы, конечно, пытаемся взять ширину таблицы «на ходу» – по числу ячеек первой строки. Но ведь там могут быть объединённые ячейки. Поэтому приоритет остаётся за явным указанием ширины при вызове подготовительной функции – через параметр tW.

Неуправляемым «снаружи» остаётся у нас набор селекторов «класс таблицы» – «класс колонки», что-то вроде:

Во входной параметр при избранной архитектуре «движка» удаётся впихнуть только цвет фона (rowC). И это сводит на нет всю красоту. Это прямо-таки позор нашего скрипта подсветки (а что если понадобится красить столбцы не через цвет фона, а, например, через opacity? лезть в код скрипта?..). Всё надо менять.

Окончательное решение

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

То есть будем уж по-человечески, просто менять классы у колонок. Примерно как ничтоже сумняшеся сделали конкуренты. Но они сделали стрёмно, а мы сделаем качественно. В скрипте http://css-tricks.com/examples/RowColumnHighlighting/js/example-one.js в интересующей нас части используется следующая схема:

  1. При подготовке таблицы всем колонкам назначаются ID (почти, как у нас: col1, col2, col3...).
  2. Во время исполнения (наступления mouseover) соответствующая колонка находится в DOM по своему ID, и ей присваивается нужный класс.

Это же страшно невыгодно! Мы один раз нашли элемент колонки (или даже сами создали его в одном из вариантов). Зачем потом ещё раз искать его по ID? Зачем вообще эти ID? Колонками не требуется управлять извне, из других скриптов. А внутри нашего собственного мы можем просто загнать ссылки на все колонки в массив, хранимый как свойство самой таблицы (t.cols).

А вот селекторы классов нужно передавать скрипту снаружи явно, через параметры rH (класс подсвеченной строки), colH (класс подсвеченной колонки), cH (класс подсвеченной ячейки). А реальное отображение этих классов, как и положено, определять в CSS.

Вот ответ, максимально приближённый к идеалу: krest5.html.

P.S. для Оперы 10.11

Ну, как же мы без Оперы. Там (в рабочем для Оперы варианте krest2.html) засада была в том, что нужно было иметь большой (раздутый!) HTML – у каждой ячейки должен был быть свой класс (одинаковые классы в пределах одной колонки – такие «псевдостолбцы»).

Зачем серверу знать все эти душераздирающие подробности? Перенесём генерацию классов ячеек в наш ненавязчивый javascript, и дело с концом: krest6.html. Любителям Оперы надо, однако, помнить, что в этом варианте останется жёсткая связка кода с CSS: там скрипт подрисовывает в начале страницы правило CSS, в котором подсвечиваемым элементам назначается конкретно background-color, а не имя CSS класса.

Дилетант

Комментарии

Виктор 18.05.2015 02:29:21

Нашел такой вот вариант. Мне он показался проще. http://jsfiddle.net/UfpWM/

Александр 20.12.2014 03:42:23

Здравствуйте Как сделать, чтобы js не применялся к строке с классом .nolighting (при наведении на строку tr с таким классом не было подсветки строк и столбцов)

Александр 20.12.2014 03:42:01

Здравствуйте Как сделать, чтобы js не применялся к строке с классом .nolighting (при наведении на строку tr с таким классом не было подсветки строк и столбцов)

Александр 20.12.2014 03:39:48

Здравствуйте Как сделать, чтобы js не применялся к строке с классом .nolighting (при наведении на строку tr с таким классом не было подсветки строк и столбцов)

Алексей 14.06.2014 21:46:52

http://www.java-study.ru/jquery-uchebnik/93-obrabotka-sobytiy-jquery там есть событие blur, через поиск по странице посмотри. это событие javascript срабатывает когда покидаем форму

Ксения 07.05.2014 07:59:46

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