在上传之前预览图像

Posted

技术标签:

【中文标题】在上传之前预览图像【英文标题】:Preview an image before it is uploaded 【发布时间】:2011-05-26 10:54:01 【问题描述】:

我希望能够在上传之前预览文件(图像)。预览动作应全部在浏览器中执行,无需使用 Ajax 上传图片。

我该怎么做?

【问题讨论】:

请注意,除非您使用 Gears 或其他插件,否则您无法在浏览器中操作图像:code.google.com/p/chromium/issues/detail?id=32276 查看这个纯 javascript 方法,包括它的答案以及 Ray Nicholus 对最终解决方案的评论:***.com/questions/16430016/… 【参考方案1】:

imgInp.onchange = evt => 
  const [file] = imgInp.files
  if (file) 
    blah.src = URL.createObjectURL(file)
  
<form runat="server">
  <input accept="image/*" type='file' id="imgInp" />
  <img id="blah" src="#"  />
</form>

【讨论】:

我做了一个ReactJS implementation of this。奇迹般有效。 @kxc 你应该进行 ajax 调用并将 input.files[0] 作为数据发送,see jQuery's doc。 上传后没有选择文件怎么办?\ @EasyBB 更改图片方向后,如何将其替换为实际上传的图片?我只得到旧图像。 Internet Explorer 版本 20H2evt =&gt; 语法错误 :(.【参考方案2】:

有几种方法可以做到这一点。最有效的方法是在您的<input> 的File 上使用URL.createObjectURL()。将此 URL 传递给 img.src 以告诉浏览器加载提供的图像。

这是一个例子:

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  var loadFile = function(event) 
    var output = document.getElementById('output');
    output.src = URL.createObjectURL(event.target.files[0]);
    output.onload = function() 
      URL.revokeObjectURL(output.src) // free memory
    
  ;
</script>

您也可以使用FileReader.readAsDataURL() 从您的 中解析文件。这将在内存中创建一个字符串,其中包含图像的 base64 表示。

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  var loadFile = function(event) 
    var reader = new FileReader();
    reader.onload = function()
      var output = document.getElementById('output');
      output.src = reader.result;
    ;
    reader.readAsDataURL(event.target.files[0]);
  ;
</script>

【讨论】:

为避免内存问题,您应该在完成 blob 后致电 URL.revokeObjectURL @Apolo 不在这种情况下,请参阅此答案:***.com/a/49346614/2313004 关于您的第一条评论@tfmontague。你确定吗?我只是在使用 readAsDataURL 后复制了 bese64 字符串并在另一个浏览器中打开它并且它可以工作。 @Lonel Lupu - 相信我的回答不正确!还使用了readAsDataURL,并且能够将base64字符转换为图像。 仔细阅读:当使用文件输入上传图像时,它会存储在浏览器的缓存中。 URL.createObjectURL() 将在浏览器上创建一个指向缓存图像的链接。要创建可以存储在数据库中的文件的 base64 字符串,请使用readAsDataURL【参考方案3】:

单线解决方案:

以下代码使用对象 URL,它比数据 URL 更有效地查看大图像(数据 URL 是包含所有文件数据的巨大字符串,而对象 URL 只是引用文件的短字符串内存中的数据):

<img id="blah"    />

<input type="file" 
    onchange="document.getElementById('blah').src = window.URL.createObjectURL(this.files[0])">

生成的 URL 如下:

blob:http%3A//localhost/7514bc74-65d4-4cf0-a0df-3de016824345

【讨论】:

@Raptor 整个文件 API 也是如此...(FileReaderinput.files 等)URL.createObjectURL 是处理用户提交的文件时要走的路,它只创建一个内存中指向用户磁盘上真实文件的符号链接。 @cnlevy 我们如何访问上传的文件?是否只能从您提到的 URL 中获取?具体来说,我正在使用已经支持访问上传文件的烧瓶。这种单线还有其他方法吗? 这个解决方案对我不起作用。图片预览未显示。 美丽。但是使用URL.revokeObjectURL() 清除内存呢? :D @pheianox 这取决于你,因为这不是什么大问题。 “当文档被卸载时,浏览器会自动释放对象 URL;但是,为了获得最佳性能和内存使用,如果有安全时间可以显式卸载它们,则应该这样做”。欲了解更多信息MDN reference【参考方案4】:

