input[type=file]
选中的图片文件呢,一般的做法,是将图片文件异步上传到服务器,获取它在服务器的url,再将这个url赋值给一个img元素的src属性来实现的,这种做法往往会在服务器端产生大量的临时资源,而且还浪费了流量。那么如何不借助服务器,在本地实现图片的预览功能呢?对于现代浏览器,我们可以使用HTML5的File API,而对于不支持它们的IE9及其以下版本我们可以借助IE的滤镜来实现。
实现说起来也很简单,通过FileReader对象的readAsDataURL()方法,将图片文件转化为base64字符串,再将其赋值给img的src属性,即可实现图片文件的预览,另外我们可以通过监听img元素的onload事件,来获得图片文件的实际大小。浏览器的支持情况可以参考这里。
- //www.bcty365.com
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- .preview-container {
- position: relative;
- width: 200px;
- height: 200px;
- background-color: #eee;
- }
- .preview-container img {
- display: none;
- position: absolute;
- }
- </style>
- </head>
- <body>
- <input type="file">
- <div class="preview-container">
- <img>
- </div>
- <script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
- <script>
- var previewrWidth = 200;
- var previewrHeight = 200;
- var $img = $('img');
- $('input[type=file]').change(function() {
- var reader = new FileReader();
- reader.onload = function(e) {
- $img.prop('src', e.target.result);
- }
- reader.readAsDataURL(this.files[0]);
- $('img').load(function() {
- var size = autoSize(this.naturalWidth, this.naturalHeight);
- $(this).css({
- width: size.width,
- height: size.height,
- top: (previewrHeight - size.height) / 2,
- left: (previewrWidth - size.width) / 2
- }).show();
- });
- });
- function autoSize(width, height) {
- var scale = width / height;
- if (scale >= previewrWidth / previewrHeight) {
- height = previewrWidth / scale;
- width = previewrWidth;
- } else {
- width = previewrHeight * scale;
- height = previewrHeight;
- }
- return {
- width: width,
- height: height
- }
- }
- </script>
- </body>
- </html>
对于IE9及其以下版本我们可以通过IE的滤镜来实现同样的功能,首先通过选中input[type=file]
的文本区域来获取选中文件的本地路径,再将其赋值给div元素的filter,即可实现本地预览,但是为了获得图片文件的实际宽高,我们还需要一个额外的img元素,通过设置它的filter来获取。
- //www.bcty365.com
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style>
- .preview-container {
- position: relative;
- width: 200px;
- height: 200px;
- background-color: #eee;
- }
- .preview-container .preview {
- display: none;
- position: absolute;
- }
- .preview-container .fake {
- filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image);
- }
- </style>
- </head>
- <body>
- <input type="file">
- <div class="preview-container">
- <div class="preview"></div>
- <img class="fake">
- </div>
- <script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
- <script>
- var previewrWidth = 200;
- var previewrHeight = 200;
- var $img = $('.preview');
- var $fakeImg = $('.fake');
- $('input[type=file]').change(function() {
- this.select();
- this.blur();
- var src = document.selection.createRange().text;
- $fakeImg.show();
- var fakeImg = $fakeImg[0];
- fakeImg.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = src;
- var size = autoSize(fakeImg.offsetWidth, fakeImg.offsetHeight);
- $fakeImg.hide();
- $img.css({
- width: size.width,
- height: size.height,
- top: (previewrHeight - size.height) / 2,
- left: (previewrWidth - size.width) / 2,
- filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="' + src + '"'
- }).show();
- });
- function autoSize(width, height) {
- var scale = width / height;
- if (scale >= previewrWidth / previewrHeight) {
- height = previewrWidth / scale;
- width = previewrWidth;
- } else {
- width = previewrHeight * scale;
- height = previewrHeight;
- }
- return {
- width: width,
- height: height
- }
- }
- </script>
- </body>
- </html>