上传前预览图像的多种方法 技术背景 在前端开发中,经常会遇到需要在用户上传图像之前进行预览的需求。这可以提升用户体验,让用户在上传之前确认所选的图像是否正确。实现图像预览的方法有多种,下面将详细介绍不同的实现方式。
实现步骤 使用 URL.createObjectURL() 这是一种高效的方法,通过 URL.createObjectURL()
为选择的文件创建一个临时的 URL,然后将该 URL 赋值给 img
元素的 src
属性。
1 2 3 4 5 6 7 8 9 10 11 <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 ) } }; </script >
使用 FileReader.readAsDataURL() 该方法将文件解析为 Base64 编码的字符串,然后将该字符串赋值给 img
元素的 src
属性。
1 2 3 4 5 6 7 8 9 10 11 12 <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 >
单文件预览 以下是一个简洁的单文件预览代码示例:
1 2 <input type ="file" oninput ="pic.src=window.URL.createObjectURL(this.files[0])" > <img id ="pic" />
多文件预览 可以使用 JavaScript 或 jQuery 实现多文件预览。以下是使用 jQuery 的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <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 > <script > $(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])+'" width="100px" height="100px"/>' ); } }); }); </script > </body >
React 中的图像预览 在 React 中,可以使用 URL.createObjectURL()
实现图像预览:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 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) 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 > ) }
核心代码 以下是一个通用的 JavaScript 函数,用于实现图像预览:
1 2 3 4 5 6 7 8 9 10 function imagePreviewFunc (that, previewerId ) { let files = that.files previewerId.innerHTML ='' for (let i = 0 ; i < files.length ; i++) { let imager = document .createElement ("img" ); imager.src = URL .createObjectURL (files[i]); previewerId.append (imager); } }
对应的 HTML 代码:
1 2 3 4 5 6 7 8 9 <input accept ="image/*" type ='file' id ="imageInput_1" onchange ="imagePreviewFunc(this, imagePreview_1)" /> <div id ="imagePreview_1" > This Div for Single Image Preview</div > <hr /> <input class ="form-control" accept ="image/*" type ='file' id ="imageInput_2" multiple ="true" onchange ="imagePreviewFunc(this, imagePreview_2)" /> <div id ="imagePreview_2" > This Div for Multiple Image Preview</div >
最佳实践 内存管理 :使用 URL.createObjectURL()
时,在图像加载完成后调用 URL.revokeObjectURL()
释放内存。兼容性处理 :不同浏览器对文件读取和预览的支持可能不同,需要进行兼容性处理,例如处理 IE 浏览器的特殊情况。错误处理 :在读取文件或设置图像 src
属性时,要考虑可能出现的错误,如文件类型不支持等情况。常见问题 文件类型验证 :在预览图像之前,需要验证文件类型是否为图像类型,避免预览非图像文件。可以通过检查文件的 type
属性来实现。跨浏览器兼容性 :不同浏览器对 FileReader
和 URL.createObjectURL()
的支持可能存在差异,需要进行兼容性测试和处理。例如,IE 浏览器需要使用不同的方法来实现图像预览。内存泄漏 :如果使用 URL.createObjectURL()
创建的对象 URL 没有及时释放,可能会导致内存泄漏。因此,在图像加载完成后,要调用 URL.revokeObjectURL()
释放内存。