How to get the image element after insert using execCommand?
Asked Answered
S

3

9

Is there any way to get the image element after we insert the image using execCommand? for example

e.execCommand('insertimage',0,'ronaldo.png')
Sucrose answered 20/9, 2012 at 6:48 Comment(0)
A
12

Don't use insertimage, use plain old insertHTML and give the element you are inserting an ID so that you can reference it later. i.e.,

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);
};
Accommodating answered 3/7, 2013 at 3:46 Comment(5)
Good suggestion, although I'd steer clear of using document.all.Goingover
But, will this work in IE? The documentation for execCommand says, insertHTML does not work in IE.Jobholder
the issue with this technique is that the user will need to SELECT some of the text before insertHTML can be executed...Lavinalavine
This solution is vulnerable to XSSMankind
@AlvaroMontoro, can you explain how it is vulnerable to XSS?Phylis
G
6

You can use the fact that browsers place the caret immediately after the inserted image and work back from there. The following requires DOM Range and selection support, which rules out IE <= 8, but if that's important then you can use a library such as my own Rangy to fill that gap.

Demo: http://jsfiddle.net/xJkuj/

Code:

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);
    }
}
Goingover answered 27/6, 2013 at 22:27 Comment(3)
Good answer, But is there any simpler solution?Heroics
@ABFORCE: Not that I can think of. The execCommand() call doesn't return anything as convenient as a reference to the inserted image, so you have to do some DOM traversal.Goingover
@ABFORCE: I think Kernel James's answer is better.Goingover
V
3

This is my way:

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
Vidal answered 23/1, 2017 at 17:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.