Создание элементов управления в теге option без использования слоев

02.05.2015
Базовая функциональность тега <option> позволяет размещать в нём только текст. Элементы управления в этом теге можно разместить поверх записи в нужном месте. Однако, некоторые элементы управления на основе ссылок возможно сделать в этом теге без помощи слоёв.
Для чего может понадобиться размещение ссылок в теге <option>? Для придания списку дополнительной функциональности и отделения процесса навигации по его записям от запросов на получение дополнительной информации.
Предположим, список содержит названия товаров и нужно отображать при щелчке на слове "описание" информацию о выбранном товаре. Проще всего выводить эту информацию по щелчку на нужном элементе списка. Но в этом случае отображение информации о товаре будет происходить автоматически при выборе записи, что неудобно. Можно рядом со списком расположить элемент управления и на него нагрузить функцию отображения информации о товаре. Но в таком случае придётся каждый раз курсором мыши тянуться к нему. Для сокращения этих лишних движений можно при помощи javascript сделать так, чтобы элемент управления перемещался или всплывал над активной записью списка. Но и в этом случае получается два действия - сначала перейти к записи, затем - нажать на ссылку для получения информации о товаре. Для выполнения этой операции за один щелчок необходимо в самой записи создать элемент управления. Тогда посетитель сможет перемещаться по списку как обычно, а для получения дополнительной информации о товаре щелкнуть на этом элементе управления или нажать заданную комбинацию клавиш, что также очень удобно.
Задача решается так:
  • Создаём список <select>
  • Создаём несколько записей <option> и выбираем среди них "родительские" - те записи, которые будут участвовать в навигации и содержать в своём поле остальные неактивные для навигации "дочерние" записи
  • При помощи CSS устанавливаем высоту "родительских" элементов <option>, а при помощи внешних отступов margin позиционируем "дочерние" записи так, чтобы они находились в "родительской" записи
Указываем для дочерних записей свойство disabled="disabled" и видим, что они не принимают участие в навигации, что нам и нужно.
А теперь о грустном. Только браузер FireFox в настоящее время поддерживает события на неактивной записи. Кто-то считает, что это баг данного браузера, тогда как "нормальные браузеры" - Chrome, Opera, Яндекс работают как надо, блокируя события на неактивной записи. Это нехорошо. Элементы управления формы функционально достаточно слабы, поэтому было бы очень здорово, если бы и другие браузеры работали здать как FireFox, позволяя события на неактивном для выбора элементе списка. Это избавило бы нас от тонны кода на javascript, который придётся писать для решения данной проблемы.
Итак, нужно решить задачу возникновения события на неактивной записи списка. Для этого создаётся обработчик onmousedown для списка, в котором в цикле осуществляется проход по всем (или только видимым) элементам списка для определения записи в пределах которой находится курсор мыши. Получаем относительные координаты мыши внутри списка с учетом смещения скроллера списка и проверям, попали ли они в область какого-нибудь элемента списка. Если попали, то выходим из цикла и выполняем событие, назначеное на этот элемент.
Остальное - выделение родительской записи при щелчке на дочерних, изменение внешнего вида записей (возможно в FireFox), изменение цвета полосы выделения активной записи и др. реализовать не сложно. Небольшое замечание насчет изменения полосы выделения. Проще всего для этого использовать полупрозрачный слой, накладываемый на активную запись. При желании можно на этот слой навешать разных элементов управления.
Оглавление
Copyright © 2016