一、页面元素只有三个简单元素:
二、添加简单的样式:
.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;
}
页面的样子:
三、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[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 += '
';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属性中。
FileReader接口的方法
方法名
参数
描述
readAsBinaryString
file
将文件读取为二进制编码
readAsText
file,[encoding]
将文件读取为文本
readAsDataURL
file
将文件读取为DataURL
abort
(none)
终端读取操作
2、FileReader接口事件
FileReader接口包含了一套完整的事件模型,用于捕获读取文件时的状态。
FileReader接口的事件
事件
描述
onabort
中断
onerror
出错
onloadstart
开始
onprogress
正在读取
onload
成功读取
onloadend
读取完成,无论成功失败
在这个例子中 reader.readAsDataURL(files[i])触发了onload方法