Вы здесь

0

Добрый день, коллеги!

Такой вопрос, я очень долгое время искал различные способы сделать адаптивными картинки(именно, чтобы менялся вес изображения, а не просто резиновое изображение), вставленные в body через редактор. По той или иной причине найденные мной способы и решения оказались не подходящими мне или попросту не работали или работали некорректно.

Короче, принялся я за изобретение велосипеда. Набросал мини модуль, на практике все работает, но так как я не силен в вопросах производительности drupal, то задаю вопрос гуру drupal, нормальное ли моё решение? Или же лучше таким способом ничего не делать, аргументируйте в комментах.

Собственно решение - теория, перед сохранением ноды, я пробегаюсь по массиву body, и нахожу все вставленные изображения, программно делаю для них уменьшенные копии с помощью пресета изображений и с помощью js анализирую размер экрана устройства и меняю адрес на уменьшенную копию.

на практике:

Подключаю js файл, который будет отвечать за смену url изображения

function resp_img_init() {
    $path = drupal_get_path('module', 'resp_img'); //получаем путь к модулю
    $path_to_js = $path . '/js/resp_img_script.js'; //Получаем полный путь к файлу 
    drupal_add_js($path_to_js); //подлючаем файл
}

код модуля:

function resp_img_preprocess_node(&$variables){

    $image_style_name = "450_adaptive";

    $body = $variables['content']['body'][0]['#markup'];
    preg_match_all('#src="([^"]+)"#i', $body, $matches);

    for($i = 0; $i < count($matches[1]); $i++){
        $source = $matches[1][$i];
        $file_name = drupal_basename($source);
        $image_style = image_style_load($image_style_name);
        $image_uri = file_build_uri($file_name);
        $destination = image_style_path($image_style_name, $image_uri);
        $url = "sites/default/files/styles/" . $image_style_name . "/public/" . $file_name;

        if(!is_file($url)){
            image_style_create_derivative($image_style , $image_uri, $destination);
        }
    }
}

собственно беру body, нахожу картинки, подгружаю пресет изображения, и если уже такого фала нет, то создаю в папке с пресетом уменьшенную копию

ну и js:

(function($){

    function adaptive(){
        var $preset_name = "450_adaptive",
            $domen = location.hostname,
            $resolution = 1000;

        if($(window).width() < $resolution) {
            $('#block-system-main .field-name-body img').each(function(){
                var $this = $(this),
                    $src_source = $this.attr("src"),  // http://poligon-drupal/sites/default/files/fotografiya_4.jpg
                    $src_array = $src_source.split("/"),
                    $file_name = $src_array[$src_array.length - 1];

                $this.attr("src", "http://" + $domen + "/sites/default/files/styles/" + $preset_name + "/public/" + $file_name);

            });
        }else{
            $('#block-system-main .field-name-body img').each(function(){
                var $this = $(this),
                    $src_source = $this.attr("src"), // http://poligon-drupal/sites/default/files/fotografiya_4.jpg
                    $src_array = $src_source.split("/"),
                    $file_name = $src_array[$src_array.length - 1];

                $this.attr("src", "http://" + $domen + "/sites/default/files/" + $file_name);

            });
        }
    }

    $(function(){
        adaptive();
    });

    $(window).resize(function(){
        adaptive();
    })
}) (jQuery);

тут если экран мальнекьй, то в адресе, добавляю папку с пресетом, например site.ru/image/image.jpg меняем на site.ru/image/450px/image.jpg

Думаю, принцип понятен, хотелось бы выслушать ваши мысли по такому методу.

Версия Drupal: 
7.x
Вопрос задан 03.03.2016 - 12:14
Аватар пользователя im
im
32

Ответы

1

В Дру мире уже давно сошлись на решении использовать для этой задачи модули Breakpoints и Picture
Вставлять инлайновые картинки можно через CKEditor + WYSIWYG, и даже подключить к этому всему модуль Media.
Подробней почитать можно, например, тут - http://purewebmedia.biz/article/2015/02/25/responsive-inline-images-pict...

Ответ дан 04.03.2016 - 00:10

"картинки можно через CKEditor + WYSIWYG" - а если используется bueditor например?

Комментарий оставлен 04.03.2016 - 09:48

Для BUEditor можно написать свою кнопку (если ещё не написана), которая будет вставлять нужную разметку (или какую-то метку для input filter).
Смысл в том, что решение для адаптивных/респонсив картинок - это элемент picture, и именно к нему и надо идти. Велосипеды тоже хорошо, полезный опыт, но в данном случае вряд ли оправдано.

Комментарий оставлен 04.03.2016 - 11:41
0

Насколько я знаю, если на страницу пришел html с исходной большой картинкой (src="big.jpg), а потом через js она изменена на маленькую (src="min.jpg), то браузер отправит два запроса - и для загрузки большой и для загрузки маленькой. Проверьте этот момент в инструментах разработчика. Например, в хроме. Там есть вкладка network. В ней видны все обращения к серверу.

Можно в src ставить самую маленькую версию картинки - для мобильных. А на js потом заменять на более больших для разных разрешений.
Можно вообще в src ставить ссылку на изображение-заглушку в 1 пиксель, а на js подставлять картинку с нужным разрешением. Но тогда без js вообще не будет видна картинка.

Ответ дан 03.03.2016 - 13:26

проверил, все норм

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

Комментарий оставлен 03.03.2016 - 14:06

Тогда хорошо. Видимо обе картинки будут загружаться если на document.ready адрес подменять. А у вас до.

Комментарий оставлен 03.03.2016 - 20:55