这是最简单的方法


在不使用 Ajax 或任何复杂功能的情况下,在将图像从浏览器上传到服务器之前预览图像。


它需要一个“onChange”事件来加载图像。

function preview() 
    frame.src=URL.createObjectURL(event.target.files[0]);
<form>
  <input type="file" onchange="preview()">
  <img id="frame" src=""  />
</form>

预览多张图片click here

【讨论】:

重要提示:如果/当使用此方法时,必须删除对象 URL 以防止内存泄漏。这是通过调用URL.revokeObjectURL(myObjectUrl) 来完成的,其中myObjectUrl 是创建的对象URL(这意味着您需要在设置图像src 之前将对象URL 分配给一个临时变量)。见developer.mozilla.org/en-US/docs/Web/API/URL/…。【参考方案5】:

LeassTaTT 的答案在 FF 和 Chrome 等“标准”浏览器中运行良好。 IE 的解决方案存在但看起来不同。这里对跨浏览器解决方案的描述:

html 中,我们需要两个预览元素,img 用于标准浏览器,div 用于 IE

HTML:

<img id="preview" 
     src="" 
      
     style="display:none; max-width: 160px; max-height: 120px; border: none;"/>

<div id="preview_ie"></div>

在 CSS 中,我们指定以下 IE 特定的东西:

CSS:

#preview_ie 
  FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)
  

在 HTML 中,我们包含标准和 IE 特定的 Javascript:

<script type="text/javascript">
  % include "pic_preview.js" %
</script>  
<!--[if gte IE 7]> 
<script type="text/javascript">
  % include "pic_preview_ie.js" %
</script>

pic_preview.js 是来自 LeassTaTT 答案的 Javascript。将$('#blah') 替换为$('#preview') 并添加$('#preview').show()

现在是 IE 特定的 Javascript (pic_preview_ie.js):

function readURL (imgFile)     
  var newPreview = document.getElementById('preview_ie');
  newPreview.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = imgFile.value;
  newPreview.style.width = '160px';
  newPreview.style.height = '120px';
    

就是这样。适用于 IE7、IE8、FF 和 Chrome。请在IE9中测试并报告。 IE预览的思路是在这里找到的: http://forums.asp.net/t/1320559.aspx

http://msdn.microsoft.com/en-us/library/ms532969(v=vs.85).aspx

【讨论】:

【参考方案6】:

我已经编辑了@Ivan 的答案以显示“没有可用的预览”图像,如果它不是图像:

function readURL(input) 
    var url = input.value;
    var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
    if (input.files && input.files[0]&& (ext == "gif" || ext == "png" || ext == "jpeg" || ext == "jpg")) 
        var reader = new FileReader();

        reader.onload = function (e) 
            $('.imagepreview').attr('src', e.target.result);
        

        reader.readAsDataURL(input.files[0]);
    else
         $('.imagepreview').attr('src', '/assets/no_preview.png');
    

【讨论】:

【参考方案7】:

这是一个多个文件版本,基于 Ivan Baev 的回答。

HTML

<input type="file" multiple id="gallery-photo-add">
<div class="gallery"></div>

JavaScript / jQuery

$(function() 
    // Multiple images preview in browser
    var imagesPreview = function(input, placeToInsertImagePreview) 

        if (input.files) 
            var filesAmount = input.files.length;

            for (i = 0; i < filesAmount; i++) 
                var reader = new FileReader();

                reader.onload = function(event) 
                    $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                

                reader.readAsDataURL(input.files[i]);
            
        

    ;

    $('#gallery-photo-add').on('change', function() 
        imagesPreview(this, 'div.gallery');
    );
);

