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

一、页面元素只有三个简单元素:

<input id="upimg" type="file">
<div class="dragarea" id="dragimg">拖拽区域</div>
<div class="show" id="showimg"></div><!--预览图片区域-->

二、添加简单的样式:

<style type="text/css">
  .dragarea{
  	width:300px;
    height:100px;
    background:#ddd;
    text-align:center;
    line-height:100px;
  }
  .drag_hover{
	background:rgba(0,0,0,.4) !important;
  }
  .item{
  	width:300px;
    height:100px;
	float:left;
	margin-right:30px;
	margin-bottom:50px;
  }
  .item > img{
  	height:auto;
    width:100%;
  }
  .big{
	position: fixed;
    top: 100px;
    left: 0px;
  }
</style>

页面的样子:

172233_Mnde_2555747.png

三、javascript的编写:

var Upload = (function(){
  	var upimg = document.getElementById("upimg");
    var dragimg = document.getElementById("dragimg");
    var showimg = document.getElementById("showimg");
    
    function init(){
      if(!(window.FileReader && window.File 
           && window.FileList && window.Blob)){
         showimg.innerHTML="您的浏览器不支持FileReader";
        return false;
      }
      handler();
    }
    function handler(){
      upimg.addEventListener("change",function(e){
      	var files = this.files;
        if(files.length){
          checkFiles(files);
        }
      });
	  dragimg.addEventListener("dragenter",function(e){
		this.className += " drag_hover";
	  },false);
	  dragimg.addEventListener("dragleave",function(e){
		this.className = "dragarea";
	  },false);
	  dragimg.addEventListener("drop",function(e){
		var files = e.dataTransfer.files;
		this.className = "dragarea";
		if(files.length !=0){
			checkFiles(files);
		}
		e.preventDefault();//阻止事件默认动作的执行
	  },false);
	  dragimg.addEventListener("dragover",function(e){
		e.dataTransfer.dropEffect = "copy";
		e.preventDefault();
	  },false);
	  showimg.addEventListener("click",function(e){
		var target = e.target;
		if(target.tagName.toUpperCase() == "IMG"){
			var parent = target.parentNode;
			var items = this.childNodes;
			var big = parent.className.indexOf("big") >0;
			for(var i=0;i<items.length;i++){
				items[i].className = "item";
				items[i].firstElementChild.style.cssText="";
			}
			if(!big){
				target.style.cssText="width:"+target.naturalWidth+"px;height:"+target.naturalHeight+"px";
				parent.className +=" big";
			}
		} 
	  },false);
    }
    function checkFiles(files){
      if(files.length != 0){
         var html = "";
         var i=0,j=showimg.childElementCount;
         var func = function(){
              if(files[i]){
					var x = parseInt((i+j)/4)*50;
                	var reader = new FileReader();
                if(!/image\/\w+/.test(files[i].type)){
                  showimg = "请确保为图像类型";
                  return false;
                }
                reader.onload = function(e){
                   html += '<div class="item" style="margin-top:'+x+'px;"><img src="'+e.target.result+'"></img></div>';
                  i++;
                  func();
                }
                reader.readAsDataURL(files[i]);
               
              }else{
              	showimg.innerHTML +=html;
              }			
      	}
        func();
      }
    }
  return {
    init:init
  }  
})();
Upload.init();

四、说明学习过程中重点理解的几点:

1、这里的javascript的整体结构为:

var xxx=(function(){
 function init(){...}
 return {
   init:init
 }
})();
xxx.init();

定义了xxx对象,并用init()方法作为执行对象方法的入口。xxx就有点像java中的类,init()就像这个类的构造方法。xxx对象是一个Function,并用小括号括起来是为了将这个Function视为一个表达式,后面又紧跟一个小括号代表函数立即执行。

注意:在全局调用了init()方法,而该方法是在一个函数中的,要知道全局无法访问函数内部的变量或者方法,所以这里将init方法return,全局才可以访问。

另外两种写法:

使用this关键字

var xxx=function(){
   this.init = function(){..}
};
var exmple = new xxx;
exmple.init();

闭包

var xxx=function(){
  var init = function(){...}
  return init;
}
var init = xxx();
init();

这里调用的时候写成var xxx= new xxx;效果是一样的。

2、addEventListener方法第三个参数,代表事件的捕获和冒泡。

