Добро пожаловать на сайт SEDBY

Кастомизируем форму поиска в стиле Github

  • 129 просмотров +1
  • 18 января, 2026
  • Обновлено: 19 января, 2026
  • admin
  • Время чтения: 5 минут
  • 1 (Подробно)
Кастомизируем форму поиска в стиле Github

Мы уже не в первый раз поднимаем тему использования глобальной формы поиска на сайте под управлением Cotonti Siena. Обсуждали и плагин Search, и сам код глобальной формы поиска, который можно взять в готовом виде из сниппета. 

На днях возник вопрос об улучшении юзабилити глобальной формы поиска на сайте. В качестве примера использовался сайт Github, где для удобства доступа к поиску используется клавиша / (Slash). Именно от этого и решили отталкиваться.

Преамбула

Клавиша / во многих браузерах используется как клавиатурное сокращение для поиска по веб-странице, открытой в текущем окне. Правда “слэш” не всегда срабатывает независимо от клавиатурной раскладки. Например, в Mozilla Firefox это происходит только при выборе английского языка.

Если говорить о реализации на сайте Github, то по факту это открытие модального окна при нажатии на / – правда, опять же, только в английской раскладке. Вероятно, это связано с многоязычностью данного сервиса.

Мы не будем использовать модальное окно, просто потому, что, в отличие от Гитхаба, место позволяет выводить форму глобальную форму поиска как есть. Будем использовать событие focus и работать с атрибутом placeholder. Впрочем, вы можете усложнить код и поведение по своему желанию.

HTML-разметка и CSS-стили

Код формы поиска можно взять готовым из сниппета. Для наглядности мы будем работать именно с ним.

Если есть желание стилизовать элементы формы, в этом не будет проблемы. Напомним лишь, как применяются CSS-стили к атрибуту placeholder:

input[name=sq]::placeholder { font-size: 1.125rem; opacity: .5; }

Теперь приступим к написанию скрипта.

JavaScript-код

Прежде всего, определим константы, с которыми будем работать. Начнем с самой формы:

const topSearch = document.forms.topsearch;

… и проверим ее присутствие в HTML-документе. Если все в порядке, определим остальные константы:

if (topSearch) {
  // Можно работать с формой
  const topSearchInput = topSearch.sq;
  const topSearchInputPlaceholder = topSearchInput.getAttribute('data-placeholder');
  const topSearchButton = topSearch.querySelector('button');
}

Определение можно реализовать, например и методом document.getElementById(). Мы же использовали свойство документа forms для доступа к форме по атрибуту name, и далее аналогично поступили с элементом input. Placeholder и button определены также максимально просто.

Итак, можем начинать, и первым делом мы заблокируем отправку формы при незаполненной строке поиска. Для этого используем следующую функцию:

  function hastext() {
    if (topSearchInput.value === '') {
      topSearchButton.disabled = true;
    } else {
      topSearchButton.disabled = false;
    }
  }

, которую “повесим” на событие keyup:

topSearchInput.addEventListener("keyup", function() {
  hastext();
});

Теперь при пустом topSearchInput к форме будет применен атрибут disabled

Двигаемся дальше. Для фиксирования клавиатурных нажатий используем событие keydown применительно к трем клавишам:

  1. / для переброса курсора в форму (событие focus),
  2. Escape для удаления курсора из формы (событие blur),
  3. Enter для отправки формы

Контроль нажатий, как обычно, в консоли:

window.addEventListener('keydown', (event) => {
  if (event.code === "Slash") {

  } else if (event.key === "Escape") {

  } else if (event.key === "Enter") {

  }
  console.log(event.key);
});
Обратим внимание: использование свойства code позволяет идентифицировать нажатие на физическую клавишу, тогда как key определяет введенный символ.

Также важным является то, что фиксировать нажатие на / нам необходимо только если мы не заполняем другую форму, т. е. если какой-либо элемент не является активным. Для краткости нотации напишем однострочную функцию:

function noActive() {
  return document.activeElement === document.body;
}

Теперь можно оформить условие для нажатого /:

if (event.code === "Slash") {
  if (noActive()) {
    event.preventDefault();
    topSearchInput.value = topSearchInput.placeholder = '';
    topSearchInput.focus();
  }
}

При отсутствии активного элемента блокируем действие по умолчанию, очищаем атрибуты value и placeholder и перебрасываем курсор в input формы.

Отслеживать нажатие на Esc необходимо только если активным элементом является input нашей формы:

if (event.key === "Escape") {
  if (document.activeElement === topSearchInput) {
    event.preventDefault();
    topSearchInput.value = '';
    topSearchInput.blur();
    topSearchInput.placeholder = topSearchInputPlaceholder;
    topSearchButton.disabled = true;
  }
}

При нажатии на Esc блокируем действие по умолчанию, очищаем атрибут value, убираем курсор из формы (событие blur), восстанавливаем значение placeholder и блокируем кнопку отправки формы.

Последний шаг – нажатие на Enter:

if (event.key === "Enter") {
  if (document.activeElement === topSearchInput) {
    return;
  }
}

Если активным элементом является input нашей формы, используем действие по умолчанию, т. е. отправляем форму.

Нам осталось только обработать клики мышкой. Здесь все просто – нас будут интересовать клики по элементам формы input и button, а также клики вне формы:

window.addEventListener('click', function(event) {
  if (topSearchInput.contains(event.target)) {
    // console.log("Clicked on form input!");
    topSearchInput.value = topSearchInput.placeholder = '';
  } else if (topSearchButton.contains(event.target)) {
    // console.log("Clicked on form button!");
    return;
  } else {
    // console.log("Clicked on empty space!");
    topSearchInput.value = '';
    topSearchInput.placeholder = topSearchInputPlaceholder;
    topSearchButton.disabled = true;
  }
});

На этом по скрипту все.

PHP-код

Не забываем определить L-строку для плейсхолдера:

$L['theme-search-hint'] = 'Жми [ / ] для поиска в публикациях и форумах';

… и загрузить наш скрипт, предварительно минифицировав его. Применим функцию минификации из сниппета и добавим в ресурсный файл темы следующий код:

minify_resource($cfg['themes_dir'] . '/' . $theme . '/js/topsearch.js', 'datas/minified/topsearch.min.js', 'js', 94);

Все заработало.

Заключение

С помощью несложного JavaScript-кода мы смогли добавить немного удобства к использованию формы поиска на сайте. Нажатие клавиши / из любой области HTML-документа перебросит курсор в форму поиска, позволит ввести подстроку с клавиатуры и отправить форму нажатием на Enter.

Если пользователь передумает, нажатие на Esc очистит форму и удалит из нее курсор. Аналогичный алгоритм будет применен при использовании мыши.

Как обычно, полный скрипт можно взть из сниппета.

В прошлый раз мы решали вопрос уникализации контента при использовании паджинации в разделе.


Комментарии:
Комментарии отсутствуют

Новый комментарий

Ваш комментарий будет доступен для редактирования 10 минут
Блок пользователя
Регистрация на нашем сайте позволит вам общаться на форумах и получить доступ к другому полезному функционалу
Вы вошли как Гость