由于使用了 $.parseHTML,因此需要 jQuery 1.8,这应该有助于缓解 XSS。

这将开箱即用,您需要的唯一依赖项是 jQuery。

【讨论】:

JS Fiddle 版本jsfiddle.net/iffikhan30/f7xozt8q/1 有没有办法用上面的代码把图片包装到div中? 一切皆有可能【参考方案8】:

这是cmlevy answer 的大小改进 - 试试

<input type=file oninput="pic.src=window.URL.createObjectURL(this.files[0])">
<img id="pic" />

【讨论】:

如何获取整个文件路径? @Bbb 它看起来不像典型的路径 - 它看起来像一些临时的“链接”:blob:null/35c35011-111c-4d9e-ac3f-a779e049eb3d【参考方案9】:

是的。这是可能的。

HTML

<input type="file" accept="image/*"  onchange="showMyImage(this)" />
 <br/>
<img id="thumbnil" style="width:20%; margin-top:10px;"  src="" />

JS

 function showMyImage(fileInput) 
        var files = fileInput.files;
        for (var i = 0; i < files.length; i++)            
            var file = files[i];
            var imageType = /image.*/;     
            if (!file.type.match(imageType)) 
                continue;
                       
            var img=document.getElementById("thumbnil");            
            img.file = file;    
            var reader = new FileReader();
            reader.onload = (function(aImg)  
                return function(e)  
                    aImg.src = e.target.result; 
                ; 
            )(img);
            reader.readAsDataURL(file);
            
    

您可以从这里获取Live Demo。

【讨论】:

【参考方案10】:

干净简单 JSfiddle

当您希望事件从 div 或按钮间接触发时,这将很有用。

<img id="image-preview"  style="height:100px; width:100px;"  src="" >

<input style="display:none" id="input-image-hidden" onchange="document.getElementById('image-preview').src = window.URL.createObjectURL(this.files[0])" type="file" accept="image/jpeg, image/png">

<button  onclick="HandleBrowseClick('input-image-hidden');" >UPLOAD IMAGE</button>


<script type="text/javascript">
function HandleBrowseClick(hidden_input_image)

    var fileinputElement = document.getElementById(hidden_input_image);
    fileinputElement.click();
     
</script>

【讨论】:

请注意:我不能对此表示赞赏,但您可以使用 &lt;label&gt; 并避免使用 JavaScript 来完全处理按钮单击。 Trigger File-input with pure HTML/CSS.,它一点也不 hacky。【参考方案11】:

使用 JavaScript (jQuery) 和 HTML5 的多张图片示例

JavaScript (jQuery)

function readURL(input) 
     for(var i =0; i< input.files.length; i++)
         if (input.files[i]) 
            var reader = new FileReader();

            reader.onload = function (e) 
               var img = $('<img id="dynamic">');
               img.attr('src', e.target.result);
               img.appendTo('#form1');  
            
            reader.readAsDataURL(input.files[i]);
           
        
    

    $("#imgUpload").change(function()
        readURL(this);
    );

标记 (HTML)

<form id="form1" runat="server">
    <input type="file" id="imgUpload" multiple/>
</form>

【讨论】:

【参考方案12】:

在 React 中,如果文件在你的 props 中,你可以使用:

props.value instanceof File && (
    <img src=URL.createObjectURL(props.value)/>
)

【讨论】:

【参考方案13】:

使用 jquery 预览多个文件

$(document).ready(function()
    $('#image').change(function()
        $("#frames").html('');
        for (var i = 0; i < $(this)[0].files.length; i++) 
            $("#frames").append('<img src="'+window.URL.createObjectURL(this.files[i])+'"  />');
        
    );
);
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <input type="file" id="image" name="image[]" multiple /><br/>
    <div id="frames"></div>
</body>

【讨论】:

喜欢:为什么? $(this)[0].files > this.files $(this)[0].files --> 给出选择的图像数量或[object FileList]【参考方案14】:

