Дата публикации
20 Января 2020
Дата изменения
9 Октября 2020
Уникальных просмотров
13.730

Оглавление

Всем известно что Google отчаянно продвигает свой любимый формат изображений webp, его поддерживают почти все известные браузеры, окромя IE и Safari. Для авто подмены формата изображений на webp, frontend разработчики используют тег picture.

Однако, если вам необходимо сделать аналогичную авто подмену изображений в свойстве background-image, специального тега вы не найдете. Основная задача — не просто подменять изображения, а отдавать только одно, не заставляя грузить оба, т. к. Page Speed Insights будет ныть, найдя изображения в формате jpg. Решение частично было найдено в интернете, частично подсказал мне знакомый товарищ и частично я доработал его, переписав на чистый JavaScript и исправив одну проблему.

Проверка браузера на поддержку Webp

Для начала нам нужна JS функция, которая будет проверять, поддерживает ли браузер формат Webp:

// Проверяем, можно ли использовать Webp формат
function canUseWebp() {
    // Создаем элемент canvas
    let elem = document.createElement('canvas');
    // Приводим элемент к булеву типу
    if (!!(elem.getContext && elem.getContext('2d'))) {
        // Создаем изображение в формате webp, возвращаем индекс искомого элемента и сразу же проверяем его
        return elem.toDataURL('image/webp').indexOf('data:image/webp') == 0;
    }
    // Иначе Webp не используем
    return false;
}

Создав изображение в формате Webp, нам нужно получить его индекс. Результатом метода indexOf() будет либо 0 — если индекс искомого элемента найден, либо -1 — если не найден. Дело в том, что например браузер IE не создаст нам изображение Webp, т. к. он не умеет работать с этим фарматом и выдаст изображение следующего типа —  data:image/png.

Именно на основании этого мы и будем делать проверку на поддержку Webp. Но есть одно но, Firefox не умеет создавать data:image/webp из canvas. Следовательно, в браузере который умеет работать с Webp, на основании работы данной функции мы получим отрицательный ответ её выполнения, что конечно не может нас устраивать. Эту проблему я решил, но для начала, давайте напишем JS код, который будет переключать форматы изображений в свойстве background-image.

Переключатель форматов в background-image

Нам нужно где-то хранить оба формата изображений, чтобы оттуда их цеплять в основное свойство.

Разметка

Мы будем использовать data-атрибуты. По умолчанию указываем в свойстве background-image изображение в формате webp, а в дата атрибутах распологаем оба формата:

<div style="background-image: url('/images/image.webp')" data-bg="/images/image.jpg" data-bg-webp="/images/image.webp"></div>

JavaScript код

Ну и сам скрипт для замены формата изображений:

window.onload = function () {
    // Получаем все элементы с дата-атрибутом data-bg
    let images = document.querySelectorAll('[data-bg]');
    // Проходимся по каждому
    for (let i = 0; i < images.length; i++) {
        // Получаем значение каждого дата-атрибута
        let image = images[i].getAttribute('data-bg');
        // Каждому найденному элементу задаем свойство background-image с изображение формата jpg
        images[i].style.backgroundImage = 'url(' + image + ')';
    }

    // Проверяем, является ли браузер посетителя сайта Firefox и получаем его версию
    let isitFirefox = window.navigator.userAgent.match(/Firefox\/([0-9]+)\./);
    let firefoxVer = isitFirefox ? parseInt(isitFirefox[1]) : 0;

    // Если есть поддержка Webp или браузер Firefox версии больше или равно 65
    if (canUseWebp() || firefoxVer >= 65) {
        // Делаем все то же самое что и для jpg, но уже для изображений формата Webp
        let imagesWebp = document.querySelectorAll('[data-bg-webp]');
        for (let i = 0; i < imagesWebp.length; i++) {
            let imageWebp = imagesWebp[i].getAttribute('data-bg-webp');
            imagesWebp[i].style.backgroundImage = 'url(' + imageWebp + ')';
        }
    }
};

Как обычно, все комментарии прописал в коде. Отдельно отмечу решение для поддержки браузера Firefox. Не идеально — да, но вполне работает и имеет право на жизнь. Поддержка Webp начинается с версии 65, а значит ниже просто не имеет смысла проверять. Вместо foreach, можно использовать функцию forEach — но тогда гуд-бай поддержка IE.

Засим все, если вы скопируете два JS кода выше и сделаете разметку по моему примеру, у вас должны переключаться изображения в инлайновых свойствах background-image.

Благодарность автору

Если по какой-либо причине вы хотите поблагодарить автора данного ресурса, вы можете это сделать одним из удобных для вас способов ниже.

Один из самых популярных способов поблагодарить автора, воспользоваться сервисом Яндекс.Деньги.

Время работы: 0,1087 s
Время запросов: 0,1087 s
Количество запросов: 28
Источник: cache