Как и зачем использовать медиа-запросы в JavaScript
Медиа-запросы, впервые представленные в CSS3, составляют основной компонент адаптивного веб-дизайна. Приложения должны быть адаптированы к ограничениям каждого типа устройства (например, мобильных телефонов, планшетов, ноутбуков, настольных компьютеров), и медиа-запросы обеспечивают простой способ установки размеров области просмотра в зависимости от размера устройства, на котором работает приложение.
Медиа-запросы позволяют не только изменять размеры области просмотра в зависимости от размера экрана, но также могут помочь вам установить различные свойства стиля для разных устройств, включая цветовые схемы, стили шрифтов, настройки движения и анимацию, границы и интервалы, и почти любой другой CSS.
На первый взгляд некоторые фронтенд-разработчики упускают из виду тот факт, что медиа-запросы также поддерживаются в JavaScript. Хотя они в JavaScript не так популярны, как в CSS, они обеспечивают гибкость и ряд преимуществ, которые могут сделать их лучшим выбором для определенных случаев использования.
Преимущества медиа-запросов в JavaScript
В этот момент вы можете подумать: с какой стати разработчику использовать JS медиа-запросы, когда он может использовать CSS3?
Медиа-запросы JavaScript обладают двумя основными преимуществами.
- Гибкость: вы можете программно включать медиа-запросы в свой код JavaScript, чтобы они запускались только при наступлении определенного события или при выполнении определенных условий. При подходе, основанном только на CSS3, изменения, описанные медиа-запросом, вступают в силу для каждого события изменения размера экрана.
- Удобство: медиа-запросы JavaScript используют тот же синтаксис, к которому вы привыкли при работе с CSS.
Подумайте над этим: что, если вы хотите динамически изменять свойства для разных размеров экрана? Вы все еще можете чесать голову, настаивая на том, что что-то вроде этого будет работать нормально:
// Функция, которую мы хотим выполнить, в зависимости от изменения размера экрана
function foo() {
if (window.innerWidth < 1024) {
/* все, что вы хотите здесь сделать */
}
}
window.addEventListener('changesize', foo);
В блоке кода выше у нас есть оператор «if», основанный на том, что он меньше 1024 (т.е. стандартный размер экрана для дисплеев рабочего стола). Предположительно, этот метод должен запускаться каждый раз, когда приложение работает на устройстве, меньшем, чем настольный компьютер.
К сожалению, этот метод дорогостоящий, потому что он будет срабатывать при каждом изменении размера, а не только тогда, когда пользователь открывает приложение на своем мобильном телефоне или планшете. Правильно - этот метод будет запускаться каждый раз, когда пользователь вручную изменяет размер экрана на настольном компьютере. Чрезмерное количество таких операций в конечном итоге может привести к зависанию приложения.
К счастью, у нас есть идеальный API для обработки динамических ситуаций и дизайна ответов: поприветствуйте matchMedia API.
Как использовать медиа-запросы JavaScript
Вместо того, чтобы прикреплять слушателей к событию изменения размера, как мы это делали в приведенном выше примере, мы можем использовать API matchMedia.
Метод matchMedia()
интерфейса Window по существу присоединяет слушателей к медиа-запросам, но не реагирует на каждое изменение размера окна или экрана, что приводит к значительному повышению производительности. Если мы воспользуемся преимуществом этого метода, мы несем ответственность только за разработку логики, которую мы хотим выполнить для изменения размера экрана, не беспокоясь о других условиях, проверках и оптимизации кода.
Чтобы использовать этот API, мы вызываем и передаем строку медиа-запроса window.matchMedia()
, определяющую размер экрана, на который мы хотим ответить.
// Этот медиа-запрос нацелен на области просмотра, которые имеют минимальную ширину 320 пикселей
const mQuery = window.matchMedia('(min-width: 320px)')
Метод matchMedia () возвращает новый объект MediaQueryList, который мы назвали mQuery в приведенном выше примере. Этот объект хранит информацию о медиа-запросе, примененном к конкретному документу, а также вспомогательные методы для управляемого событиями и немедленного сопоставления. Это позволяет нам запускать настраиваемую логику в начале события изменения размера.
Чтобы выполнить необходимую логику изменения размера, нам нужно проверить window.matches, логическое свойство, которое возвращает «истину», если медиа-запрос совпал, и «ложь», если нет. В нашем примере это свойство сообщает нам, было ли фактическое соответствие указанному условию (т.е. минимальная ширина экрана составляет 320 пикселей).
// Проверяем соответствие медиа-запроса
if (mQuery.matches) {
// Выводим сообщение в консоль
console.log('Media query matched!')
}
Легко, правда? Есть только одна загвоздка: window.matches может выполнить эту проверку только один раз. Чтобы облегчить адаптивный веб-дизайн, мы хотим постоянно проверять любые происходящие изменения. К счастью, есть еще один инструмент, который мы можем объединить с windows.matches, чтобы помочь нам в этом: метод addListener().
Метод addListener()
API matchMedia предоставляет метод addListener()
, а также соответствующий метод removeListener(). Когда мы вызываем addListener()
, мы передаем функцию обратного вызова, которая запускается всякий раз, когда обнаруживает изменение статуса соответствия медиа-запроса. Эта функция обратного вызова - функция, которая должна запускаться при изменении размера:
// Этот медиа-запрос нацелен на области просмотра, которые имеют минимальную ширину 320 пикселей
const mQuery = window.matchMedia('(min-width: 320px)')
function handleMobilePhoneResize(e) {
// Проверяем, верен ли медиа-запрос
if (e.matches) {
// Затем выводим в консоль следующее сообщение
console.log('Media Query Matched!')
}
}
// Настраиваем слушателя событий
mQuery.addListener(handleMobilePhoneResize)
Этот метод позволяет нам реагировать на изменения медиа-запросов и динамически вызывать дополнительные методы по мере необходимости. Эти динамически вызываемые методы могут затем изменять различные свойства документа, такие как стили шрифтов, границы и интервалы, анимацию и многое другое.
Например, если вы хотите добавить динамический стиль шрифта, вы можете добиться этого примерно так:
function changeFontStyleMobile(e) {
// Проверяем соответствие медиа-запроса
if (e.matches) {
// Изменить размер шрифта
document.getElementById("p2").style.color="blue";
var span = document.document.getElementById("span");
span.style.fontSize = "25px";
span.style.fontcolor = "white"; span.style.fontSize = "36px";
}
}
mQuery.addListener(changeFontStyleMobile)
Вывод
Теперь вы должны иметь общее представление о медиа-запросах в JavaScript и о том, как они обеспечивают эффективный адаптивный дизайн. MatchMedia API может помочь вам создать медиа-запрос на JavaScript, а addListener() может позволить вам создать адаптивный кроссплатформенный интерфейс, вызывая функции обратного вызова.
Периодический опрос на предмет изменений состояния документа - это неэффективный и ресурсоемкий подход, который в конечном итоге приведет к задержке приложения. Использование matchMedia() позволяет нам наблюдать за конкретным документом, обнаруживать изменения в условиях медиа-запроса и программно изменять свойства документа в зависимости от статуса медиа-запроса.