如何创建一个加载文件并触发自定义事件的函数。然后将侦听器附加到输入。这样我们可以更灵活地使用文件,而不仅仅是预览图像。

/**
 * @param domElement input - The input element
 * @param string typeData - The type of data to be return in the event object. 
 */
function loadFileFromInput(input,typeData) 
    var reader,
        fileLoadedEvent,
        files = input.files;

    if (files && files[0]) 
        reader = new FileReader();

        reader.onload = function (e) 
            fileLoadedEvent = new CustomEvent('fileLoaded',
                detail:
                    data:reader.result,
                    file:files[0]  
                ,
                bubbles:true,
                cancelable:true
            );
            input.dispatchEvent(fileLoadedEvent);
        
        switch(typeData) 
            case 'arraybuffer':
                reader.readAsArrayBuffer(files[0]);
                break;
            case 'dataurl':
                reader.readAsDataURL(files[0]);
                break;
            case 'binarystring':
                reader.readAsBinaryString(files[0]);
                break;
            case 'text':
                reader.readAsText(files[0]);
                break;
        
    

function fileHandler (e) 
    var data = e.detail.data,
        fileInfo = e.detail.file;

    img.src = data;

var input = document.getElementById('inputId'),
    img = document.getElementById('imgId');

input.onchange = function (e) 
    loadFileFromInput(e.target,'dataurl');
;

input.addEventListener('fileLoaded',fileHandler)

可能我的代码不如某些用户好,但我想你会明白的。在这里你可以看到example

【讨论】:

【参考方案15】:

以下是工作代码。

<input type='file' onchange="readURL(this);" /> 
<img id="ShowImage" src="#" />

Javascript:

 function readURL(input) 
        if (input.files && input.files[0]) 
            var reader = new FileReader();

            reader.onload = function (e) 
                $('#ShowImage')
                    .attr('src', e.target.result)
                    .width(150)
                    .height(200);
            ;

            reader.readAsDataURL(input.files[0]);
        
    

【讨论】:

【参考方案16】:

试试这个

window.onload = function() 
  if (window.File && window.FileList && window.FileReader) 
    var filesInput = document.getElementById("uploadImage");
    filesInput.addEventListener("change", function(event) 
      var files = event.target.files;
      var output = document.getElementById("result");
      for (var i = 0; i < files.length; i++) 
        var file = files[i];
        if (!file.type.match('image'))
          continue;
        var picReader = new FileReader();
        picReader.addEventListener("load", function(event) 
          var picFile = event.target;
          var div = document.createElement("div");
          div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
            "title='" + picFile.name + "'/>";
          output.insertBefore(div, null);
        );        
        picReader.readAsDataURL(file);
      

    );
  
<input type="file" id="uploadImage" name="termek_file" class="file_input" multiple/>
<div id="result" class="uploadPreview">

【讨论】:

【参考方案17】:

这个解决方案怎么样?

只需将数据属性“data-type=editable”添加到图像标签,如下所示:

<img data-type="editable" id="companyLogo" src="http://www.coventrywebgraphicdesign.co.uk/wp-content/uploads/logo-here.jpg"   />

你的项目的脚本偏离了方向......

function init() 
    $("img[data-type=editable]").each(function (i, e) 
        var _inputFile = $('<input/>')
            .attr('type', 'file')
            .attr('hidden', 'hidden')
            .attr('onchange', 'readImage()')
            .attr('data-image-placeholder', e.id);

        $(e.parentElement).append(_inputFile);

        $(e).on("click", _inputFile, triggerClick);
    );


function triggerClick(e) 
    e.data.click();


Element.prototype.readImage = function () 
    var _inputFile = this;
    if (_inputFile && _inputFile.files && _inputFile.files[0]) 
        var _fileReader = new FileReader();
        _fileReader.onload = function (e) 
            var _imagePlaceholder = _inputFile.attributes.getNamedItem("data-image-placeholder").value;
            var _img = $("#" + _imagePlaceholder);
            _img.attr("src", e.target.result);
        ;
        _fileReader.readAsDataURL(_inputFile.files[0]);
    
