Как получить элемент изображения после вставки с помощью execCommand?

Есть ли способ получить элемент изображения после того, как мы вставим изображение с помощью execCommand? Например

e.execCommand('insertimage',0,'ronaldo.png')

person Najib Razak    schedule 20.09.2012    source источник


Ответы (3)


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

function insertHTML(img) {
  var id = "rand" + Math.random();
  var doc = document.getElementById("editor");
  doc = doc.document ? doc.document : doc.contentWindow.document;
  img = "<img src='" + img + "' id=" + id + ">";

  if(document.all) {
    var range = doc.selection.createRange();
    range.pasteHTML(img);
    range.collapse(false);
    range.select();
  } else {
    doc.execCommand("insertHTML", false, img);
  }
  return doc.getElementById(id);
};
person Kernel James    schedule 03.07.2013
comment
Хорошее предложение, хотя я бы избегал использования document.all. - person Tim Down; 03.07.2013
comment
Но будет ли это работать в IE? В документации для execCommand сказано, что insertHTML не работает в IE. - person Abhishek; 14.10.2015
comment
проблема с этим методом заключается в том, что пользователю нужно будет ВЫБРАТЬ часть текста, прежде чем insertHTML можно будет выполнить... - person oldboy; 13.11.2017
comment
Это решение уязвимо для XSS - person Alvaro Montoro; 27.01.2018
comment
@AlvaroMontoro, можете ли вы объяснить, как он уязвим для XSS? - person David Frick; 07.10.2020

Вы можете использовать тот факт, что браузеры помещают курсор сразу после вставленного изображения и возвращаются оттуда. Для следующего требуется поддержка DOM Range и выбора, что исключает IE ‹= 8, но если это важно, вы можете использовать библиотеку, такую ​​​​как моя собственная Rangy, чтобы заполнить этот пробел.

Демонстрация: http://jsfiddle.net/xJkuj/

Код:

function previousNode(node) {
    var previous = node.previousSibling;
    if (previous) {
        node = previous;
        while (node.hasChildNodes()) {
            node = node.lastChild;
        }
        return node;
    }
    var parent = node.parentNode;
    if (parent && parent.nodeType.hasChildNodes()) {
        return parent;
    }
    return null;
}

document.execCommand("InsertImage", false, "http://placekitten.com/200/300");

// Get the current selection
var sel = window.getSelection();
if (sel.rangeCount > 0) {
    var range = sel.getRangeAt(0);
    var node = range.startContainer;
    if (node.hasChildNodes() && range.startOffset > 0) {
        node = node.childNodes[range.startOffset - 1];
    }

    // Walk backwards through the DOM until we find an image
    while (node) {
        if (node.nodeType == 1 && node.tagName.toLowerCase()  == "img") {
            alert("Found inserted image with src " + node.src);
            break;
        }
        node = previousNode(node);
    }
}
person Tim Down    schedule 27.06.2013
comment
Хороший ответ, но есть ли более простое решение? - person frogatto; 28.06.2013
comment
@ABFORCE: Не то, чтобы я мог придумать. Вызов execCommand() не возвращает ничего более удобного, чем ссылка на вставленное изображение, поэтому вам нужно выполнить некоторый обход DOM. - person Tim Down; 28.06.2013
comment
@ABFORCE: я думаю, что ответ Кернела Джеймса лучше. - person Tim Down; 03.07.2013

Это мой путь:

e.execCommand('insertimage', 0, URI) // image's URI
image=$('img[src="'+URI+'"]').not('.handled').addClass('.handled');

//.not('.handled').addClass('.handled') is needed if there are many images with the same URI
person user3076450    schedule 23.01.2017