true:事件捕获,事件从最不精确的对象(document 对象)开始触发,然后到最精确,顺序document——>body——>div——>目标元素;

false:事件冒泡,事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发,和上面的顺序相反。

3、拖拽事件:

dragdrop:拖放完成,也就是鼠标拖入对象并在拖放区域释放。
dragenter:拖放进入,也就是鼠标拖放对象进入拖放区域。
dragleave:离开拖放区域。
dragover:拖放对象悬浮于拖放区域,在拖放区域内移动时多次触发。

这个例子中我只在dragenter和dragleave事件中做了背景颜色的切换。

dragover中有个dataTransfer,对其的介绍:

DataTransfer

拖拽数据传递对象,一般使用方式event.dataTransfer。

dataTransfer . dropEffect [ = value ]

拖拽效果,可选值:“none”, “copy”, “copyLink”, “copyMove”, “link”, “linkMove”, “move”, “all”, and “uninitialized”。

dataTransfer . items

拖拽的数据集合,是一个数组。

dataTransfer . setDragImage (element, x, y)

Uses the given element to update the drag feedback, replacing any previously specified feedback.

英文有点拗口,就是拖拽过程中定义一个元素替换原有的,可以看到拖拽元素跟随的效果。

dataTransfer . addElement (element)

Adds the given element to the list of elements used to render the drag feedback.

dataTransfer . types

Returns a DOMStringList listing the formats that were set in the dragstart event. In addition, if any files are being dragged, then one of the types will be the string “Files”.

data = dataTransfer . getData (format)

Returns the specified data. If there is no such data, returns the empty string.

获取自定义的数据格式,如ev.dataTransfer.getData("text");通常是配合ev.dataTransfer.setData使用。

dataTransfer . setData (format, data)

Adds the specified data.

添加自定义数据格式,如ev.dataTransfer.setData("text", ev.target.innerHTML);有点像jquery里面的data

dataTransfer . clearData ( [ format ] )

 

Removes the data of the specified formats. Removes all data if the argument is omitted.

清除自定义的数据格式及其数据。

dataTransfer . files

Returns a FileList of the files being dragged, if any.

拖拽的文件列表对象。

那么drop事件中的e.dataTransfer.files也不难理解了。

4、事件的preventDefault()方法:

该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。例如,如果 type 属性是 "submit",在事件传播的任意阶段可以调用任意的事件句柄,通过调用该方法,可以阻止提交表单。注意,如果 Event 对象的 cancelable 属性是 fasle,那么就没有默认动作,或者不能阻止默认动作。无论哪种情况,调用该方法都没有作用。

5、javascript的style.cssText:

可以像jquery中的css()方法一样用一行代码添加多种样式,只是会覆盖之前的样式,所以在使用cssText的时候可以这样写 obj.style.cssText +="width:30px;height:40px";用加号添加样式。

6、正则表达式/image\/\w+/.test():

test()方法:

该方法的返回值是布尔值,通过该值可以匹配字符串中是否存在于正则表达式相匹配的结果,如果有匹配内容,返回ture,如果没有匹配内容返回false,该方法常用于判断用户输入数据的合法性,比如检验Email的合法性

/image\/\w+/的解释: 

/正则内容/ 是一种正则的写法

imge\/\w+

\/表示 /
\w+ 表示一个或多个字母数字下划线
+表示一个多个

7、FileReader

用来把文件读入内存,并且读取文件中的数据。FileReader接口提供了一个异步API,使用该API可以在浏览器主线程中异步访问文件系统,读取文件中的数据。到目前文职,只有FF3.6+和Chrome6.0+实现了FileReader接口。

1、FileReader接口的方法

FileReader接口有4个方法,其中3个用来读取文件,另一个用来中断读取。无论读取成功或失败,方法并不会返回读取结果,这一结果存储在result属性中。

方法名参数描述
readAsBinaryStringfile将文件读取为二进制编码
readAsTextfile,[encoding]将文件读取为文本
readAsDataURLfile将文件读取为DataURL
abort(none)终端读取操作

2、FileReader接口事件

FileReader接口包含了一套完整的事件模型,用于捕获读取文件时的状态。

事件描述
onabort中断
onerror出错
onloadstart开始
onprogress正在读取
onload成功读取
onloadend读取完成,无论成功失败

 在这个例子中 reader.readAsDataURL(files[i])触发了onload方法

转载于:https://my.oschina.net/zerzer/blog/756496

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值