;

// 
// IIFE - Immediately Invoked Function Expression
// https://***.com/questions/18307078/jquery-best-practises-in-case-of-document-ready
(

function (yourcode) 
    "use strict";
    // The global jQuery object is passed as a parameter
    yourcode(window.jQuery, window, document);
(

function ($, window, document) 
    "use strict";
    // The $ is now locally scoped 
    $(function () 
        // The DOM is ready!
        init();
    );

    // The rest of your code goes here!
));

See demo at JSFiddle

【讨论】:

【参考方案18】:

我做了一个插件,可以在IE 7+中生成预览效果,感谢互联网,但限制很少。我把它放到了github page,这样更容易得到它

$(function () 
		$("input[name=file1]").previewimage(
			div: ".preview",
			imgwidth: 180,
			imgheight: 120
		);
		$("input[name=file2]").previewimage(
			div: ".preview2",
			imgwidth: 90,
			imgheight: 90
		);
	);
.preview > div 
  display: inline-block;
  text-align:center;


.preview2 > div 
  display: inline-block; 
  text-align:center;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://rawgit.com/andrewng330/PreviewImage/master/preview.image.min.js"></script>
	Preview
	<div class="preview"></div>
	Preview2
	<div class="preview2"></div>

	<form action="#" method="POST" enctype="multipart/form-data">
		<input type="file" name="file1">
		<input type="file" name="file2">
		<input type="submit">
	</form>

【讨论】:

【参考方案19】:

对于多张图片上传(修改@IvanBaev的解决方案)

function readURL(input) 
    if (input.files && input.files[0]) 
        var i;
        for (i = 0; i < input.files.length; ++i) 
          var reader = new FileReader();
          reader.onload = function (e) 
              $('#form1').append('<img src="'+e.target.result+'">');
          
          reader.readAsDataURL(input.files[i]);
        
    

http://jsfiddle.net/LvsYc/12330/

希望这对某人有所帮助。

【讨论】:

【参考方案20】:

这是我的代码,支持IE[6-9]、chrome 17+、firefox、Opera 11+、Maxthon3

   
function previewImage(fileObj, imgPreviewId) 
    var allowExtention = ".jpg,.bmp,.gif,.png";  //allowed to upload file type
    document.getElementById("hfAllowPicSuffix").value;
    var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase();
    var browserVersion = window.navigator.userAgent.toUpperCase();
    if (allowExtention.indexOf(extention) > -1) 
        if (fileObj.files) 
            if (window.FileReader) 
                var reader = new FileReader();
                reader.onload = function (e) 
                    document.getElementById(imgPreviewId).setAttribute("src", e.target.result);
                ;
                reader.readAsDataURL(fileObj.files[0]);
             else if (browserVersion.indexOf("SAFARI") > -1) 
                alert("don't support  Safari6.0 below broswer");
            
         else if (browserVersion.indexOf("MSIE") > -1) 
            if (browserVersion.indexOf("MSIE 6") > -1) //ie6
                document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
             else //ie[7-9]
                fileObj.select();
                fileObj.blur(); 
                var newPreview = document.getElementById(imgPreviewId);

                newPreview.style.border = "solid 1px #eeeeee";
                newPreview.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + document.selection.createRange().text + "')";
                newPreview.style.display = "block";

            
         else if (browserVersion.indexOf("FIREFOX") > -1) //firefox
            var firefoxVersion = parseFloat(browserVersion.toLowerCase().match(/firefox\/([\d.]+)/)[1]);
            if (firefoxVersion < 7) //firefox7 below
                document.getElementById(imgPreviewId).setAttribute("src", fileObj.files[0].getAsDataURL());
             else //firefox7.0+ 
                document.getElementById(imgPreviewId).setAttribute("src", window.URL.createObjectURL(fileObj.files[0]));
            
         else 
            document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
        
     else 
        alert("only support" + allowExtention + "suffix");
        fileObj.value = ""; //clear Selected file
        if (browserVersion.indexOf("MSIE") > -1) 
            fileObj.select();
            document.selection.clear();
        

    

