Яндекс.Метрика

    Веб разработка

    Давайте разрабатывать UI-элементы правильно

    Не так давно у меня кончилось терпение. По началу всякие плагины, а затем различные framework'и начинают «насиловать» HTMLDocument. Что бы понять потерял элемент фокус или нет — они отслеживают событие onclick на HTMLBodyElement или на HTMLDocument. И если некоторые из них обращают внимание на нажатие Taba при потере фокуса, то большая часть вообще игнорирует данный факт.

    Focus/Blur

    Есть 4 «волшебных» DOM события:
    • focus
    • blur
    • focusin
    • focusout

    Обычные DOMElements их не генерируют, однако, если использовать волшебный атрибут tabindex, то у нас появляется такая возможность.
    При создании своего UI элемента для jQuery пришлось столкнуться с 2 проблемами, связанные с тем, что внутри моего элемента используется HTMLInputElement (тут и далее я подразумеваю так же HTMLSelectElement и HTMLButtonElement).

    Проблема номер один — отсутствие всплывания событий focus и blur. И тут нам на помощь придут focusin и focusout.Теперь мы можем оперировать событиями фокуса на уровне родительского элемента,.
    Проблема номер два — генерация событий blur и focusout в родительском элементе, когда происходит click на дочернем HTMLInputElement(атрибут tabindex влияет лишь на получение фокуса с помощью Taba). Что в свою очередь «ломает» нам всю логику работы с разрабатываемым UI-элементом. На данный момент «приличного» решения данной проблемы я так и не нашел (отслеживание события onclick на document или body, тоже не является «приличным»)
    Первое возможное решение — это трансляция событий клавиатуры «детям» при удержании фокуса на «родителе», но на данный момент ни один из браузеров не поддерживает корректную генерацию событий этого типа (Fx поддерживает свой собственный интерфейс. IE9 и Chrome придерживаются стандарта, но у них баг при передаче кода нажатой клавиши — всегда передается ноль. Опера вообще не может генерировать события клавиатуры)
    Второе — это проверка document.activeElement при событиях потери фокуса ( и тут не без неприятностей, в Fx и Chrome activeElement становится ссылкой на новый элемент получивший фокус, только после завершения события blur).
    И так как, ни один из этих методов, не работает, то пришлось прибегнуть к «грязному хаку». Инструкции события blur выносить из общего потока, другими словами, используем setTimout.


    CSS System Colors

    Почему-то, мало кто помнит(знает) про системные цвета. Дорогие разработчики, давайте уважать желание пользователя и использовать те цвета, которые он предпочитает видеть в своей ОС. Ведь не все хотят читать на белом фоне и соответственно не пользуются синим для выделения текста.

    >>>UPD
    Конечно же, если вы создаете кнопочку, для вашего стилизованного приложения, то использовать системные цвета глупо. Я же упоминаю случаи, когда эмулируется системный GUI-элемент или его вариация. Например в Sencha(бывшее ExtJS) для фона элементов используется белый цвет, вместо Window. Вот пример.
    В jQuery по умолчанию во всех UI-решениях идет оранжевый цвет. Почему они решили сделать так, для меня до сих пор остается загадкой. Они бы многим облегчили жизнь, если бы использовали системные цвета по умолчанию( Признавайтесь, кто начинал мучиться со стилями jQuery UI при прикручивании календарика? :) )
    <<<<UPD


    event.stopPropagation()

    Инструкция прерывания потока события — это самое большое зло, которое я встречал на web-страницах. Если вдруг у вас не верно работает какой то элемент, перестают работать ссылки при странных стечениях обстоятельств, то знайте — это результат присутствия данной инструкции.
    Её можно аккуратно использовать лишь там, где вы точно уверены, что без нее не обойтись. Где альтернативное решение обойдется вам слишком дорого. Но как правило, если вы использовали «это», значит в вашем решении архитектурный просчет.
    Банальный пример, перехват щелчков мыши на вашем элементе с обрыванием потока сообщений. Все — теперь все кто завязаны на получения этого события (см. на все плагины, которые «закрываются» при клике вне них) будут работать не корректно.
    Или сворачивание всплывающего окна, по клавише Escape не будет работать, если ваш элемент перехватывает нажатие клавиш и находится в фокусе.


    WAI-ARIA

    Ну и наконец — стандарт о котором я узнал после выхода IE8. Он определяет подходы к содержимому сайта и/или интернет-приложения со стороны устройства(браузера). Стандарт был разработан и преподносится как механизм позволяющий людям с ограниченными возможностями полноценно использовать ваш интернет-проект.
    Но мне кажется, что данный стандарт будет активно применяться в мобильных браузерах. Т.к. использование UI-элементов поддерживающих WAI-ARIA позволит сделать их более удобным. Например вот так выглядит раскрытый HTMLSelectElement в мобильной версии IE9:


    Согласитесь, выбирать из такого списка на мобильном телефоне гораздо удобнее и приятнее, чем из небольшого, хоть и «симпатичного», сделанного с помощью JS и HTML


    Вместо послесловия

    По большому счету, данную заметку я решил написать, что бы попросить помощи у хабросообщества с решением проблемы focus/blur. Я ищу его уже не 1 месяц, и даже подумываю обратиться либо к разработчикам браузеров для стандартизации изменения activeElement либо в w3c.


    «Это интересно».

    Наиболее правильно оформленные UI-элементы реализованы корпорацией Google в Gmail. Это кнопочки над списком писем.