蓝子 發表於 2020-9-11 16:33:00

HTML5 实现图片预览和查看原图

<p>html5从一开始就给开发者很多的期待,提供众多新的API,不用再想以前一样,为了实现某个功能写很多的代码。在以前,如果要实现图片预览会怎么做呢,因为为了安全的原因,web端的js是不能读取文件的本地真实路径的,那么只能将图片上传到服务器上,然后再拿到图片的链接,这样才能实现图片预览。而服务器呢,比如有两个文件夹,一个是临时文件夹,一个是正式文件夹,临时文件夹会定时进行清理,正式文件夹是用户确认使用的图片存储的位置。</p>
<p>&nbsp;</p>
<h2>1. fileReader</h2>
<p>现在html5提供的API不再让图片预览那么麻烦,FileReader提供了很多的方法来进行图片预览和文本读取,同时也提供了一整套完整的事件来捕获文件的状态,如下:</p>
<p><strong>FileReader接口的方法</strong>&nbsp;FileReader接口有4个方法,其中3个用来读取文件,另一个用来中断读取。无论读取成功或失败,方法并不会返回读取结果,这一结果存储在result属性中。</p>
<table>
<tbody>
<tr>
<td>方法名</td>
<td>参数</td>
<td>描述</td>
</tr>
<tr>
<td>readAsBinaryString</td>
<td>file</td>
<td>将文件读取为二进制编码</td>
</tr>
<tr>
<td>readAsText</td>
<td>file[, encoding]</td>
<td>按照格式将文件读取为文本,encode默认为UTF-8</td>
</tr>
<tr>
<td>readAsDataURL</td>
<td>file</td>
<td>将文件读取为DataUrl</td>
</tr>
<tr>
<td>abort</td>
<td>(none)</td>
<td>终端读取操作</td>
</tr>
</tbody>
</table>
<p><strong>FileReader接口事件</strong>&nbsp;FileReader接口包含了一套完整的事件模型,用于捕获读取文件时的状态。</p>
<table>
<tbody>
<tr>
<td>事件</td>
<td>描述</td>
</tr>
<tr>
<td>onabort</td>
<td>中断</td>
</tr>
<tr>
<td>onerror</td>
<td>出错</td>
</tr>
<tr>
<td>onloadstart</td>
<td>开始</td>
</tr>
<tr>
<td>onprogress</td>
<td>正在读取</td>
</tr>
<tr>
<td>onload</td>
<td>成功读取</td>
</tr>
<tr>
<td>onloadend</td>
<td>读取完成,无论成功失败</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h2>2. 使用 fileReader 读取图片</h2>
<p>从上面的表格中,我们可以大致了解fileReader提供哪些方法和事件,不过本文主要是讲解图片的读取,那么我们就是用readAsDataURL()就可以了。不过,在进行这一切之前,我们必须检测当前的浏览器是否支持HTML5的fileReader,别进行了一系列的处理和操作,结果js报错,说fileReader没有定义。就好像对一个女孩儿又亲又啃,马上要提枪上马了,结果发现这是个纯爷们。</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">if(!(<span class="hljs-built_in">window.FileReader &amp;&amp; <span class="hljs-built_in">window.File &amp;&amp; <span class="hljs-built_in">window.FileList &amp;&amp; <span class="hljs-built_in">window.Blob)){
    show.innerHTML = ‘您的浏览器不支持fileReader‘;
    upimg.setAttribute(‘disabled‘, ‘disabled‘);
    <span class="hljs-keyword">return <span class="hljs-literal">false;
}
</span></span></span></span></span></span></span></code></pre>
<p>好的,让我们先看下demo演示:【狠狠点击这里】</p>
<h3>2.1 读取单张图片</h3>
<p>使用input控件读取文件,然后监听这个控件的change事件,若读取的文件个数大于零,那么就进行下一步的操作:</p>
<pre><code class="hljs php">&lt;input type=<span class="hljs-string">"file" id=‘upimg‘ /&gt;
<span class="hljs-keyword">var</span> upimg = document.querySelector(‘<span class="hljs-comment">#upimg‘);
upimg.addEventListener(‘change‘, <span class="hljs-function"><span class="hljs-keyword">function<span class="hljs-params">(e){
    <span class="hljs-keyword">var</span> files = this.files;
    <span class="hljs-keyword">if(files.length){
      <span class="hljs-comment">// 对文件进行处理,下面会讲解checkFile()会做什么
      checkFile(this.files);
    }
});
</span></span></span></span></span></span></span></code></pre>
<p>现在我们只能选取一张图片,针对选取的这张图片,我们使用fileReader进行图片的处理</p>
<pre><code class="hljs javascript"><span class="hljs-comment">// 图片处理
<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">checkFile(<span class="hljs-params">files){
    <span class="hljs-keyword">var file = files[<span class="hljs-number">0];
    <span class="hljs-keyword">var reader = <span class="hljs-keyword">new FileReader();
    <span class="hljs-comment">// show表示&lt;<span class="hljs-comment">div</span><span class="hljs-comment"> id=‘show‘&gt;&lt;/<span class="hljs-comment">div</span><span class="hljs-comment">&gt;,用来展示图片预览的
    <span class="hljs-keyword">if(!<span class="hljs-regexp">/image\/\w+/.test(file.type)){
      show.innerHTML = <span class="hljs-string">"请确保文件为图像类型";
      <span class="hljs-keyword">return <span class="hljs-literal">false;
    }
    <span class="hljs-comment">// onload是异步操作
    reader.onload = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e){
      show.innerHTML = ‘&lt;img src=<span class="hljs-string">"‘+e.target.result+‘" alt=<span class="hljs-string">"img"&gt;‘;
    }
    reader.readAsDataURL(file);
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>现在,就可以在页面上看到图片了。审查元素后我们能够看到,图片地址是个base64的字符串,如:‘data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sA......‘</p>
<h3>2.2 读取多张图片</h3>
<p>多张图片和单张图片的处理过程很相似,但是也还是有区别的,因为reader.onload()是一个异步的操作,进行下一步的操作时必须在这个方法里</p>
<pre><code class="hljs javascript">&lt;input type=<span class="hljs-string">"file" id=‘upimg‘ multiple /&gt;
<span class="hljs-comment">// change事件没有改动
<span class="hljs-comment">// 图片处理
<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">checkFile(<span class="hljs-params">files){
    <span class="hljs-keyword">var html=‘‘, i=<span class="hljs-number">0;
    <span class="hljs-keyword">var func = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">){
      <span class="hljs-keyword">if(i&gt;=files.length){
            <span class="hljs-comment">// 若已经读取完毕,则把html添加页面中
            show.innerHTML = html;
      }
      <span class="hljs-keyword">var file = files;
      <span class="hljs-keyword">var reader = <span class="hljs-keyword">new FileReader();

      <span class="hljs-comment">// show表示&lt;div id=‘show‘&gt;&lt;/div&gt;,用来展示图片预览的
      <span class="hljs-keyword">if(!<span class="hljs-regexp">/image\/\w+/.test(file.type)){
            show.innerHTML = <span class="hljs-string">"请确保文件为图像类型";
            <span class="hljs-keyword">return <span class="hljs-literal">false;
      }
      reader.onload = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e){
            html += ‘&lt;img src=<span class="hljs-string">"‘+e.target.result+‘" alt=<span class="hljs-string">"img"&gt;‘;
            i++;
            func(); <span class="hljs-comment">//选取下一张图片
      }
      reader.readAsDataURL(file);
    }
    func();
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<h3>2.3 拖拽拉去图片</h3>
<p>拖拽事件,采用的是HTML5中的drag和drop,本文不着重介绍这两个方法,仅仅是讲解如何使用。</p>
<p>首先,我们设置一块拖拽区域,告诉用户应该把图片拖拽到什么位置:</p>
<pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">style&gt;<span class="css">
    <span class="hljs-selector-class">.drag{ <span class="hljs-attribute">width: <span class="hljs-number">400px;<span class="hljs-attribute">height: <span class="hljs-number">100px;<span class="hljs-attribute">border: <span class="hljs-number">1px dotted <span class="hljs-number">#333; <span class="hljs-attribute">text-align: center; <span class="hljs-attribute">line-height: <span class="hljs-number">100px; <span class="hljs-attribute">color: <span class="hljs-number">#aaa; <span class="hljs-attribute">display: inline-block;}
    <span class="hljs-selector-class">.drag_hover{<span class="hljs-attribute">background: <span class="hljs-number">#FAD6F9;}
<span class="hljs-tag">&lt;/<span class="hljs-name">style&gt;
<span class="hljs-tag">&lt;<span class="hljs-name">span <span class="hljs-attr">class=<span class="hljs-string">‘drag‘ <span class="hljs-attr">id=<span class="hljs-string">"drag"&gt;拖拽区域<span class="hljs-tag">&lt;/<span class="hljs-name">span&gt;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>然后,我们给drag区域绑定上拖拽事件</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">var drag = <span class="hljs-built_in">document.getElementById(‘drag‘);
drag.addEventListener(‘dragenter‘, <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e){
    <span class="hljs-comment">// 拖拽鼠标进入区域时
    <span class="hljs-keyword">this.className = ‘drag_hover‘;
}, <span class="hljs-literal">false);
drag.addEventListener(‘dragleave‘, <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e){
    <span class="hljs-comment">// 拖拽鼠标离开区域时
    <span class="hljs-keyword">this.className = ‘‘;
}, <span class="hljs-literal">false);
drag.addEventListener(‘drop‘, <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e){
    <span class="hljs-comment">// 当鼠标执行‘放’的动作时,执行读取文件操作
    <span class="hljs-keyword">var files = e.dataTransfer.files;
    <span class="hljs-keyword">this.className = ‘‘;
    <span class="hljs-keyword">if (files.length != <span class="hljs-number">0) {
      checkFile(files);
    };
    e.preventDefault();
}, <span class="hljs-literal">false)
drag.addEventListener(‘dragover‘, <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">e){
    <span class="hljs-comment">// 当对象拖动到目标对象时触发
    e.dataTransfer.dragEffect = ‘copy‘;
    e.preventDefault();
}, <span class="hljs-literal">false);
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>这里有个需要注意的地方:<strong>需要给dragover和drop添加阻止默认事件,否则浏览器会采用file:///的方式打开文件</strong>。drop事件执行后就是进行checkFile(),后续的操作与使用input的操作一样。</p>
<p><span style="position: relative; left: -100000px">广州vi设计公司 http://www.maiqicn.com</span> <span style="position: relative; left: -100000px">我的007办公资源网 https://www.wode007.com</span></p>
<h2>3. 点击查看原图</h2>
<p>当我们点击图片查看原图时,需要知道图片的原始尺寸。可能你会想到使用img.width和img.height,对,这个确实能获取到图片的长和宽,但是,这个长和宽是经过css修饰后的,不是图片原始的尺寸。如果要获取图片的原始尺寸,我们可以在js中创建一个imgs对象,然后把那张图片的地址给了这个imgs对象,然后获取imgs对象的尺寸,这样就能获取到图片的原始尺寸了。</p>
<pre><code class="hljs javascript"><span class="hljs-keyword">var imgs = <span class="hljs-keyword">new Image();
imgs.src = img.src; <span class="hljs-comment">// 给新的img对象链接
<span class="hljs-built_in">console.log(imgs.width, imgs.height);
</span></span></span></span></code></pre>
<p>而在HTML5中,我们不用再那么麻烦的创建一个无用的img对象了,直接使用给出的属性即可。</p>
<pre><code class="hljs javascript"><span class="hljs-built_in">console.log(img.naturalWidth);<span class="hljs-comment">// 获取图片的原始的宽度
<span class="hljs-built_in">console.log(img.naturalHeight); <span class="hljs-comment">// 获取图片的原始的高度
</span></span></span></span></code></pre>
<p>获取到图片的原始尺寸后,就能做出‘查看原图’的效果了。</p><br><br>
来源:https://www.cnblogs.com/qianxiaox/p/13652475.html
頁: [1]
查看完整版本: HTML5 实现图片预览和查看原图