Links, please
Однажды наступит тот день, когда самые продвинутые IT-компании научатся пользоваться ссылками. Тогда заживем.
Три правила ссылок
Раз
Если вам в href
очень хочется положить javascript: void(0);
, #
или еще какую-нибудь фигню, успокойтесь, глубоко вздохните и замените ссылку на button
.
Кнопка воспринимает событие click
, стили :hover
и :active
и попадает в общий tabindex точно так же, как и ссылка. Невероятно!
Два
Если вам очень хочется запихнуть в ваш элемент onclick="location.href='...'"
, остановитесь, вздохните еще раз и сделайте ссылку. Теперь вашу ссылку можно открыть в новой вкладке, вызвать контекстное меню браузера с кучей функций, а адрес ссылки будет виден при наведении мыши. Поразительно!
Три
Единственный случай, когда можно (и нужно) вешать обработчик на ссылку — если есть что показать по ссылке. При этом важно, чтобы обработчик срабатывал только при нажатии левой кнопки мыши без кнопок-модификаторов.
Классический пример — превьюшки фоток. При нажатии на превьюшку показывается большая фотка поверх текущего контента. При клике колесом или ctrl-клике фотка открывается в новой вкладке. Контекстное меню тоже работает. Юзеры с отключенным / сломанным яваскриптом получают рабочую ссылку на фотку. Все довольны:
HTML:
<a href="photo.jpg" class="preview">
<img src="p_photo.jpg">
</a>
JS + jQuery:
$('.preview').click(function(event) {
// If it's not LMB or if a modifier key is pressed – do nothing.
if (
event.button !== 0 ||
event.shiftKey ||
event.altKey ||
event.ctrlKey ||
event.metaKey
) {
return;
}
// Otherwise prevent the default action
event.preventDefault();
// and execute our function (e. g. show photo)
alert('Function executed');
});
Результат:
ИЕ версии 8 и ниже в событие click
всегда возвращает button
равный нулю. В результате клик колесом также приведет к выполнению функции, но все остальное будет работать корректно. Я бы с этим не заморачивался, но если очень хочется, можно заморочиться. Не стоит, ИЕ8 давно мертв.
Хорошие ребята
Есть много других ситуаций, в которых также очень желательно оставлять функционал ссылки. Смотрите, как делают хорошие ребята:
Переключение страниц
Пагинатор комментариев на vk.com переключает страницы без перезагрузки, но оставляет возможность открыть страницу в новой вкладке.
Форма логина / регистрации
На реддите форма логина и регистрации открывается в попапе поверх текущей странице, если кликнуть левой кнопкой мыши, и на новой вкладке, если нажать колесом. Правда, они не учли кнопок-модификаторов.
Дополненный функционал
Случайно наткнулся на этот пример, когда на метакритике отказались загружаться скрипты. Кнопка Expand под пользовательскими отзывами — ссылка на ту же страницу с GET-параметром, например ?user_review_id=1713311
. При отключенном или сломанном (как в моем случае) яваскрипте сервер отдаст вам страницу с раскрытым отзывом пользователя. Отличный пример ненавязчивого яваскрипта. Грамотный фоллбек на серверную часть сохранил функционал сайта при упавшем CDN-сервере.
Плохие ребята
Твиттер встал на путь истины и стал потихоньку исправлять свои косяки. Профиль юзера можно открыть в новой вкладке — гут. Кнопочка refresh в сайдбаре и кнопка нового твита используют button
— тоже гут (а можно было и ссылку на форму нового твита сделать).
Тем не менее, постоянно попадаются <a href="#">
. Ссылки reply, retweet и favourite никуда не ведут, а могли бы.
Google+
Та же ситуация, что и с Твиттером. В целом, ребята исправляются (раньше все было очень плохо), тем не менее на главной странице менюшка переключения кругов по-прежнему использует data-dest="stream/circles/p4765f1c30e7d2c98"
вместо нормальной ссылки, а аватарка в верхнем правом углу завернута в ссылку с моим любимым javascript:void(0)
.
Все плохо. javascript:;
в кнопках, ни одна ссылка не открывается в новой вкладке. Ребята запилили навигацию через хистори стейты, но о вкладках не особо слышали. Ведь одной вкладки для среднего хипстера вполне достаточно, да?
TL;DR
Используйте button
для действий на странице, a
для ссылок и для действий с фоллбеком, доступным по ссылке.
Несмотря на то, что сейчас сложно найти устройство без яваскрипта, ситуации, когда скрипт по той или иной причине не загружается или выполняется с ошибкой, происходят довольно часто. В таких случаях грамотные фоллбеки помогут сохранить функционал сайта.
Ссылки по теме
- «Жми сюда!», Вадим Макеев
- «When is a link not a link?», Jeremy Keith
- Javascript Madness: Mouse Events, Jan Wolter