function changeFile(elem) 
    //file object , preview img tag id
    previewImage(elem,'imagePreview')
<input type="file"  id="netBarBig"  onchange="changeFile(this)"  />
<img  src="" id="imagePreview" style="width:120px;height:80px;" />

【讨论】:

【参考方案21】:

默认图片

                @Html.TextBoxFor(x => x.productModels.DefaultImage, new @type = "file", @class = "form-control", onchange = "openFile(event)", @name = "DefaultImage", @id = "DefaultImage" )
                @Html.ValidationMessageFor(model => model.productModels.DefaultImage, "", new  @class = "text-danger" )
                    <img src="~/img/ApHandler.png"  style="height:125px; width:125px" id="DefaultImagePreview"/>
            </div>

 <script>
    var openFile = function (event) 
        var input = event.target;

        var reader = new FileReader();
        reader.onload = function () 
            var dataURL = reader.result;
            var output = document.getElementById('DefaultImagePreview');
            output.src = dataURL;
        ;
        reader.readAsDataURL(input.files[0]);
    ;
</script>

【讨论】:

【参考方案22】:

如果您使用 React,这里有一个解决方案:

import * as React from 'react'
import  useDropzone  from 'react-dropzone'

function imageDropper() 
  const [imageUrl, setImageUrl] = React.useState()
  const [imageFile, setImageFile] = React.useState()

  const onDrop = React.useCallback(
    acceptedFiles => 
      const file = acceptedFiles[0]
      setImageFile(file)

      // convert file to data: url
      const reader = new FileReader()
      reader.addEventListener('load', () => setImageUrl(String(reader.result)), false)
      reader.readAsDataURL(file)
    ,
    [setImageFile, setImageUrl]
  )
  const  getRootProps, getInputProps, isDragActive  = useDropzone( onDrop )

  return (
    <div>
      <div ...getRootProps()>
        imageFile ? imageFile.name : ''
        isDragActive ? <p>Drop files here...</p> : <p>Select image file...</p>
        <input ...getInputProps() />
      </div>
      imageUrl && (
        <div>
          Your image: <img src=imageUrl />
        </div>
      )
    </div>
  )

【讨论】:

【参考方案23】:

在使用 jQuery/javascript 上传之前预览多个图像?

这将一次以缩略图的形式预览多个文件

HTML

<input id="ImageMedias" multiple="multiple" name="ImageMedias" type="file"
accept=".jfif,.jpg,.jpeg,.png,.gif" class="custom-file-input"  value="">                                    
<div id="divImageMediaPreview"></div>

脚本

$("#ImageMedias").change(function () 
    if (typeof (FileReader) != "undefined") 
        var dvPreview = $("#divImageMediaPreview");
        dvPreview.html("");            
        $($(this)[0].files).each(function () 
            var file = $(this);                
                var reader = new FileReader();
                reader.onload = function (e) 
                    var img = $("<img />");
                    img.attr("style", "width: 150px; height:100px; padding: 10px");
                    img.attr("src", e.target.result);
                    dvPreview.append(img);
                
                reader.readAsDataURL(file[0]);                
        );
     else 
        alert("This browser does not support HTML5 FileReader.");
    
);

Working Demo on Codepen

Working Demo on jsfiddle

我希望这会有所帮助。

【讨论】:

这可以在普通的javascript中完成吗?我宁愿不添加所有 jQuery 进行预览......因为我没有使用它来节省加载时间。【参考方案24】:
<img id="blah"    />
<input type="file" name="photo" id="fileinput" />
<script>
$('#fileinput').change(function() 
var url = window.URL.createObjectURL(this.files[0]);
 $('#blah').attr('src',url);
);
</script>

