Всё началось с того, что наши проекты встали на тропу адаптивного дизайна (responsive design – а то некоторые пишут неправильно adaptive design).
Сейчас, когда макеты рисуются и верстаются, мы постоянно натыкаемся на те или иные грабли. В частности, одними из серьёзных граблей стали адаптивные изображения.
На просторах Рунета и западных блогов сломано немало копий на эту тему и вариантов названо большое множество. В процессе работы мы перепробовали массу решений, в результате чего я плюнул и написал своё решение. Оно похоже на некоторые, предлагаемые другими авторами, однако у него есть свои нюансы.
Основной особенностью моего решения можно назвать то, что оно работает не только с тегом IMG, но и позволяет проводить манипуляции также с background: url(), что значительно упрощает жизнь нашему верстальщику.
<div class="resp"
img-array="{
800:'images/banner_large.jpg',
500:'images/banner_medium.jpg',
0:'images/banner_small.jpg'
}"></div>
<img class="resp2"
src="filename"
img-array="{
800:'images/banner_large.jpg',
500:'images/banner_medium.jpg',
0:'images/banner_small.jpg'
}" />
В данных примерах в DIV изображения помещены в виде CSS стиля background: url(), а у IMG, соответственно, мы используем атрибут SRC, как и положено.
Атрибут img-array содержит в себе альтернативные URL изображений для разных разрешений. Количество альтернативных изображений не ограничено тремя, количество их вы можете легко менять.
$(document).ready(function () {
$(window).resize(function () {
$('.resp').responsibleImages({isImg: false, retinaPrefix: '@2x'});
$('.resp2').responsibleImages({isImg: true, retinaPrefix: '@2x'});
});
$('.resp').responsibleImages({isImg: false, retinaPrefix: '@2x'});
$('.resp2').responsibleImages({isImg: true, retinaPrefix: '@2x'});
});
Во-первых, вешаем вызов нашей функции на событие resize окна браузера. Это нужно для того, если кто-то решит поиграться размером окна и посмотреть на динамически меняющиеся изображения.
Во-вторых, вызываем функцию для проставления текущих изображений.
Как видно из примера, функцию мы вызываем дважды:
Контрольные точки описываются в виде JSON объекта. Где ключ – это контрольная точка, а значение – путь до файла и его название. Контрольная точка 0 должна быть всегда – она управляет значением по-умолчанию. Порядок следования значений не важен, функция отсортирует массив в нужном ей порядке.
Количество контрольных точек и их значение вы выбираете сами.
Перейдём к рассмотрению непосредственно кода jQuery плагина, управляющего адаптивными изображениями в SRC или CSS.
Github репозиторий: https://github.com/kvf77/responsibleImages
/**
* Responsible Images.
* http://www.sesmikcms.ru/blog/read/adaptivnye-izobrazhenija-responsive-images/
*
* Use:
* change background: url():
* <div class="resp"
* img-array="{
* 800:'images/banner_large.jpg',
* 500:'images/banner_medium.jpg',
* 0:'images/banner_small.jpg'
* }">
* </div>
* $('.resp').responsibleImages({isImg: false, retinaPrefix: '@2x'});
*
* change img src:
* <img class="resp2"
* src="filename"
* img-array="{
* 800:'images/banner_large.jpg',
* 500:'images/banner_medium.jpg',
* 0:'images/banner_small.jpg'}" />
* $('.resp2').responsibleImages({isImg: true, retinaPrefix: '@2x'});
*
* options: {
* isImg : true|false, - true - change src, false - change background:url()
* retinaPrefix: {string} - this prefix will be added to the image
* name before dot, if detected retina screen.
* }
*
* @author Kuzma Feskov <kfeskov@gmail.com>
* @copyright Copyright (c) 2015, Kuzma Feskov
*/
(function ($) {
jQuery.fn.responsibleImages = function (options) {
var data = eval('(' + $(this).attr('img-array') + ")");
var arr = [];
jQuery.each(data, function (key, val) {
arr.push(key);
});
arr.sort(function (a, b) {
return b - a
});
img = '';
jQuery.each(arr, function (key) {
if (img == '' && $(window).width() > arr[key]) {
img = data[arr[key]];
}
});
if ('devicePixelRatio' in window && window.devicePixelRatio >= 2) {
img = img.replace(/\.(png|jpg|gif)+$/i, options['retinaPrefix'] + '.$1');
}
if (false !== options['isImg']) {
$(this).attr('src', img);
} else {
$(this).css('background', 'url(' + img + ') no-repeat');
}
};
})(jQuery);
Обратите внимание на финальные строки функции. Именно они занимаются подменой URL изображения. Соответственно, вы можете расширить её возможности, добавляя нужные вам варианты работы с HTML или CSS.
Собственно, в своей работе функция опирается на значение 'devicePixelRatio'. Если это значение больше или равно 2, то мы делаем вывод, что у пользователя retina-подобный экран.
Определив это, функция добавляет к полученному URL изображения префикс, который вы указываете при вызове. В нашем примере URL image/banner_small.jpg превратится в image/banner_small@2x.jpg. То есть префикс дописывается к названию изображения перед расширением.
В комментариях к статье отвечу на любые вопросы и выслушаю пожелания к доработкам функции.
Те, кто встал на нелёгкий путь адаптивной вёрстки, непременно столкнутся с проблемой адаптивных изображений. Мы рассмотрели несколько решений данной проблемы, но в итоге сделали своё. Именно об этом я сегодня и расскажу. Кузьма Феськов 2015-04-01 http://www.sesmikcms.ru/resources/img/000/000/001/img_138_original-640-480.png http://www.sesmikcms.ru/blog/read/adaptivnye-izobrazhenija-responsive-images/