# или javascript:void(0): что выбрать для JavaScript-ссылок? Полное объяснение с кодом
Привет, коллега-разработчик! Если ты когда-нибудь писал ссылки, которые не ведут на новую страницу, а запускают JavaScript-код (например, открывают модальное окно, подгружают контент или выполняют анимацию), то наверняка сталкивался с дилеммой: какое значение атрибута href использовать? href="#" или href="javascript:void(0)"?
Этот вопрос — настоящий хит на Stack Overflow (тысячи просмотров!), и неспроста. Казалось бы, мелочь, но от неё зависит, как поведёт себя страница: будет ли она прокручиваться вверх, появится ли хэш в URL, сработает ли оно вообще в старых браузерах. Давай разберёмся раз и навсегда, какой подход лучше, и почему «правильный» ответ не так однозначен.
Проблема: зачем вообще менять href?
Представь: ты пишешь кнопку, которая открывает меню:
<a href="#" onclick="openMenu(); return false;">Меню</a>
Или так:
<a href="javascript:void(0)" onclick="openMenu();">Меню</a>
Оба варианта «работают», но каждый таит в себе сюрпризы. Давай сравним их по ключевым критериям.
Вариант 1: href="#" — классика с подвохом
# — это ссылка на «верх» страницы. Если ты просто напишешь <a href="#">, браузер прокрутит страницу вверх. Чтобы этого избежать, нужно добавить return false; в обработчик:
<a href="#" onclick="doSomething(); return false;">Нажми меня</a>
Плюсы:
- Доступность: ссылка остаётся фокусируемой (можно перейти по Tab).
- Семантика: для скринридеров это всё ещё ссылка (хотя и не ведущая никуда).
- Простота: легко запомнить, пишется быстро.
Минусы:
- Прокрутка вверх: если забыть
return false, пользователь потеряет позицию. - Изменение URL: добавляется
#в адресную строку (иногда это нежелательно). - История браузера: создаётся запись в истории (кнопка «Назад» поведёт на предыдущую «#»-страницу).
Вариант 2: href="javascript:void(0)" — хак для старых времён
javascript:void(0) — это JavaScript-псевдопротокол. Он говорит браузеру: «выполни код void(0) и не переходи по ссылке». void(0) возвращает undefined, поэтому страница не двигается.
<a href="javascript:void(0)" onclick="doSomething();">Нажми меня</a>
Плюсы:
- Не прокручивает страницу — никаких
return falseне нужно. - Не меняет URL — хэш не добавляется.
Минусы:
- Проблемы с доступностью: некоторые старые скринридеры могут «споткнуться» о
javascript:в href. - Нарушение принципов прогрессивного улучшения: если у пользователя отключён JavaScript, ссылка не работает (ведёт на пустоту).
- Невалидный HTML? Формально
javascript:— это нестандартный протокол, но браузеры его понимают. Однако валидатор W3C может ругаться. - Сложнее отладка: если в href есть ошибка, браузер может вести себя непредсказуемо.
Сравнение в таблице
| Критерий | href="#" |
href="javascript:void(0)" |
|---|---|---|
| Прокрутка вверх | Да (нужен return false) |
Нет |
| Изменение URL | Добавляет # |
Нет |
| Работает без JS | Да, но ведёт наверх | Нет (ссылка «ломается») |
| Доступность | Хорошая | Средняя |
| Совместимость | Все браузеры | Все современные браузеры |
| Валидность HTML | Да | Спорно |
Альтернатива: <button> — современный подход
Лучшее решение — вообще не использовать <a> для JavaScript-действий. Если элемент не ведёт на другую страницу, это кнопка, а не ссылка. Используй <button>:
<button onclick="openMenu();">Меню</button>
Преимущества:
- Чистая семантика — скринридеры сразу понимают, что это действие, а не навигация.
- Не нужно думать о href.
- Стилизуется как угодно (можно убрать стандартное оформление кнопки).
- Работает без JavaScript (если нужно — используй
<noscript>).
Но если по дизайну или контексту нужна именно ссылка (например, она должна выглядеть как текстовая ссылка внутри абзаца), то придётся выбирать из двух зол.
Когда какой вариант выбрать?
Выбирай href="#" если:
- Ты хочешь сохранить доступность и семантику ссылки.
- Ты готов писать
return falseв каждом обработчике. - Тебе не важно, что в URL появится