【讨论】:

【参考方案25】:

https://***.com/a/59985954/8784402

ES2017 方式

// convert file to a base64 url
const readURL = file => 
    return new Promise((res, rej) => 
        const reader = new FileReader();
        reader.onload = e => res(e.target.result);
        reader.onerror = e => rej(e);
        reader.readAsDataURL(file);
    );
;

// for demo
const fileInput = document.createElement('input');
fileInput.type = 'file';
const img = document.createElement('img');
img.attributeStyleMap.set('max-width', '320px');
document.body.appendChild(fileInput);
document.body.appendChild(img);

const preview = async event => 
    const file = event.target.files[0];
    const url = await readURL(file);
    img.src = url;
;

fileInput.addEventListener('change', preview);

【讨论】:

【参考方案26】:

对于我的应用程序,使用加密的 GET url 参数,只有这个有效。我总是得到一个TypeError: $(...) is null。 取自https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL

function previewFile() 
  var preview = document.querySelector('img');
  var file    = document.querySelector('input[type=file]').files[0];
  var reader  = new FileReader();

  reader.addEventListener("load", function () 
    preview.src = reader.result;
  , false);

  if (file) 
    reader.readAsDataURL(file);
  
<input type="file" onchange="previewFile()"><br>
<img src=""  >

【讨论】:

【参考方案27】:

这是使用纯javascript在上传之前预览图像的一种非常简单的方法;

//profile_change is the id of the input field where we choose an image
document.getElementById("profile_change").addEventListener("change", function() 

//Here we select the first file among the selected files.
const file = this.files[0];

/*here i used a label for the input field which is an image and this image will 
  represent the photo selected and profile_label is the id of this label */
const profile_label = document.getElementById("profile_label");

//Here we check if a file is selected
if(file) 
    //Here we bring in the FileReader which reads the file info. 
    const reader = new FileReader();
    
    /*After reader loads we change the src attribute of the label to the url of the 
    new image selected*/
    reader.addEventListener("load", function() 
        dp_label.setAttribute("src", this.result);
    )

    /*Here we are reading the file as a url i.e, we try to get the location of the 
    file to set that as the src of the label which we did above*/
    reader.readAsDataURL(file);

else 
    //Here we simply set the src as default, whatever you want if no file is selected.
    dp_label.setAttribute("src", "as_you_want")

);

这里是 HTML;

<label for="profile_change">
            <img title="Change Profile Photo" id="profile_label" 
             src="as_you_want"  style="height: 150px; width: 150px; 
               border-radius: 50%;" >
</label>
<input style="display: none;" id="profile_change" name="DP" type="file" class="detail form-control">

【讨论】:

请用我的回答评论问题。【参考方案28】:
function assignFilePreviews() 
    $('input[data-previewable=\"true\"]').change(function() 
        var prvCnt = $(this).attr('data-preview-container');
        if (prvCnt) 
            if (this.files && this.files[0]) 
                var reader = new FileReader();
                reader.onload = function(e) 
                    var img = $('<img>');
                    img.attr('src', e.target.result);
                    img.error(function() 
                        $(prvCnt).html('');
                    );
                    $(prvCnt).html('');
                    img.appendTo(prvCnt);
                
                reader.readAsDataURL(this.files[0]);
            
        
    );

$(document).ready(function() 
    assignFilePreviews();
);

HTML

<input type="file" data-previewable="true" data-preview-container=".prd-img-prv" />
<div class = "prd-img-prv"></div>

这也可以处理选择了无效类型(例如 pdf)的文件时的情况

【讨论】:

以上是关于在上传之前预览图像的主要内容,如果未能解决你的问题,请参考以下文章

在上传之前预览多个图像

生成 BMP 图像的预览

在使用 FileReader 上传之前预览图像,旋转图像

在上传之前预览多个图像

是否可以在通过表单上传之前预览本地图像?

在phonegap中上传之前的图像预览