动态图像未在DIV中显示

时间:2019-04-10 13:10:42

标签: jquery

当我选择图像时,我希望将图像插入到光标在Div中的位置。我正在使用IE11,这使我无法使用document.execCommand(例如插入HTML或插入图像)。

这是脚本的JS小提琴,带有硬编码的图像。问题出在URL.createObjectURL

https://jsfiddle.net/lvwiseguy/fLkh2by5/9/

$(document).ready(function() {
  $("#getfile").change(function(event) {
    var imageurl = "url(" + URL.createObjectURL(event.target.files[0]) + ")";
    var image = '<p><img src=' + imageurl + '></p>';
    var sel, range, node;
    if (window.getSelection) {
      sel = window.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(image);
        range.insertNode(node);
      }
    } else if (document.selection && document.selection.createRange) {
      document.selection.createRange().pasteHTML(image);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="getfile" value="Go!" />
<div id="divbox" contenteditable="true">The Quick Brown Fox Jumped Over The Lazy Dog</div>

2 个答案:

答案 0 :(得分:1)

由于以下原因,图片未显示:

var imageurl = "url(" + URL.createObjectURL(event.target.files[0]) + ")";

应为:

var imageurl = URL.createObjectURL(event.target.files[0]);

如以下演示所示。

$(document).ready(function() {
  $("#getfile").change(function(event) {
    // Check if a file was selected.
    if (! event.target.files.length) {
      return;
    }
    var imageurl = URL.createObjectURL(event.target.files[0]);
    // For testing purposes, I set the width to 150px.
    var image = '<p><img src=' + imageurl + ' width="150"></p>';
    var sel, range, node;
    if (window.getSelection) {
      sel = window.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(image);
        range.insertNode(node);
      }
    } else if (document.selection && document.selection.createRange) {
      document.selection.createRange().pasteHTML(image);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="getfile" value="Go!" />
<div id="divbox" contenteditable="true">The Quick Brown Fox Jumped Over The Lazy Dog</div>

我还添加了这一部分,当未选择文件/图像时,这将防止错误:

if (! event.target.files.length) {
  return;
}

只是一个建议

为了获得最佳性能和内存使用,MDN recommends使用URL.revokeObjectURL()显式卸载对象URL。因此,在下面的代码段中,我根据他们的example做了MDN建议的操作:

$(document).ready(function() {
  $("#getfile").change(function(event) {
    // Check if a file was selected.
    if (! event.target.files.length) {
      return;
    }
    var img = document.createElement('img');
    img.src = URL.createObjectURL(event.target.files[0]);
    img.onload = function(){
      URL.revokeObjectURL(this.src);
      console.log('Object URL unloaded');
    };
    // For testing purposes, I set the width to 150px.
    var image = '<p><img src=' + img.src + ' width="150"></p>';
    var sel, range, node;
    if (window.getSelection) {
      sel = window.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(image);
        range.insertNode(node);
      }
    } else if (document.selection && document.selection.createRange) {
      document.selection.createRange().pasteHTML(image);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="getfile" value="Go!" />
<div id="divbox" contenteditable="true">The Quick Brown Fox Jumped Over The Lazy Dog</div>

还有一个..

如果未进行选择(在#divbox区域内),则图像将附加到该区域内容的末尾:

$(document).ready(function() {
  $("#getfile").change(function(event) {
    // Check if a file was selected.
    if (! event.target.files.length) {
      return;
    }
    var img = document.createElement('img');
    img.src = URL.createObjectURL(event.target.files[0]);
    img.onload = function(){
      URL.revokeObjectURL(this.src);
      console.log('Object URL unloaded');
    };
    // For testing purposes, I set the width to 150px.
    var image = '<p><img src=' + img.src + ' width="150"></p>';
    var sel, range, node, has_selection;
    if (window.getSelection) {
      sel = window.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(image);
        range.insertNode(node);
        has_selection = true;
      }
    } else if (document.selection && document.selection.createRange) {
      document.selection.createRange().pasteHTML(image);
      has_selection = true;
    }
    if (! has_selection) {
      document.querySelector('#divbox').innerHTML += image;
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="getfile" value="Go!" />
<div id="divbox" contenteditable="true">The Quick Brown Fox Jumped Over The Lazy Dog</div>

更新

  

在IE 11中,无论图像如何插入文本的末尾   光标所在的位置。

很明显,当焦点对准#getfile按钮时,IE 11“丢失”(或重置?)选择数据。

因此,克服这一问题的一种方法是通过mouseleave元素的#divbox事件保存选择 range :(下面的演示基于第三个演示以上)

var _range;
$('#divbox').mouseleave(function(){
  if (window.getSelection) {
    var sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
      _range = window.getSelection().getRangeAt(0);
    }
  }
});

$(document).ready(function() {
  var _range;
  $('#divbox').mouseleave(function(){
    if (window.getSelection) {
      var sel = window.getSelection();
      if (sel.getRangeAt && sel.rangeCount) {
        _range = window.getSelection().getRangeAt(0);
      }
    }
  });
  $("#getfile").change(function(event) {
    // Check if a file was selected.
    if (! event.target.files.length) {
      return;
    }
    var img = document.createElement('img');
    img.src = URL.createObjectURL(event.target.files[0]);
    img.onload = function(){
      URL.revokeObjectURL(this.src);
      console.log('Object URL unloaded');
    };
    // For testing purposes, I set the width to 150px.
    var image = '<p><img src=' + img.src + ' width="150"></p>';
    var node, has_selection;
    if (_range) {
      node = _range.createContextualFragment(image);
      _range.insertNode(node);
      has_selection = true;
    } else if (document.selection && document.selection.createRange) {
      document.selection.createRange().pasteHTML(image);
      has_selection = true;
    }
    if (! has_selection) {
      $('#divbox').append(image);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="getfile" value="Go!" />
<div id="divbox" contenteditable="true">The Quick Brown Fox Jumped Over The Lazy Dog</div>

使用$('#getfile').mouseenter(...)也可以,并且可能还有其他选择(即IE 11问题的解决方法),但是上述方法对我有用。

答案 1 :(得分:0)

这是一个可行的例子

注意:您必须检查选择项是否位于所需的contenteditable中。这样可以防止将图像插入错误的textareacontenteditable

$(document).ready(function() {
  $("#getfile").change(function(event) {
    var imageurl = URL.createObjectURL(event.target.files[0]);
    var image = '<p><img src=' + imageurl + '></p>';
    var sel, range, node;
    
    if (window.getSelection) {
      sel = window.getSelection();
      let divbox = document.getElementById('divbox');
      if (sel.baseNode &&
        sel.baseNode.parentNode == divbox &&
        sel.getRangeAt &&
        sel.rangeCount) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(image);
        range.insertNode(node);
      }
    } else if (document.selection && document.selection.createRange) {
      document.selection.createRange().pasteHTML(image);
    }
    
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="file" id="getfile" value="Go!" />
<div id="divbox" contenteditable="true">The Quick Brown Fox Jumped Over The Lazy Dog</div>