tinymce получить информацию об изображении при удалении

Я создал плагин для загрузки изображений для tinymce. ЭТО все работает нормально. Что я хочу сделать, так это удалить изображение с моего сервера, если оно будет удалено пользователем, чтобы у меня не было гигов потерянных файлов.

Я смог прослушать событие nodechange, используя установочную часть процесса инициализации tinymce.

<script src="//tinymce.cachefly.net/4.0/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({
    selector: "textarea",
    plugins: "autoresize",

    toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image jbimages",
    relative_urls: false,
        setup : function(ed) {
                    ed.on("NodeChange", function(e) {
        console.log('change event', e);
               });
}

});</script>

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

Я создал скрипт для этого здесь ЗДЕСЬ

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

Заранее спасибо


person JaChNo    schedule 12.05.2014    source источник


Ответы (3)


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

Итак, в вашей функции «настройки» tinymce.init:

ed.on('KeyDown', function (e) {

    if ((e.keyCode == 8 || e.keyCode == 46) && editor.selection) { // delete & backspace keys

        var selectedNode = editor.selection.getNode(); // get the selected node (element) in the editor

        if (selectedNode && selectedNode.nodeName == 'IMG') {

            MyCallback(selectedNode.src); // A callback that will let me invoke the deletion of the image on the server if appropriate for the image source.
        }
    }
});

Я настроил это в новом плагине, а затем добавил обратный вызов в качестве одной из настроек этого плагина.

person JohnB    schedule 24.12.2014
comment
Интересно… как это работает, когда вы нажимаете Ctrl+A с несколькими элементами… скажем, img и p, а затем удаляете? - person Chinmay; 06.01.2015
comment
Хорошая точка зрения. Короче говоря, это не так. Я попробовал Ctrl + A, и в этом случае selectedNode является тегом body IFrame TinyMCE. Этот метод необходимо сделать более надежным, рекурсивно перебирая дочерние узлы выбранного узла (если это не изображение) и выбирая все изображения для обработки. Я почти уверен, что будут и другие случаи, когда вы можете удалить узел, содержащий одно или несколько изображений. Насколько я вижу, вы не можете выбрать более одного узла (попробовал щелкнуть Ctrl, щелкнуть Shift и выделить мышью) - person JohnB; 07.01.2015
comment
Ага. То, что я закончил, было чем-то очень специфичным для моей реализации. Я подключил свои изображения к URL-адресу (в любом случае я должен поддерживать связи в базе данных). Сервер удаляет все изображения, кроме тех, что в html при отправке. - person Chinmay; 07.01.2015
comment
используя tinymce v4 вместо: var selectedNode = editor.selection.getNode(); использование: var selectedNode = tinymce.activeEditor.selection.getNode(); - person Jaylord Ferrer; 25.01.2018
comment
Это отличное решение, но одно предупреждение. Если вы хотите, чтобы это работало на мобильном телефоне, при использовании «мобильной» конфигурации ключа не добавляйте этот код в качестве плагина, потому что в настоящее время TinyMCE не поддерживает пользовательские плагины для мобильных конфигураций. Когда я говорю «мобильная конфигурация», я имею в виду «tinymce.init({mobile:{theme:’mobile’}});’… - person Charles Robertson; 02.01.2019
comment
И поверьте мне, вам нужно использовать мобильную конфигурацию, если вы планируете добавить поддержку мобильных устройств. Конфигурация рабочего стола просто не подходит для мобильных устройств. Прокрутка, среди многих других основных функций, просто не работает с конфигурацией рабочего стола! - person Charles Robertson; 02.01.2019

Этот вариант был применен к tinyMCE-5, однако он был бы полезен (я думаю).

  1. получение с сервера начальной разметки (значение для редактора);
  2. парсинг по идентификаторам разметки изображений (regexp и т.д.);
  3. сохранение в массиве состояний идентификаторов изображений;
  4. при добавлении новых изображений в редактор мы должны добавить новые идентификаторы в существующее состояние (используйте images_upload_handler);
  5. при отправке данных мы должны снова разобрать значение редактора и сравнить его с существующим состоянием (фактически сравнить два массива);
  6. вызовите api.deleteImages для отсутствующих идентификаторов.

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

person Michael    schedule 26.01.2021

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

init_instance_callback: function (editor) {
    //console.log("tinymce " + editor.id + " init finished.");

    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

    var observer = new MutationObserver(function (mutations, instance) {
        var addedImages = new Array();
        $.each(mutations, function (index, mutationRecord) {
            for (var i = 0; i < mutationRecord.addedNodes.length; i++) {
                var currentNode = mutationRecord.addedNodes[i];
                if (currentNode.nodeName == 'IMG' && currentNode.className != "mce-clonedresizable") {
                    if (addedImages.indexOf(currentNode.src) >= 0) continue;

                    addedImages.push(currentNode.getAttribute("src"));
                    continue;
                }

                var imgs = $(currentNode).find('img');
                for (var j = 0; j < imgs.length; j++) {
                    if (addedImages.indexOf(imgs[j].src) >= 0) continue;

                    addedImages.push(imgs[j].getAttribute("src"));
                }
            }
        });

        var removedImages = new Array();
        $.each(mutations, function (index, mutationRecord) {
            for (var i = 0; i < mutationRecord.removedNodes.length; i++) {
                var currentNode = mutationRecord.removedNodes[i];
                if (currentNode.nodeName == 'IMG' && currentNode.className != "mce-clonedresizable") {
                    if (removedImages.indexOf(currentNode.src) >= 0) continue;

                    removedImages.push(currentNode.getAttribute("src"));
                    continue;
                }

                var imgs = $(currentNode).find('img');
                for (var j = 0; j < imgs.length; j++) {
                    if (removedImages.indexOf(imgs[j].src) >= 0) continue;

                    removedImages.push(imgs[j].getAttribute("src"));
                }
            }
        });

        for (var i = 0; i < removedImages.length; i++) {
            var imageSrc = removedImages[i];
            if (addedImages.indexOf(imageSrc) >= 0) continue;

            if (confirm("delete image from server?\n" + imageSrc)) {
                //delete image from server.
            }
        };
    });
    
    observer.observe(editor.getBody(), {
        childList: true,
        subtree: true
    });
}
person happyexplorer    schedule 23.06.2020