Три способа поддержать вставку картинок в поле ввода от разработчиков Яндекс.Почты

в 10:37, , рубрики: javascript, Блог компании Яндекс, Веб-разработка, интерфейсы, котики, Яндекс.Почта, метки: , , ,

Три способа вставки картинок в тело письма в Яндекс.Почте

Не так давно мы подробно рассказывали новые аттачи в Яндекс.Почте. В декабре в у нас появился новый просмоторщик картинок. Работать с изображениями в Почте благодаря этим нововведениям стало действительно проще и удобнее.

Тем не менее, оставалась ещё одна сложность: в связи с браузерными ограничениями изображения нельзя было вставлять прямо в тело письма. Картинку нужно было сохранить на своём компьютере и уже оттуда прикрепить к письму, как любой другой файл.

Мы долго думали над этой проблемой. Можно было использовать java-апплет или flash, но у этих решений были существенные ограничения. Например, при использовании java-апплета нужно будет обязательно разрешать выполнение апплета в браузере. В итоге мы решили использовать новые возможности современных браузеров, такие как Clipboard API, File API и Drag n Drop.

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

Вставка картинок из буфера обмена

До недавнего времени полноценная работа с буфером обмена в веб-приложениях казалась невозможной. Но затем появился новый API, специально предназначенный именно для этого (Clipboard API). Он представляет собой интерфейс для работы с данными из буфера обмена при копировании, вырезании и вставке. Интерфейс достаточно универсальный и работает не только с текстовыми данными, но и с файлами в разных форматах. Но, как это обычно бывает, поддерживается он не всеми браузерами и в разном объёме.

Наиболее полная поддержка на сегодняшний день реализована только в WebKit-браузерах (Safari, Chrome, Яндекс.Браузер). В этих браузерах для событий copy, cut и paste в объекте события есть доступ к объекту clipboardData. У clipboardData есть свойства items (элементы в буфере обмена) и types (типы информации в буфере обмена). Получать или менять информацию из буфера можно при помощи методов getData и setData.

В Chrome (c 18 версии) и Яндекс.Браузере есть доступ к картинкам в буфере обмена при вставке. Делается это примерно так:

    // Элемент с contentEditable
    var el = document.getElementById('editor');

    el.addEventListener('paste', function(e) {
        var clipboard = e.clipboardData;

        if (clipboard && clipboard.items) {
            // В буфере обмена может быть только один элемент
            var item = clipboard.items[0];

            if (item && item.type.indexOf('image/') > -1) {
                // Получаем картинку в виде блоба
                var blob = item.getAsFile();

                if (blob) {
                    // Читаем файл и вставляем его в data:uri
                    var reader = new FileReader();
                    reader.readAsDataURL(blob);

                    reader.onload = function(event) {
                        var img = new Image();
                        img.src = event.target.result;

                        el.appendChild(img);
                    }
                }
            }
        }
    });

Кроме браузеров на движке WebKit, вставка картинкок из буфера обмена также работает в Firefox: там картинки в designMode сразу вставляются в data:uri.

Вставка картинок по публичному URL

Одно из самых простых и привычных действий — скопировать картинку со страницы в интернете и вставить её в письмо — не поддерживается браузерами по умолчанию. В Safari 5+ в объекте clipboardData нет свойства items, но есть массив types, содержащий типы копируемой иформации. И если копируемая картинка уже есть в интернете по публичному урлу, то её тоже получится вставить. При обычной вставке картинок в designMode Safari создает элемент img с фейковым значением аттрибута src (webkit-fake-url://416873AC...). К этому ресурсу никак нельзя получить доступ из JS, поэтому, чтобы фейковая картинка не вставлялась нужно делать preventDefault у объекта события.

    // Элемент с contentEditable
    var el = document.getElementById('editor');

    el.addEventListener('paste', function(e) {
        var clipboard = e.clipboardData;

        if (clipboard && clipboard.types) {
            var types = clipboard.types;

            if (types.indexOf('public.url') > -1) {
                // Останавливаем действие по умолчанию, чтобы не вставлялась картинка с фейковым урлом (webkit-fake-url://416873AC...)
                e.preventDefault();

                // Вставляем картинку
                var img = new Image();
                img.src = clipboard.getData('public.url');

                el.appendChild(img);
            }
        }
    });

Вставка по публичному урлу по умолчанию работает в IE9 и выше.

Вставка перетягиванием

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

    // Элемент с contentEditable
    var el = document.getElementById('editor');

    el.addEventListener('drop', function(e) {
        var dataTransfer = e.dataTransfer;

        if (dataTransfer && dataTransfer.files) {
            var files = dataTransfer.files;
            var len = files.length;

            if (len) {
                for (var i = 0; i < len; i++) {
                    var file = files[i];

                    // Вставляем только картинки
                    if (file.type.indexOf('image/') < 0) continue;

                    var reader = new FileReader();
                    reader.readAsDataURL(file);

                    reader.onload = function(event) {
                        var img = new Image();
                        img.src = event.target.result;

                        el.appendChild(img);
                    };
                }

                e.preventDefault();
            }
        }
    });

Это работает в Firefox, Safari 5.1+, Chrome и Яндекс.Браузере.

В Яндекс.Почте для написания писем с оформлением используется WYSIWYG-редактор TinyMCE. Мы написали для него плагин, объединяющий все решения из этой статьи. Он доступен по адресу github.com/Panya/tinymce_pasteimage.

Автор: Panya

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js